#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
using namespace std;
typedef long long int ll;
typedef pair<ll, int> P;
int par[100002];
int rk[100002];
ll w[100002];
int n, m;
vector<int> g[300002];
int num[100002];
int ec[100002];
int c;
int mx[300002];
void init(int n){
	for(int i=0; i<n; i++){
		par[i]=i; rk[i]=0; num[i]=i;
	}
}
 
int find(int x){
	if(par[x]==x){
		return x;
	}else{
		return par[x]=find(par[x]);
	}
}
 
void unite(int x, int y){
	x=find(x);
	y=find(y);
	if(x==y) return;
	if(rk[x]<rk[y]){
		g[c].push_back(num[x]);
		g[c].push_back(num[y]);
		par[x]=y;
		num[y]=c;
		c++;
		w[y]+=w[x];
		ec[y]+=ec[x];
	}else{
		g[c].push_back(num[x]);
		g[c].push_back(num[y]);
		par[y]=x;
		num[x]=c;
		c++;
		w[x]+=w[y];
		ec[x]+=ec[y];
		if(rk[x]==rk[y]) rk[x]++;
	}
}
 
bool same(int x, int y){
	return find(x)==find(y);
}

int ans;

void dfs(int x){
	if(mx[x]>=0){
		ans+=mx[x];
		return;
	}
	for(auto y:g[x]){
		dfs(y);
	}
}

int main()
{
	cin>>n>>m;
	for(int i=0; i<n; i++) cin>>w[i];
	init(n);
	P e[100001];
	int a[100001], b[100001];
	for(int i=0; i<m; i++){
		ll y; cin>>a[i]>>b[i]>>y; a[i]--; b[i]--;
		e[i]=P(y, i);
	}
	c=n;
	sort(e, e+m);
	fill(mx, mx+300000, -1);
	for(int i=0; i<n; i++) mx[i]=0;
	for(int i=0; i<m; i++){
		int j=e[i].second;
		if(!same(a[j], b[j])){
			unite(a[j], b[j]);
		}
		int p=find(a[j]);
		ec[p]++;
		if(w[p]>=e[i].first){
			mx[num[p]]=max(ec[p], mx[num[p]]);
		}
	}
	dfs(c-1);
	cout<<m-ans<<endl;
	return 0;
}