#include <bits/stdc++.h>
using namespace std;

const int N = 100005;

struct edge {
	int u; int v; int w;
	bool operator < (const edge &other) const {
		return w < other.w;
	}
} e[N];

int n, m;
int a[N];
bool can[N], used[N];
vector < pair<int,int> > g[N];

struct dsu {
	int par[N];
	long long sum[N];
	void init() {
		for (int i = 1; i <= n; ++i) par[i] = i, sum[i] = a[i];
	}
	int anc(int p) { return p == par[p] ? p : par[p] = anc(par[p]); }
	bool join(int p, int q) {
		p = anc(p), q = anc(q);
		if (p == q) return false;
		par[p] = q;
		sum[q] += sum[p];
		sum[p] = 0;
		return true;
	}
} d;

int main() {
	ios_base::sync_with_stdio(false); cin.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) cin >> a[i];
	
	// build edges
	for (int i = 1; i <= m; ++i) {
		int u, v, w; cin >> u >> v >> w;
		e[i] = {u, v, w};
	}
	sort(e + 1, e + m + 1);
	for (int i = 1; i <= m; ++i) {
		g[e[i].u].push_back({e[i].v, i});
		g[e[i].v].push_back({e[i].u, i});
	}
	
	// solve
	d.init();
	for (int i = 1; i <= m; ++i) {
		d.join(e[i].u, e[i].v);
		int x = d.anc(e[i].u);
		if (d.sum[x] >= e[i].w) can[i] = true;
	}
	
	d.init();
	for (int i = m; i >= 1; --i) if (can[i] && !used[i]) {
		used[i] = true;
		queue <int> q;
		d.join(e[i].u, e[i].v);
		q.push(e[i].u); q.push(e[i].v);
		
		while(!q.empty()) {
			int u = q.front(); q.pop();
			for (auto &ed : g[u]) {
				if (ed.second <= i) {
					used[ed.second] = true;
					if (d.join(ed.first, u)) q.push(ed.first);
				} else break;
			}
		}
	}
	
	int res = 0;
	for (int i = 1; i <= m; ++i) if (!used[i]) ++res;
	
	cout << res << endl;
}
