/*
费用流,建模很难想。
S向i连边 (1,0)
S向i‘连边 (1,vi)
i‘向T连边 (1,0)
u向v‘连边 (i,w)
因为一定会满流,所以直接跑费用流,有点类似于最小路径覆盖
*/
#include<cstdio>
#include<iostream>
#include<queue>
#define N 1610
#define M 40010
#define lon long long
#define inf 1000000000
using namespace std;
int head[N],inq[N],fa[N],dis[N],n,m,S,T,cnt=1;
lon ans;
struct node{int u,v,f,w,pre;}e[M];
queue<int> q;
void add(int u,int v,int f,int w){
e[++cnt].u=u;e[cnt].v=v;e[cnt].f=f;e[cnt].w=w;e[cnt].pre=head[u];head[u]=cnt;
e[++cnt].u=v;e[cnt].v=u;e[cnt].f=0;e[cnt].w=-w;e[cnt].pre=head[v];head[v]=cnt;
}
bool spfa(){
for(int i=S;i<=T;i++) dis[i]=inf;
dis[S]=0;q.push(S);
while(!q.empty()){
int u=q.front();q.pop();inq[u]=0;
for(int i=head[u];i;i=e[i].pre)
if(e[i].f&&dis[e[i].v]>dis[u]+e[i].w){
dis[e[i].v]=dis[u]+e[i].w;
fa[e[i].v]=i;
if(!inq[e[i].v]){
inq[e[i].v]=1;
q.push(e[i].v);
}
}
}
return dis[T]!=inf;
}
void updata(){
int tmp=fa[T],x=inf;
while(tmp){
x=min(x,e[tmp].f);
tmp=fa[e[tmp].u];
}
tmp=fa[T];
while(tmp){
e[tmp].f-=x;
e[tmp^1].f+=x;
tmp=fa[e[tmp].u];
}
ans+=(lon)dis[T]*(lon)x;
}
int main(){
scanf("%d%d",&n,&m);
S=0;T=n*2+1;
for(int i=1;i<=n;i++){
int x;scanf("%d",&x);
add(S,i,1,0);add(S,i+n,1,x);add(i+n,T,1,0);
}
for(int i=1;i<=m;i++){
int u,v,w;scanf("%d%d%d",&u,&v,&w);
if(u>v) swap(u,v);
add(u,v+n,1,w);
}
while(spfa())
updata();
cout<<ans;
return 0;
}