#include <bits/stdc++.h>
#define REP(i, a, n) for (ll i = ((ll) a); i < ((ll) n); i++)
using namespace std;
typedef long long ll;

class UnionFind {
private:
  vector<ll> data;
  vector<ll> sum;

public:
  UnionFind(ll n, vector<ll> sum): data(n, -1), sum(sum) {
  }

  ll size(ll i) { return -data[find(i)]; }
  bool root(ll i) { return data[i] < 0; }
  bool same(ll i, ll j) { return find(i) == find(j); }

  ll find(ll i) { return root(i) ? i : (data[i] = find(data[i])); }

  bool unite(ll i, ll j) {
    if(same(i, j)) return false;
    sum[find(i)] += sum[find(j)];
    data[find(i)] += data[find(j)];
    data[find(j)] = find(i);
    return true;
  }

  ll get(ll i) {
    return sum[find(i)];
  }
};

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

int main(void) {
  ll N, M;
  cin >> N >> M;
  vector<ll> W(N);
  REP(i, 0, N) cin >> W[i];
  vector<edge> edges(M);
  REP(i, 0, M) cin >> edges[i].u >> edges[i].v >> edges[i].w, edges[i].u--, edges[i].v--;

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

  ll ans = 0;
  vector<ll> cnt(N, 0);
  UnionFind uf(N, W);

  REP(i, 0, M) {
    edge e = edges[i];
    ll u = e.u, v = e.v, w = e.w;

    if (!uf.same(u, v)) {
      cnt[uf.find(u)] += cnt[uf.find(v)];
      cnt[uf.find(u)]++;
      uf.unite(u, v);
    } else {
      cnt[uf.find(u)]++;
    }

    if (uf.get(u) >= w) {
      ans += cnt[uf.find(u)];
      cnt[uf.find(u)] = 0;
    }
  }

  cout << M - ans << endl;
}