#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using PII = pair<ll, ll>;
template <typename T>
void chmin(T &a, const T &b) {
  a = min(a, b);
}
template <typename T>
void chmax(T &a, const T &b) {
  a = max(a, b);
}
struct FastIO {
  FastIO() {
    cin.tie(0);
    ios::sync_with_stdio(0);
  }
} fastiofastio;
const ll INF = 1LL << 60;
struct UnionFind {
  vector<ll> par, s, w;
  UnionFind(int n, vector<ll> a) : par(n), s(n, 1), w(a) {
    iota(par.begin(), par.end(), 0);
  }
  int find(int x) {
    if (par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (s[x] < s[y])
      par[x] = y, s[y] += s[y], w[y] += w[x];
    else
      par[y] = x, s[x] += s[y], w[x] += w[y];
  }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return s[find(x)]; }
  int weight(int x) { return w[find(x)]; }
};
int main(void) {
  ll n, m;
  cin >> n >> m;
  vector<ll> x(n);
  for (ll i = (ll)0; i < (ll)n; ++i) cin >> x[i];
  vector<ll> a(m), b(m), y(m);
  vector<vector<PII>> g(n);
  for (ll i = (ll)0; i < (ll)m; ++i) {
    cin >> a[i] >> b[i] >> y[i];
    a[i]--, b[i]--;
    g[a[i]].push_back({b[i], i});
    g[b[i]].push_back({a[i], i});
  }
  vector<ll> ord(m);
  iota(ord.begin(), ord.end(), 0LL);
  sort(ord.begin(), ord.end(), [&](ll l, ll r) { return y[l] < y[r]; });
  vector<ll> ok;
  UnionFind uf(n, x);
  for (auto i : ord) {
    uf.unite(a[i], b[i]);
    if (uf.weight(a[i]) >= y[i]) ok.push_back(i);
  };
  ll ret = 0;
  vector<bool> used(m);
  function<void(ll, ll)> dfs = [&](ll v, ll ub) {
    for (auto to : g[v]) {
      if (y[to.second] <= ub && !used[to.second]) {
        ret++;
        used[to.second] = true;
        dfs(to.first, ub);
      }
    }
  };
  reverse(ok.begin(), ok.end());
  for (auto i : ok)
    if (!used[i]) dfs(a[i], y[i]);
  cout << m - ret << endl;
  return 0;
}
