#include <bits/stdc++.h>
using namespace std;
template <typename A, typename B>
inline void chmin(A &a, B b) {
  if (a > b) a = b;
}
template <typename A, typename B>
inline void chmax(A &a, B b) {
  if (a < b) a = b;
}
struct UnionFindTree {
  vector<long long> par, sz, num, sum;
  UnionFindTree(long long n) {
    par.resize(n);
    sz.resize(n);
    sum.resize(n);
    for (long long i = 0; i < n; i++) {
      par[i] = i;
      sz[i] = 1;
    }
  }
  long long find(long long x) {
    return x == par[x] ? x : par[x] = find(par[x]);
  }
  void unite(long long x, long long y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (sz[x] < sz[y]) swap(x, y);
    sz[x] += sz[y];
    par[y] = x;
    sum[x] += sum[y];
  }
  bool areSame(long long x, long long y) { return find(x) == find(y); }
  long long size(long long x) { return sz[find(x)]; }
};
long long N, M;
long long X[111111];
long long A[111111], B[111111], Y[111111];
vector<pair<long long, long long> > G[111111];
long long ans;
bool used[111111];
void dfs(long long v, long long val) {
  used[v] = true;
  for (auto &e : G[v]) {
    if (e.second > val) continue;
    ans++;
    if (used[e.first]) continue;
    dfs(e.first, val);
  }
}
signed main() {
  cin >> N >> M;
  UnionFindTree uf(N);
  for (long long i = 0; i < (N); i++) {
    cin >> X[i];
    uf.sum[i] = X[i];
  }
  vector<pair<long long, long long> > es;
  for (long long i = 0; i < (M); i++) {
    cin >> A[i] >> B[i] >> Y[i];
    A[i]--;
    B[i]--;
    es.push_back({Y[i], i});
    G[A[i]].push_back({B[i], Y[i]});
    G[B[i]].push_back({A[i], Y[i]});
  }
  sort((es).begin(), (es).end());
  vector<long long> lis;
  for (long long i = 0; i < (es.size()); i++) {
    long long k = es[i].second;
    uf.unite(A[k], B[k]);
    if (uf.sum[uf.find(A[k])] >= Y[k]) {
      lis.push_back(i);
    }
  }
  for (long long i = (long long)lis.size() - 1; i >= 0; i--) {
    if (used[A[lis[i]]]) continue;
    dfs(A[lis[i]], Y[lis[i]]);
  }
  cout << M - ans / 2 << endl;
  return 0;
}
