// After contest. 
#include <iostream>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <climits>
#include <cmath>
#include <utility>
#include <string>
#include <cstring>
#include <functional>

using namespace std;

const int maxn = 100002;

struct edge
{
	int u, v, y;
};
vector<edge> edges;

long long sum[maxn];

int n, m, ans, fa[maxn], cnt[maxn];

bool mycmp(edge &a, edge &b) {
	return a.y < b.y;
}

vector<vector<int> > g;

int getfa(int u) {
	if (fa[u] != u)
		fa[u] = getfa(fa[u]);

	return fa[u];
}

// void unify(int a, int b) {
// 	sum[b] += sum[a];
// 	sum[a] = 0;

// 	fa[a] = b;
// }

// void keepEdges(int u, int lim) {
// 	if (vis[u])
// 		return;

// 	vis[u] = true;
// 	for (int i = 0; i < g[u].size(); ++i) {
// 		int idx = g[u][i];
// 		if (edges[idx].y <= lim) {
// 			ok[idx] = true;
// 			keepEdges(edges[idx].v, lim);
// 		}
// 	}
// }

int main() {

	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		cin >> sum[i];
		fa[i] = i;
	}

	edges = vector<edge>(m);
	for (int i = 0; i < m; ++i)
		cin >> edges[i].u >> edges[i].v >> edges[i].y;

	sort(edges.begin(), edges.end(), mycmp);

	g = vector<vector<int> >(n+1);

	for (int i = 0; i < m; ++i) {
		int u = edges[i].u, v = edges[i].v;
		g[u].push_back(i);
		g[v].push_back(i);

		int f1 = getfa(u);
		int f2 = getfa(v);

		++cnt[f1];
		if (f1 != f2) {
			cnt[f1] += cnt[f2];
			cnt[f2] = 0;

			sum[f1] += sum[f2];
			sum[f2] = 0;

			fa[f2] = f1;
		}
		
		if (sum[f1] >= edges[i].y) {
			ans += cnt[f1];
			cnt[f1] = 0;
		}
	}

	ans = m - ans;
	cout << ans << endl;

	return 0;
}