#include <bits/stdc++.h>
using i64 = long long;
using std::cout;
using std::endl;
using std::cin;

struct HyperUnionFind {
	std::vector<int> data;
	std::vector<i64> w, sz;
	
	HyperUnionFind(int n) {
		data.assign(n, -1);
		w.assign(n, 0);
		sz.assign(n, 0);
	}
	void set(int k, int x) {
		w[k] = x;
	}
	i64 unite(int x, int y) {
		x = find(x); y = find(y);
		if(x == y) {
			sz[x]++;
			return w[x];
		}
		if(data[x] > data[y]) std::swap(x, y);
		data[x] += data[y];
		w[x] += w[y];
		w[y] = 0;
		sz[x] += sz[y] + 1;
		sz[y] = 0;
		data[y] = x;
		return w[x];
	}
	int find(int k) {
		if(data[k] < 0) return k;
		return find(data[k]);
	}
	int get(int k) {
		k = find(k);
		int ret = sz[k];
		sz[k] = 0;
		return ret;
	}
};
	
int main() {
	int n, m; scanf("%d%d", &n, &m);
	HyperUnionFind uf(n);
	for(int i = 0; i < n; i++) {
		int a; scanf("%d", &a);
		
		uf.set(i, a);
	}
	std::vector<std::pair<int, std::pair<int, int>>> vec;
	for(int i = 0; i < m; i++) {
		int a, b, c; scanf("%d%d%d", &a, &b, &c);
		
		vec.push_back({c, {a - 1, b - 1}});
	}
	sort(begin(vec), end(vec));
	
	int ans = 0;
	for(auto v : vec) {
		int a = v.second.first, b = v.second.second, w = v.first;
		
		if(uf.unite(a, b) >= w) {
			ans += uf.get(a);
		}
	}
	printf("%d\n", m - ans);
	return 0;
}
