#include <bits/stdc++.h>
using namespace std;
int N, M;
vector<long long> X;
vector<tuple<long long, int, int>> edges;
class UnionFind {
  int n;
  vector<int> par;
  vector<int> rank;

 public:
  vector<int> sm;
  vector<int> cnt;
  UnionFind(int a) : n(a), rank(a, 0) {
    par.reserve(n);
    for (int i = 0; i < a; i++) par.push_back(i);
    sm.resize(n, 0);
    cnt.resize(n, 0);
    for (int i = 0; i < n; i++) sm[i] = X[i];
  }
  int find(int x) {
    if (par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  void unite(int x, int y) {
    int x_root = find(x);
    int y_root = find(y);
    if (x_root == y_root) {
      cnt[x_root]++;
      return;
    }
    if (rank[x_root] > rank[y_root]) {
      par[y_root] = x_root;
      cnt[x_root] += cnt[y_root] + 1;
      sm[x_root] += sm[y_root];
    } else if (rank[x_root] < rank[y_root]) {
      par[x_root] = y_root;
      cnt[y_root] += cnt[x_root] + 1;
      sm[y_root] += sm[x_root];
    } else if (x_root != y_root) {
      par[y_root] = x_root;
      rank[x_root]++;
      cnt[x_root] += cnt[y_root] + 1;
      sm[x_root] += sm[y_root];
    }
  }
  bool same(int x, int y) { return find(x) == find(y); }
  long long get_sum(int x) { return sm[find(x)]; }
  long long get_cnt(int x) { return cnt[find(x)]; }
  void reset_cnt(int x) { cnt[find(x)] = 0; }
};
int main() {
  cin >> N >> M;
  X.resize(N);
  edges.resize(M);
  for (int i = 0; i < N; i++) cin >> X[i];
  UnionFind uf(N);
  for (int i = 0; i < M; i++) {
    int A, B;
    long long Y;
    cin >> A >> B >> Y;
    A--;
    B--;
    edges[i] = make_tuple(Y, A, B);
  }
  sort(edges.begin(), edges.end());
  long long ans = 0;
  for (auto edge : edges) {
    int A, B;
    long long Y;
    tie(Y, A, B) = edge;
    uf.unite(A, B);
    if (Y <= uf.get_sum(A)) {
      ans += uf.get_cnt(A);
      uf.reset_cnt(A);
    }
  }
  cout << M - ans << endl;
  return 0;
}
