#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using i_i = tuple<int, int>;
struct union_find {
  vector<int> v;
  union_find(int n) : v(n, -1) {}
  int find(int x) { return v[x] < 0 ? x : v[x] = find(v[x]); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (-v[x] < -v[y]) swap(x, y);
    v[x] += v[y];
    v[y] = x;
  }
  bool root(int x) { return v[x] < 0; }
  bool same(int x, int y) { return find(x) == find(y); }
  int size(int x) { return -v[find(x)]; }
};
int main() {
  int N, M;
  cin >> N >> M;
  vector<int> a(N);
  for (int u = 0; u < (N); u++) cin >> a[u];
  vector<int> x(M), y(M), z(M);
  for (int i = 0; i < (M); i++) {
    cin >> x[i] >> y[i] >> z[i];
    x[i]--;
    y[i]--;
  }
  vector<i_i> zi(M);
  for (int i = 0; i < (M); i++) zi[i] = i_i(z[i], i);
  sort((zi).begin(), (zi).end());
  union_find uf(N);
  vector<ll> A(N);
  for (int u = 0; u < (N); u++) A[u] = a[u];
  vector<int> E(N), unko(N);
  int ans = 0;
  for (auto p : zi) {
    int i = get<1>(p);
    int u = x[i], v = y[i], w = z[i];
    if (uf.same(u, v)) {
      E[uf.find(u)]++;
      if (w <= A[uf.find(u)]) {
        unko[uf.find(u)]++;
        ans++;
      }
    } else {
      ll tmp = A[uf.find(u)] + A[uf.find(v)];
      ll hoge = E[uf.find(u)] + E[uf.find(v)];
      uf.unite(u, v);
      A[uf.find(u)] = tmp;
      E[uf.find(u)] = hoge + 1;
      if (tmp >= w) {
        ans += E[uf.find(u)] - unko[uf.find(u)];
        unko[uf.find(u)] = E[uf.find(u)];
      }
    }
  }
  cout << M - ans << endl;
}
