#include <cassert>
#include <cstdio>
#include <vector>
#include <queue>
#include <iostream>
using namespace std;
const int max_n=64, max_m=305, max_t=110, INF=0x3f3f3f3f;
const int Source=0, Sink=10000;
#define FORIT( it,v ) for( typeof((v).begin()) it=(v).begin(); it!=(v).end(); ++it )
struct edge{
int a, b, c, f;
/* edge(){
a = b = c = f = 0;
}
edge( int _a, int _b, int _c ){
a = _a;
b = _b;
c = _c;
f = 0;
}*/
int other( int nod ){
return a+b-nod;
}
int cap( int nod ){
if( nod == a )
return c-f;
return f;
}
void update( int nod, int p ){
if( nod == a )
f+=p;
else
f-=p;
}
} StartEdge[max_m], empty;
vector<edge> Edge;
int n, m, i;
int Start[max_n], Target;
int a, b, L;
int t;
int From[Sink+5], MaxFlow;
vector<int> Vertex[Sink+5];
queue<int> Deq;
void make_empty();
bool Find_Flow(){
make_empty();
int nod, other;
Deq.push( Source );
From[Source] = 1;
while( !Deq.empty() ){
if( From[Sink] )
break;
nod = Deq.front();
Deq.pop();
FORIT( it, Vertex[nod] ){
other = Edge[*it].other(nod);
if( Edge[*it].cap( nod ) && !From[other] ){
From[other] = *it;
Deq.push( other );
}
}
}
if( From[Sink] )
;
else
return false;
int mn=INF;
for( nod = Sink; nod != Source; nod = Edge[ From[nod] ].other( nod ) )
mn = min( mn, Edge[ From[nod] ].cap( Edge[ From[nod] ].other(nod) ) );
for( nod = Sink; nod != Source; nod = Edge[ From[nod] ].other( nod ) ){
Edge[ From[nod] ].update( Edge[From[nod]].other(nod), mn );
}
MaxFlow += mn;
return true;
}
void make_empty(){
for( int i=0; i<=Sink; ++i )
From[i]=0;
while( !Deq.empty() )
Deq.pop();
}
void add_edge( int a, int b, int c ){
Vertex[a].push_back( Edge.size() );
Vertex[b].push_back( Edge.size() );
empty.a=a;
empty.b=b;
empty.c=c;
empty.f=0;
Edge.push_back( empty );
}
void make_vertex( int T ){
int i, a, b;
for( i=1; i<=m; ++i ){
// a->b
a = T*64 + StartEdge[i].a;
b = (T+1)*64 + StartEdge[i].b;
add_edge( a, b, StartEdge[i].c );
a = T*64 + StartEdge[i].b;
b = (T+1)*64 + StartEdge[i].a;
add_edge( a, b, StartEdge[i].c );
}
// de la el la el cu cap infinit :)
for( i=1; i<=n; ++i ){
a = T*64 + i;
b = (T+1)*64 + i;
add_edge( a, b, INF );
}
a = (T+1)*64 + 1;
b = Sink;
add_edge( a, b, INF );
}
int main(){
Edge.push_back( empty );
freopen("algola.in","r",stdin);
freopen("algola.out","w",stdout);
scanf("%d %d", &n, &m );
for( i=1; i<=n; ++i ){
scanf("%d", &Start[i] );
Target += Start[i];
}
for( i=1; i<=n; ++i ){
scanf("%d %d %d", &a, &b, &L );
StartEdge[i].a=a;
StartEdge[i].b=b;
StartEdge[i].c=L;
StartEdge[i].f=0;
}
// facem muchiile initiale
for( i=1; i<=n; ++i ){
add_edge( Source, i, Start[i] );
}
add_edge( 1, Sink, INF );
for( t=0; ; ++t ){
while( Find_Flow() )
;
if( MaxFlow >= Target ){
printf("%d\n", t );
return 0;
}
make_vertex( t );
}
return 0;
}