#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
using namespace std;
typedef long long ll;
int N,M;
ll A[100010],B[100010],Y[100010];
ll X[100010];
vector<vector<pair<int,ll>>> v(100010);
vector<pair<ll,int>> edges;
int p[100010] = {0},r[100010] = {0};
ll s[100010] = {0};
void init(int N){
	for(int i=0;i<=N;++i){
		p[i] = i;
		s[i] = X[i];
	}
}
 
int root(int a){
	if(p[a] == a) return a;
	return (p[a] = root(p[a]));
}
 
bool is_same_set(int a,int b){
	return root(a) == root(b);
}
 
void unite(int a, int b){
	a = root(a);
	b = root(b);
	if(a==b) return;
	if(r[a]<r[b]){
		p[a] = b;
		s[b] += s[a];
		s[a] = s[b];
	}else{
		p[b] = a;
		s[a] += s[b];
		s[b] = s[a];
		if(r[a] == r[b]) r[a]++;
	}
}
 
int visited[100010] = {},ans = 0;
void dfs(int n,int c){
	for(auto& a:v[n]){
		int b = a.first;ll id = a.second;
		if(visited[id]==0 && Y[id]<=c){
			visited[id] = 1; ans++;
			dfs(b,c);
		}
	}
}
 
int main(){
	cin >> N >> M;
	for(int i=1;i<=N;i++){
		cin >> X[i];
	}
	init(N);
	for(int i=1;i<=M;i++){
		cin >> A[i] >> B[i] >> Y[i];
		v[A[i]].push_back({B[i],i});
		v[B[i]].push_back({A[i],i});
		edges.push_back({Y[i],i});
	}
	sort(edges.begin(),edges.end());
	stack<int> S;
	for(auto& a:edges){
		int id = a.second;
		unite(A[id],B[id]);
		if(s[root(A[id])]>=Y[id]) S.push(id);
	}
	while(!S.empty()){
		int a = S.top(); S.pop();
		if(visited[a]==0) dfs(A[a],Y[a]);
	}
	cout << M-ans << endl;
}