#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define mod 1000000007
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
int n,m;
vector<pair<ll,P> >edge;
ll x[100005];
struct uf{
	int par[100005],ran[100005];
	ll sum[100005];
	void init(){
		for(int i=1;i<=n;i++){
			par[i] = i; ran[i] = 0; sum[i] = x[i];
		}
	}
	int find(int x){ if(x == par[x]) return x; else return par[x] = find(par[x]); }
	ll get(int x){ return sum[find(x)]; }
	void unite(int x,int y,bool bad){
		x = find(x); y = find(y);
		if(ran[x] < ran[y]){
			par[x] = y;
			if(bad) ran[y] = ran[y]+ran[x]+1;
			else ran[y] = 0;
			sum[y] += sum[x];
		}
		else{
			par[y] = x;
			if(bad) ran[x] = ran[y]+ran[x]+1;
			else ran[x] = 0;
			sum[x] += sum[y];
		}
	}
	void add_ran(int x){ ran[find(x)]++; return; }
	int get_ran(int x){ return ran[find(x)]; }
	bool same(int x,int y){ return find(x)==find(y); }
}kaede;
int main(){
	scanf("%d%d",&n,&m);
	repn(i,n) scanf("%lld",&x[i]);
	for(int i=0;i<m;i++){
		int a,b; ll y; scanf("%d%d%lld",&a,&b,&y);
		edge.pb(mp(y,mp(a,b)));
	}
	sort(edge.begin(),edge.end());
	kaede.init();
	for(int i=0;i<edge.size();i++){
		ll cs = edge[i].fi;
		int u = edge[i].sc.fi, v = edge[i].sc.sc;
		if(kaede.same(u,v)){
			if(kaede.get(u) < cs){
				kaede.add_ran(u);
			}
		}
		else{
			ll sum = kaede.get(u) + kaede.get(v);
			bool flag = false;
			if(sum < cs) flag = true;
			kaede.unite(u,v,flag);
		}
	}
	cout << kaede.get_ran(1) << endl;
}