#include <bits/stdc++.h>
#define rep(i,n) for (int i = 0; i < (n); ++i)
using namespace std;
using ll = long long;
using P = pair<int,int>;
using PP = pair<ll ,P>;

vector<ll> w; // on-the-fly weight of connected component, indexed by ranks
vector<vector<int>> head;

class DSU {
	private:
		int *data;
	public:
		DSU(int n) {
			data = new int[n];
			for(int i = 0; i < n; i++) {
				data[i] = -1;
			}
		}

		~DSU() {delete[] data;}

		int find(int i) {
			int parent;
			int back_to = -1;
			for(; (parent = data[i]) >= 0; i = parent) {
				data[i] = back_to;
				back_to = i;
			}
			int root = i;
			while(back_to != -1) {
				i = back_to;
				back_to = data[i];
				data[i] = root;
			}
			return root;
		}

		int merge(int i, int j) {
			int ri = find(i), rj = find(j);
			if (ri == rj)
				return 0;
			if (data[ri] > data[rj]) {
				int t = ri;
				ri = rj;
				rj = t;
			}
			data[ri] += data[rj];
			data[rj] = ri;
			w[ri] += w[rj];
			head[ri].insert(head[ri].end(), head[rj].begin(), head[rj].end());
			return 1;
		}

		int get_size(int i) {
			return -data[find(i)];
		}
};

int main() {
	int n, m;
	cin >> n >> m;
	vector<PP> aby(m);
	w.resize(n);
	head.resize(n);
	rep(i, n) cin >> w[i];
	rep(i, m) {
		int a, b;
		ll y;
		cin >> a >> b >> y;
		aby[i] = {y, {a - 1, b - 1}};
	}
	sort(aby.begin(), aby.end());
	DSU d(n);
	vector<bool> res(m);
	vector<vector<int>> nxt(m);
	rep(i, m) {
		int a = aby[i].second.first, b = aby[i].second.second;
		ll y = aby[i].first;
		d.merge(a, b);
		int rank = d.find(a);
		res[i] = w[rank] >= y;
		nxt[i] = head[rank];
		head[rank] = vector<int>{i};
	}
	set<int> rall;
	rep(i, n) rall.insert(d.find(i));
	queue<int> q;
	for(int r: rall) for(int i: head[r]) q.push(i);
	int ans = 0;
	while(!q.empty()) {
		int i = q.front();
		q.pop();
		if (res[i]) continue;
		ans++;
		for(int j: nxt[i]) q.push(j);
	}
	cout << ans << endl;
}
