#include <iostream>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <fstream>
#include <cassert>
#include <cstring>
#include <unordered_set>
#include <unordered_map>
#include <numeric>
#include <ctime>
#include <bitset>
#include <complex>
#include <chrono>
#include <random>
#include <functional>

using namespace std;

typedef long long ll;

struct Edge {
	int u;
	int v;
	int w;
	int alive;

	Edge() {
		u = -1;
		v = -1;
		w = -1;
		alive = 0;
	}

	Edge(int u_, int v_, int w_) {
		u = u_;
		v = v_;
		w = w_;
		alive = 1;
	}

	int get(int x) {
		if (x == u) {
			return v;
		} else {
			return u;
		}
	}

	bool operator<(const Edge &other) const {
		return w < other.w;
	}
};

struct Dsu {
	int n;
	vector<int> p;
	vector<int> rank;

	Dsu() {}

	Dsu(int n_) {
		n = n_;
		p.resize(n);
		iota(p.begin(), p.end(), 0);
		rank.resize(n);
	}

	int get(int v) {
		if (p[v] != v) {
			p[v] = get(p[v]);
		} 
		return p[v];
	}

	int merge(int a, int b) {
		a = get(a);
		b = get(b);
		if (a == b) {
			return 0;
		} else {
			if (rank[a] < rank[b]) {
				swap(a, b);
			}
			p[b] = a;
			if (rank[a] == rank[b]) {
				rank[a]++;
			}
			return 1;
		}
	}
};

const int N = 1e5 + 2;

int a[N];
vector<Edge> E;
vector<int> g[N];

int pnt_c = 1;
int comp[N];
int size_comp[N];
ll sum_a_comp[N];
set<pair<Edge, int>> edge_comp[N];

vector<int> seen;
vector<int> seen_e;

int used[N];

int pnt[N];

void double_bfs(int s1, int s2) {
	queue<int> q1;
	queue<int> q2;
	vector<int> seen1 = {s1};
	vector<int> seen2 = {s2};
	vector<int> seen_e1;
	vector<int> seen_e2;
	used[s1] = 1;
	used[s2] = 1;
	q1.push(s1);
	q2.push(s2);
	for (int c = 0; ; c++) {
		if (c & 1) {
			while (!q1.empty()) {
				int v = q1.front();
				int any = 0;
				for (; pnt[v] < (int)g[v].size(); pnt[v]++) {
					if (E[g[v][pnt[v]]].alive == 0) continue;
					int u = E[g[v][pnt[v]]].get(v);
					if (!used[u]) {
						used[u] = 1;
						q1.push(u);
						seen1.push_back(u);
						seen_e1.push_back(g[v][pnt[v]]);
						any = 1;
						break;
					}
				}
				if (!any) {
					q1.pop();
				} else {
					break;
				}
			}
			if (q1.empty()) {
				seen = seen1;
				seen_e = seen_e1;
				break;
			}
		} else {
			while (!q2.empty()) {
				int v = q2.front();
				int any = 0;
				for (; pnt[v] < (int)g[v].size(); pnt[v]++) {
					if (E[g[v][pnt[v]]].alive == 0) continue;
					int u = E[g[v][pnt[v]]].get(v);
					if (!used[u]) {
						used[u] = 1;
						q2.push(u);
						seen2.push_back(u);
						seen_e2.push_back(g[v][pnt[v]]);
						any = 1;
						break;
					}
				}
				if (!any) {
					q2.pop();
				} else {
					break;
				}
			}
			if (q2.empty()) {
				seen = seen2;
				seen_e = seen_e2;
				break;
					
			}
		}
	}
	for (auto x : seen1) {
		used[x] = 0;
		pnt[x] = 0;
	}
	for (auto x : seen2) {
		used[x] = 0;
		pnt[x] = 0;
	}
}

queue<int> bad_comps;

void split(int ind) {
	E[ind].alive = 0;
	Edge e = E[ind];
	assert(comp[e.u] == comp[e.v]);
	int W = comp[e.u];
	//
	double_bfs(e.u, e.v);
	//
	for (auto t : seen) {
		size_comp[comp[t]]--;
		sum_a_comp[comp[t]] -= a[t];
		comp[t] = pnt_c;
		size_comp[comp[t]]++;
		sum_a_comp[comp[t]] += a[t];
	}
	for (auto t : seen_e) {
		edge_comp[W].erase({E[t], t});
		edge_comp[pnt_c].insert({E[t], t});
	}
	edge_comp[W].erase({E[ind], ind});
	if (!edge_comp[W].empty() && sum_a_comp[W] < edge_comp[W].rbegin()->first.w) {
		bad_comps.push(W);
	}
	if (!edge_comp[pnt_c].empty() && sum_a_comp[pnt_c] < edge_comp[pnt_c].rbegin()->first.w) {
		bad_comps.push(pnt_c);
	}
	pnt_c++;
}

signed main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
	}
	for (int i = 0; i < m; i++) {
		int u, v, w;
		cin >> u >> v >> w;
		u--;
		v--;
		E.push_back(Edge({u, v, w}));
	}
	sort(E.begin(), E.end());
	Dsu D(n);
	for (int i = 0; i < m; i++) {
		if (D.merge(E[i].u, E[i].v)) {
			edge_comp[0].insert({E[i], i});
			g[E[i].v].push_back(i);
			g[E[i].u].push_back(i);
		}
	}
	size_comp[0] = n;
	for (int i = 0; i < n; i++) {
		sum_a_comp[0] += a[i];
	}
	if (!edge_comp[0].empty() && sum_a_comp[0] < edge_comp[0].rbegin()->first.w) {
		bad_comps.push(0);
	}
	while (!bad_comps.empty()) {
		int v = bad_comps.front();
		bad_comps.pop();
		split(edge_comp[v].rbegin()->second);
	}
	int ans = 0;
	for (auto t : E) {
		if (comp[t.u] == comp[t.v] && sum_a_comp[comp[t.u]] >= t.w) ans++;
	}
	cout << m - ans << '\n';
}



Measured memory_bytes: 25452