#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
#define repp(i,a,b) for(int i = (int)(a) ; i < (int)(b) ; ++i)
#define repm(i,a,b) for(int i = (int)(a) ; i > (int)(b) ; --i)

template <int T_size> class Union_Find{
	int p[T_size];
	LL x[T_size];
	int uni_count;
	
public:
	
	Union_Find(vector<LL> V){
		fill(p,p+T_size,-1);
		repp(i,0,V.size()) x[i] = V[i];
		uni_count = 0;
	}
	
	int boss(int a){
		return p[a] >= 0 ? boss(p[a]) : a;
	}
	
	tuple<LL,LL,int,int> uni(int a , int b){
		int s = boss(a);
		int t = boss(b);
		auto y = get_x(s);
		auto z = get_x(t);
		if(s != t){
			++uni_count;
			if(p[s] > p[t]){
				swap(s,t);
				swap(a,b);
				swap(y,z);
			}
			x[s] += x[t];
			p[s] += p[t];
			p[t] = s;
		}
		return make_tuple(y,z,s,t);
	}

	void cut(LL y, LL z, int s, int t){
		p[s] = -1;
		p[t] = -1;
		x[s] = y;
		x[t] = z;
	}

	bool find(int a , int b){
		return boss(a) == boss(b);
	}
	
	int count(){
		return uni_count;
	}
	
	int member(int a){
		return -p[boss(a)];
	}

	LL get_x(int a){
		return x[boss(a)];
	}
};

int main(){
	int N,M; cin >> N >> M;
	vector<LL> X(N+1);
	repp(i,0,N) cin >> X[i+1];
	vector<tuple<LL,int,int>> E(M);
	repp(i,0,M){
		LL Y; int A,B; cin >> A >> B >> Y;
		E[i] = make_tuple(Y,A,B);
	}
	sort(E.begin(),E.end());
	Union_Find<100010> uf(X);
	vector<tuple<LL,LL,int,int>> V(M,make_tuple(-1,-1,-1,-1));
	repp(i,0,M) if(!uf.find(get<1>(E[i]),get<2>(E[i]))){
		V[i] = uf.uni(get<1>(E[i]),get<2>(E[i]));
	}
	int ans = 0;
	repm(i,M-1,-1){
		if(uf.get_x(get<1>(E[i])) < get<0>(E[i])){
			++ans;
			
			if(get<0>(V[i]) != -1){
				uf.cut(get<0>(V[i]),get<1>(V[i]),get<2>(V[i]),get<3>(V[i]));
			}
		}
	}
	cout << ans << endl;
	return 0;
}
