#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <tuple>
#include <iomanip>
#include <cmath>
#include <queue>
#include <deque>
#include <stack>
//#pragma GCC optimize("Ofast")
//#pragma GCC target("avx,avx2")
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
typedef long double ld;
typedef long long ll;
typedef double db;
#define endl '\n'
#define pb push_back
#define pii pair<ll, ll>
#define ff first
#define ss second
#define sz(x) (ll)(x).size()
#define optimize1() ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#pragma warning(disable:4996)

using namespace std;
const ll MX = 1e5 + 10;
ll lead[MX], rang[MX], w[MX], n, m, res[MX], used[MX], ans = 0;
vector<pii> g[MX];
pair<ll, pii> edg[MX];

ll find(ll x) {
	//cout << x << endl;
	if (lead[x] == x)
		return x;
	return lead[x] = find(lead[x]);
}

void unite(ll a, ll b) {
	ll x = find(a);
	ll y = find(b);
	if (x == y)
		return;
	lead[x] = y;
	w[y] += w[x];
}


void dfs(ll v, ll val) {
	for (auto c : g[v]) {
		if (c.ff <= val && used[c.ff] == 0) {
			used[c.ff] = 1;
			dfs(c.ss, val);
			ans++;
		}
	}
}



signed main() {
    optimize1();
	cin >> n >> m;
	for (ll i = 1; i <= n; ++i) {
		cin >> w[i];
		lead[i] = i;
	}
	for (ll i = 0; i < m; ++i) {
		ll j, x, y;
		cin >> x >> y >> j;
		edg[i] = { j, {x, y} };
	}
	sort(edg, edg + m);

	for (ll i = 0; i < m; ++i) {
		ll x = edg[i].ss.ff, y = edg[i].ss.ss;
		g[x].push_back({ i, y });
		g[y].push_back({ i, x });
	}

	for (ll i = 0; i < m; ++i) {
		unite(edg[i].ss.ff, edg[i].ss.ss);
		res[i] = (w[lead[edg[i].ss.ss]] >= edg[i].ff);
	}
	for (ll i = m - 1; i >= 0; --i) {
		if (res[i] == 1)
			dfs(edg[i].ss.ff, i);
	}
	cout << m - ans << endl;
    return 0;
}
