#include <bits/stdc++.h>
using namespace std;

#define rep(i, N) for (int i = 0; i < (N); i++)
#define all(a) (a).begin(), (a).end()
#define pb push_back

using ll = long long;
using i_i = tuple<int, int>;

struct union_find {
	vector<int> v;
	union_find(int n) : v(n, -1) {}
	int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
	void unite(int x, int y) {
		x = find(x); y = find(y);
		if (x == y) return;
		if (-v[x] < -v[y]) swap(x, y);
		v[x] += v[y]; v[y] = x;
	}
	bool root(int x) { return v[x] < 0; }
	bool same(int x, int y) { return find(x) == find(y); }
	int size(int x) { return -v[find(x)]; }
};

int main() {
    int N, M;
    cin >> N >> M;
    vector<int> a(N);
    rep(u, N) cin >> a[u];
    vector<int> x(M), y(M), z(M);
    rep(i, M) {
        cin >> x[i] >> y[i] >> z[i];
        x[i]--; y[i]--;
    }
    vector<i_i> zi(M);
    rep(i, M) zi[i] = i_i(z[i], i);
    sort(all(zi));
    union_find uf(N);
    vector<ll> A(N);
    rep(u, N) A[u] = a[u];
    vector<int> E(N), unko(N);
    int ans = 0;
    for (auto p: zi) {
        int i = get<1>(p);
        int u = x[i], v = y[i], w = z[i];
        if (uf.same(u, v)) {
            E[uf.find(u)]++;
            if (w <= A[uf.find(u)]) {
                unko[uf.find(u)]++;
                ans++;
            }
        }
        else {
            ll tmp = A[uf.find(u)] + A[uf.find(v)];
            ll hoge = E[uf.find(u)] + E[uf.find(v)];
            ll kuso = unko[uf.find(u)] + unko[uf.find(v)];
            uf.unite(u, v);
            A[uf.find(u)] = tmp;
            E[uf.find(u)] = hoge + 1;
            unko[uf.find(u)] = kuso;
            if (tmp >= w) {
                ans += E[uf.find(u)] - unko[uf.find(u)];
                unko[uf.find(u)] = E[uf.find(u)];
            }
        }
    }
    cout << M - ans << endl;
}
