#include <bits/stdc++.h>
#define il inline
#define ri register int
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define mid ((l+r)>>1)
#define MAXN 100050
#define MAXM
#define mod
#define INF (1<<30)
#define eps (1e-6)
#define rep(i, x, y) for(ri i = x; i <= y; ++i)
#define repd(i, x, y) for(ri i = x; i >= y; --i)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ll, int> pli;
typedef pair <int, ll> pil;
typedef pair <ll, ll> pll;
template <typename T> inline bool chkmin(T &x, T y) {return x > y ? x = y, 1 : 0;}
template <typename T> inline bool chkmax(T &x, T y) {return x < y ? x = y, 1 : 0;}
il void read(int &qwq) {
	char ch = getchar(); int f = 1; qwq = 0;
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') qwq = qwq*10+ch-'0', ch = getchar();
	qwq *= f;
}
//default codes end here
int n, m, val[MAXN], fa[MAXN], ok[MAXN], good[MAXN], vis[MAXN], ans;
ll sum[MAXN];
struct node {
	int u, v, w;
	bool operator < (const node &x) const {
		return w < x.w;
	}
} E[MAXN];
vector <node> adj[MAXN];
int get(int u) {
	return u == fa[u] ? u : fa[u] = get(fa[u]);
}
void merge(int u, int v) {
	u = get(u), v = get(v);
	if(u != v) fa[v] = u, sum[u] += sum[v];
}
void search(int u, int w) {
	vis[u] = 1;
	for(auto pa: adj[u]) {
		if(pa.w <= w) {
			ok[pa.u] = 1;
			if(!vis[pa.v]) search(pa.v, w);
		}
	}
	
}
int main() {
	int u, v, w;
	read(n), read(m);
	rep(i, 1, n) read(val[i]), fa[i] = i, sum[i] = val[i];
	rep(i, 1, m) read(u), read(v), read(w), E[i] = node {u, v, w};
	sort(E+1, E+m+1);
	rep(i, 1, m) {
		merge(E[i].u, E[i].v);
		adj[E[i].u].pb(node {i, E[i].v, E[i].w}), adj[E[i].v].pb(node {i, E[i].u, E[i].w});
		if(sum[get(E[i].u)] >= E[i].w) good[i] = 1;
//		cout<<sum[get(E[i].u)]<<' '<<E[i].w<<endl;
	}
	repd(i, m, 1) {
		if(ok[i]) ++ans;
		else if(good[i]) ++ans, search(E[i].u, E[i].w);
	}
	cout<<m-ans<<endl;
	return 0;
}