#include <bits/stdc++.h>

#define fi first
#define se second
#define mp make_pair
#define mt make_tuple
#define pb push_back
#define INF  (1<<30)
#define INFL (1LL<<60)
#define MOD 1000000007
#define EPS ((ld)(1e-9))

#define sz(x) ((int)(x).size())
#define setz(x) memset(x, 0, sizeof(x))
#define rep(i, x)  for (int i = 0, _##i = (x); i < _##i; i++)
#define repp(i, x) for (int i = 1, _##i = (x); i <= _##i; i++)
#define repr(i, s, e) for (int i = (s), _##i = (e); i < _##i; i++)

#define L(x) ((x)*2)
#define R(x) ((x)*2+1)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<ld, ld> pdd;
typedef pair<ll, ll> pll;

template<typename T, typename V>
ostream &operator<<(ostream &os, const pair<T, V> pai) { 
    os << pai.first << ' ' << pai.second;
	return os;
}

template<typename T>
ostream &operator<<(ostream &os, const vector<T> v) {
    rep(i, sz(v)) cout << v[i] << ' ';
    return os;
}

template<typename T, typename V>
istream &operator>>(istream &is, pair<T, V> &pai) {
	is >> pai.first >> pai.second;
	return is;
}

int N, M;
int par[100001];
int edges[100001];
int maxv[100001];
ll sumv[100001];

pair<int, pii> edge[100001];

int find(int x) {
	return x == par[x] ? x : par[x] = find(par[x]);
}

int main(void) {
    iostream::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);

	cin >> N >> M;
	repp(i, N) {
		cin >> sumv[i];
		par[i] = i;
	}
	rep(i, M) {
		int a, b, c; cin >> a >> b >> c;
		edge[i] = mp(c, mp(a, b));
	}


	sort(edge, edge+M);
	int res = 0;

	rep(i, M) {
		int g1 = find(edge[i].se.fi);
		int g2 = find(edge[i].se.se);
		int we = edge[i].fi;

		if (g1 == g2) {
			if (sumv[g1] >= we) res++;
			else edges[g1]++;
		} else {
			par[g2] = g1;
			maxv[g1] = we;
			edges[g1] += edges[g2]+1;
			sumv[g1] += sumv[g2];
			if (sumv[g1] >= maxv[g1]) {
				res += edges[g1];
				edges[g1] = 0;
			}
		}
	}

	cout << M-res;
}