#include <bits/stdc++.h>

using namespace std;

struct UF {
	UF *p;
	long s;
	UF() :p(nullptr), s(1) {}
	UF *Find() {
		if (p == nullptr)
			return this;
		return p = p->Find();
	}
	int Union(UF &n) {
		auto *r = Find(), *nr = n.Find();
		if (r == nr) return 0;
		if (r->s < nr->s) swap(r, nr);
		nr->p = r, r->s += nr->s;
		return 1;
	}
} u[111111];
tuple<int, int, int> e[111111];
vector<int> v[111111];
int c[111111];
void f(int i, int w) {
	if (c[i] == -1) return;
	if (get<0>(e[i]) > w)
		return;
	c[i] = -1;
	for (int j : {get<1>(e[i]), get<2>(e[i])})
		for (int k : v[j])
			f(k, w);
}
int main() {
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		int x;
		scanf("%d", &x);
		u[i + 1].s = x;
	}
	for (int i = 0; i < m; i++) {
		int a, b, y;
		scanf("%d%d%d", &a, &b, &y);
		e[i] = tuple<int, int, int>(y, a, b);
	}
	sort(e, e + m);
	for (int i = 0; i < m; i++)
		v[get<1>(e[i])].push_back(i), v[get<2>(e[i])].push_back(i);
	for (int i = 0; i < m; i++) {
		u[get<1>(e[i])].Union(u[get<2>(e[i])]);
		if (u[get<1>(e[i])].Find()->s >= get<0>(e[i]))
			c[i] = 1;
	}
	for (int i = m; i--;)
		if (c[i] == 1) f(i, get<0>(e[i]));
	int r = 0;
	for (int i = 0; i < m; i++)
		if (!c[i]) r++;
	cout << r << endl;
	return 0;
}
