#include <bits/stdc++.h>
#define endl '\n'

//#pragma GCC optimize ("O3")
//#pragma GCC target ("sse4")

#define SZ(x) ((int)x.size())
#define ALL(V) V.begin(), V.end()
#define L_B lower_bound
#define U_B upper_bound
#define pb push_back

using namespace std;
template<class T, class T2> inline int chkmax(T &x, const T2 &y) { return x < y ? x = y, 1 : 0; }
template<class T, class T2> inline int chkmin(T &x, const T2 &y) { return x > y ? x = y, 1 : 0; }
const int MAXN = (1 << 20);

struct dsu
{
	int sz;
	vector<int> par, psz;

	void init(int n)
	{
		sz = n;
		par.assign(sz + 1, 0);
		psz.assign(sz + 1, 0);
		for(int i = 0; i <= sz; i++)
			par[i] = i, psz[i] = 1;
	}

	int root(int u) { return par[u] = ((u == par[u]) ? u : root(par[u])); }
	
	bool connected(int x, int y) { return root(x) == root(y); }

	void unite(int x, int y)
	{
		x = root(x), y = root(y);
		if(x == y) return;
		if(psz[x] > psz[y]) swap(x, y);
		par[x] = y, psz[y] += psz[x]; 
	}
} DS;

int n, m, w[MAXN];
vector<pair<int, pair<int, int> > > ed;

void read()
{
	cin >> n >> m;
	for(int i = 1; i <= n; i++) cin >> w[i];
	for(int i = 0; i < m; i++)
	{
		int u, v, x;
		cin >> u >> v >> x;
		ed.pb({x, {u, v}});
	}
} 

bool in_tr[MAXN];
vector<pair<int, int> > adj[MAXN];

int64_t sum[MAXN];
int comp[MAXN];
bool vis[MAXN];

void dfs(int u, int C)
{
	vis[u] = 1;
	comp[u] = C;
	for(auto v: adj[u])
		if(!vis[v.first])
			dfs(v.first, C);
}

int psz = 0;

set<pair<int64_t, int> > ST;
set<pair<int64_t, int> > li[MAXN];

void assign(int u, int pr, int nC, int C)
{
	comp[u] = nC;
	sum[nC] += w[u];	
	for(auto e: adj[u])
		if(comp[e.first] == C && e.first != pr)
		{
			li[C].erase({(int64_t)ed[e.second].first, e.second});
			li[nC].insert({(int64_t)ed[e.second].first, e.second});
			assign(e.first, u, nC, C);
		}
}

int T;
bool dfsT(int u, int pr, int C)
{
	T--;
	if(T == 0) return false;

	for(auto e: adj[u])
		if(e.first != pr && comp[e.first] == C)
			if(!dfsT(e.first, u, C)) return false;
	
	return true;
}

void add_comp(int i) 
{ 
	if(!li[i].empty())
		ST.insert({sum[i] - prev(li[i].end())->first, i}); 
}

void solve()
{
	sort(ALL(ed));

	DS.init(n);
	for(int i = 0; i < m; i++)
	{
		int u = ed[i].second.first, v = ed[i].second.second;
		if(!DS.connected(u, v))
		{
			in_tr[i] = 1;
			adj[u].pb({v, i});
			adj[v].pb({u, i});
			DS.unite(u, v);
		}
	}

	psz++;
	for(int i = 1; i <= n; i++)
		if(!vis[i])
			dfs(i, psz++);

	for(int i = 1; i <= n; i++)
		sum[comp[i]] += w[i];
	
	int answer = 0;
	for(int i = 0; i < m; i++)
		if(in_tr[i])
		{
			int64_t w = ed[i].first;
			li[comp[ed[i].second.second]].insert({w, i});
		}

	for(int i = 0; i <= n; i++)
		add_comp(i);

	while(true)
	{
		if(ST.empty()) break;

		auto it = ST.begin();
		if(it->first >= 0) break; 
	
		int Ccomp = it->second;

		int i = prev(li[Ccomp].end())->second; 
		int u = ed[i].second.first, v = ed[i].second.second;

		ST.erase(it);
		
		li[Ccomp].erase({(int64_t)ed[i].first, i});
		
		answer++;

		for(int tms = 1; ; tms <<= 1)
		{
			T = tms; if(dfsT(u, v, comp[u])) { break; }
			T = tms; if(dfsT(v, u, comp[u])) { swap(u, v); break; }
		}

		assign(u, v, psz++, comp[u]);
		
		sum[comp[v]] -= sum[comp[u]];
	
		add_comp(comp[u]);
		add_comp(comp[v]);
	}

	for(int i = 0; i < m; i++)
		if(!in_tr[i])
		{
			int u = ed[i].second.first, v = ed[i].second.second, w = ed[i].first;
			if(comp[u] != comp[v]) answer++;
			else if(w > sum[comp[u]]) answer++;
		}

	cout << answer << endl;
}

int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	read();
	solve();
	return 0;
}



Measured memory_bytes: 96372