#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
const ll INF = 1LL << 60;
const double PI = 3.141592653589793238;
const double EPS = 1e-10;
typedef pair<int, int> P;
typedef pair<ll, P> E;
struct UnionFind {
	vector<int> par;
	vector<int> rank;
	vector<ll> weight;
	int size;
	UnionFind(int n, vector<ll> &weight) :size(n), weight(weight) {
		par.resize(size);
		rank.resize(size);
		for (int i = 0; i < size; i++) {
			par[i] = i;
			rank[i] = 0;
		}
	}
	void unite(int x, int y) {
		x = find(x);
		y = find(y);
		if (x == y) return;
		if (rank[x] < rank[y]) {
			par[x] = y;
			weight[y] += weight[x];
		}
		else {
			par[y] = x;
			weight[x] += weight[y];
			if (rank[x] == rank[y]) rank[x]++;
		}
	}
	int find(int x) {
		if (par[x] == x) return x;
		return par[x] = find(par[x]);
	}
	bool same(int x, int y) {
		x = find(x);
		y = find(y);
		return x == y;
	}
};
vector<E> edge;
vector<P> G[100000];
int use[100000];
void dfs(int v, ll d) {
	for (P p : G[v]) {
		if (edge[p.second].first > d || use[p.second] == 1) continue;
		use[p.second] = 1;
		dfs(p.first, d);
	}
}
int main() {
	int N, M;
	cin >> N >> M;
	vector<ll> X;
	for (int i = 0; i < N; i++) {
		ll x;
		cin >> x;
		X.push_back(x);
	}
	for (int i = 0; i < M; i++) {
		int A, B;
		ll Y;
		cin >> A >> B >> Y;
		A--; B--;
		edge.emplace_back(Y, P(A, B));
	}
	sort(edge.begin(), edge.end());
	UnionFind U(N, X);
	for (int i = 0; i < M; i++) {
		G[edge[i].second.first].emplace_back(edge[i].second.second, i);
		G[edge[i].second.second].emplace_back(edge[i].second.first, i);
	}
	for (int i = 0; i < M; i++) {
		E e = edge[i];
		U.unite(e.second.first, e.second.second);
		int v = U.find(e.second.first);
		if (U.weight[v] >= e.first) use[i] = 2;
	}
	for (int i = M - 1; i >= 0; i--) {
		E e = edge[i];
		if (use[i] == 1 || use[i] == 0) continue;
		dfs(e.second.first, e.first);
	}
	int ans = M;
	for (int i = 0; i < M; i++) {
		if (use[i]) ans--;
	}
	cout << ans << endl;
}