#include"bits/stdc++.h"
using namespace std;
#define MOD 1000000007
long long int ppow(long long int i, long long int j) {
	long long int res = 1LL;
	while (j) {
		if ((j & 1LL)) {
			res *= i;
			if (res >= MOD) {
				res %= MOD;
			}
		}
		j >>= 1;
		i *= i;
		if (i >= MOD) {
			i %= MOD;
		}
	}
	return res;
}
long long int gcd(long long int a, long long int b) {
	if (a > b) {
		swap(a, b);
	}
	while (a) {
		swap(a, b);
		a %= b;
	}
	return b;
}
long long int lcm(long long int a, long long int b) {
	return a / gcd(a, b)*b;
}

int n;
int m;
vector<long long int> node;
struct st {
	int a;
	int b;
	long long int cost;
};
vector<st> ed;
bool cmp(st a, st b) {
	return a.cost < b.cost;
}
struct UF {
	vector<int> belong;
	vector<long long int> size;
	vector<long long int> mx;
	vector<set<int> > wait;
	vector<multiset<long long int> > que;
	int gross;
	void resize(int n) {
		belong.assign(n + 1, -1);
		mx.resize(n + 1, 0);
		que.assign(n, multiset<long long int>());
		wait.assign(n, set<int>());
		size = node;
		gross = 0;
	}
	inline int root(int b) {
		if (belong[b] == -1) {
			return b;
		}
		belong[b] = root(belong[b]);
		return belong[b];
	}
	void merge(int a, int b,long long int cost) {
		a = root(a);
		b = root(b);
		if (a == b)return;
		belong[a] = b;
		size[b] += size[a];
		mx[b] = max(mx[b], mx[a]);
		mx[b] = max(mx[b], cost);
		if (wait[b].size() < wait[a].size())swap(wait[a], wait[b]);
		for (auto el : wait[a]) {
			if (wait[b].count(el)) {
				que[b].insert(ed[el].cost);
				wait[b].erase(el);
			}
			else {
				wait[b].insert(el);
			}
		}
		wait[a].clear();
		if (que[b].size() < que[a].size())swap(que[a], que[b]);
		for (auto el : que[a]) {
			que[b].insert(el);
		}
		que[a].clear();
		while (que[b].size() && (*que[b].begin()) <= size[b]) {
			que[b].erase(que[b].begin());
			gross++;
		}
	}
	bool valid(int a) {
		a = root(a);
		return mx[a] > size[a];
	}
	void dum(int a, long long int z) {
		a = root(a);
		if (z <= size[a]) {
			gross++;
			return;
		}
		que[a].insert(z);
	}
};
UF uf;
bool make(int mid) {
	uf.resize(n);
	int dum = 0;
	int MM = 0;
	for (int i = 0; i < ed.size(); i++) {
		uf.wait[ed[i].a].insert(i);
		uf.wait[ed[i].b].insert(i);
	}
	for (int i = 0; i < mid; i++) {
		if (uf.root(ed[i].a) != uf.root(ed[i].b)) {
			dum -= uf.valid(ed[i].a);
			dum -= uf.valid(ed[i].b);
			uf.merge(ed[i].a, ed[i].b, ed[i].cost);
			if (uf.valid(ed[i].a)) {
				dum++;
			}
			if (dum == 0) {
				MM = max(MM, uf.gross);
			}
		}
		else {
			//uf.dum(ed[i].a, ed[i].cost);
		}
	}
	printf("%d\n", ed.size() - MM);
	return true;
}
struct UF2 {  //with pop  partially persistent
	vector<vector<int> > belong;
	vector<vector<int> > dep;
	vector<vector<long long int> > sum;
	void resize(int n) {
		vector<int> f;
		f.push_back(-1);
		belong.assign(n, f);
		f[0] = 1;
		dep.assign(n, f);
		f[0] = 0;
		sum.assign(n, vector<long long int>() );
		for (int i = 0; i < n; i++) {
			sum[i].push_back(node[i]);
		}
	}
	int root(int b) {
		if (belong[b].back() == -1) {
			return b;
		}
		return root(belong[b].back());
	}
	vector<pair<int, int> > op;
	int push(int a, int b) {  //merge
		a = root(a);
		b = root(b);
		int f = op.size();
		if (a == b) {
			op.push_back(make_pair(-1, -1));
			return f;
		}
		if (dep[a].back() > dep[b].back()) {
			swap(a, b);
		}
		belong[a].push_back(b);
		dep[b].push_back(max(dep[b].back(), dep[a].back() + 1));
		long long int R = sum[a].back() + sum[b].back();
		sum[b].push_back(R);
		op.push_back(make_pair(a, b));
		return f;
	}
	void pop(int id) {
		belong[op[id].first].pop_back();
		dep[op[id].second].pop_back();
		sum[op[id].second].pop_back();
		//op.pop_back();
	}
};
UF2 uf2;
inline void dfs(int c) {
	if (c == ed.size())return;
	if (uf2.root(ed[c].a) == uf2.root(ed[c].b)) {
		dfs(c + 1);
		return;
	}
	int id=uf2.push(ed[c].a, ed[c].b);
	dfs(c + 1);
	if (uf2.sum[uf2.root(ed[c].a)].back() < ed[c].cost) {
		uf2.pop(id);
	}
}
int main() {
	cin >> n >> m;
	uf.resize(n);
	for (int i = 0; i < n; i++) {
		int a;
		scanf("%d", &a);
		node.push_back(a);
	}
	for (int i = 0; i < m; i++) {
		int a, b, y;
		scanf("%d%d%d", &a, &b, &y);
		a--;
		b--;
		ed.push_back({ a,b,y });
	}
	sort(ed.begin(), ed.end(), cmp);
	uf2.resize(n);
	dfs(0);
	int fa = 0;
	for (int i = 0; i < ed.size(); i++) {
		int a = ed[i].a;
		int b = ed[i].b;
		if (uf2.root(a) == uf2.root(b) && uf2.sum[uf2.root(a)].back() >= ed[i].cost) {

		}
		else {
			fa++;
		}
	}
	cout << fa << endl;
	return 0;
	make(ed.size());
	return 0;
}

Measured memory_bytes: 40176