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

typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
//typedef vector<vector<ll>> Graph;

const ll mod = 1e9 + 7;
//const ll mod = 998244353;

#define REP(i,n) for(ll i=0;i<(ll)n;i++)
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define spa << " " <<
#define fi first
#define se second

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }

template<class S, class T> ostream& operator << (ostream& os, const pair<S, T> v){
os << "(" << v.first << ", " << v.second << ")"; return os;
}
template<class T> ostream& operator << (ostream& os, const vector<T> v){
for(int i = 0; i < (int)v.size(); i++){if(i > 0){os << " ";} os << v[i];} return os;
}
template<class T> ostream& operator << (ostream& os, const vector<vector<T>> v){
for(int i = 0; i < (int)v.size(); i++){if(i > 0){os << endl;} os << v[i];} return os;
}

template<typename T> void debug(vector<vector<T>>&v,ll h,ll w){for(ll i=0;i<h;i++)
{cerr<<v[i][0];for(ll j=1;j<w;j++)cerr spa v[i][j];cerr<<endl;}};
void debug(vector<string>&v,ll h,ll w){for(ll i=0;i<h;i++)
{for(ll j=0;j<w;j++)cerr<<v[i][j];cerr<<endl;}};
template<typename T> void debug(vector<T>&v,ll n){if(n!=0)cerr<<v[0];
for(ll i=1;i<n;i++)cerr spa v[i];
cerr<<endl;};

string num2bit(ll num, ll len){
	string bit = "";
	REP(i, len){
	bit += char('0'+(num>>i & 1));
	}
	return bit;
}

struct edge{
	ll u, v, w;
};

struct UnionFindSize {
    vector<int> par;
    
    UnionFindSize(int n) : par(n, -1) { }
    void init(int n) { par.assign(n, -1); }
    
    int root(int x) {
        if (par[x] < 0) return x;
        else return par[x] = root(par[x]);
    }
    
    bool issame(int x, int y) {
        return root(x) == root(y);
    }
    
    bool merge(int x, int y) {
        x = root(x); y = root(y);
        if (x == y) return false;
        if (par[x] > par[y]) swap(x, y); // merge technique
        par[x] += par[y];
        par[y] = x;
        return true;
    }
    
    int size(int x) {
        return -par[root(x)];
    }

	void print(){
		cout << "uf: ";
		for(int i=0;i<(int)par.size();i++) cout << root(i) << " ";
		cout << endl;
	}
};

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);

	ll N, M;
	cin >> N >> M;
	vector<ll> X(N);
	REP(i, N) cin >> X[i];

	vector<edge> E(M);
	REP(i, M){
		cin >> E[i].u >> E[i].v >> E[i].w;
		E[i].u--;
		E[i].v--;
	}

	sort(E.begin(), E.end(), [](const edge &x, const edge &y){
		return x.w < y.w;
	});

	UnionFindSize uf(N);

	vector<ll> sum(N, 0), enu(N, 0), ema(N, 0), sude(N, 0);
	REP(i, N) sum[i] = X[i];

	REP(i, M){
		//dump(i)
		//debug(sude, N);

		edge e = E[i];
		ll ru = uf.root(e.u);
		ll rv = uf.root(e.v);

		if(uf.issame(e.u, e.v)){
			//dump(1)
			if(e.w > sum[ru]){
				enu[ru]++;
				chmax(ema[ru], e.w);
			}else{
				enu[ru]++;
				chmax(ema[ru], e.w);
				sude[ru]++;
			}
		}else{
			//dump(2)
			uf.merge(e.u, e.v);
			ll rr = uf.root(e.u);
			
			sum[rr] = sum[ru] + sum[rv];
			enu[rr] = enu[ru] + enu[rv] + 1;
			ema[rr] = max(max(ema[ru], ema[rv]), e.w);

			if(ema[rr] > sum[rr]){
				// fail
				sude[rr] = sude[ru] + sude[rv];
				if(rr == ru) sude[rv] = 0;
				if(rr == rv) sude[ru] = 0;
			}else{
				// success
				sude[ru] = 0;
				sude[rv] = 0;
				sude[rr] = enu[rr];
			}
		}
		//uf.print();
	}
	//debug(sude, N);

	ll res = M;
	REP(i, N) res -= sude[i];
	cout << res << endl;

	return 0;
}

Measured memory_bytes: 6912