#include <bits/stdc++.h>
using namespace std;
template <typename T>
ostream &operator<<(ostream &os, vector<T> &v) {
  string sep = " ";
  if (v.size()) os << v[0];
  for (int i = 1; i < v.size(); i++) os << sep << v[i];
  return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
  for (int i = 0; i < v.size(); i++) is >> v[i];
  return is;
}
struct UnionFind {
  std::vector<int> par, rnk, cnt;
  UnionFind(int n) {
    par.assign(n, 0);
    rnk.assign(n, 0);
    cnt.assign(n, 1);
    for (int i = 0; i < n; i++) par[i] = i;
  }
  int root(int i) {
    if (par[i] == i) return i;
    return par[i] = root(par[i]);
  }
  void unite(int i, int j) {
    int ri = root(i);
    int rj = root(j);
    if (ri == rj) return;
    if (rnk[ri] == rnk[rj]) {
      cnt[rj] += cnt[ri];
      par[ri] = rj;
      rnk[rj]++;
    } else if (rnk[ri] < rnk[rj]) {
      cnt[rj] += cnt[ri];
      par[ri] = rj;
    } else {
      cnt[ri] += cnt[rj];
      par[rj] = ri;
    }
  }
  bool same(int i, int j) { return root(i) == root(j); }
  int count(int i) { return cnt[root(i)]; }
};
int main() {
  ios_base::sync_with_stdio(false);
  cout << setprecision(20) << fixed;
  int n, m;
  cin >> n >> m;
  vector<long long> x(n);
  cin >> x;
  vector<tuple<long long, int, int>> yab(m);
  for (int i = 0; i < m; i++) {
    cin >> get<1>(yab[i]) >> get<2>(yab[i]) >> get<0>(yab[i]);
    get<1>(yab[i])--;
    get<2>(yab[i])--;
  }
  vector<long long> sum(x), emax(n);
  map<int, vector<long long>> unused;
  set<int> ng;
  sort(yab.begin(), yab.end());
  UnionFind uf(n);
  int k = 0;
  for (int i = 0; i < m; i++) {
    long long y = get<0>(yab[i]);
    int a = get<1>(yab[i]);
    int b = get<2>(yab[i]);
    int ra = uf.root(a);
    int rb = uf.root(b);
    long long sa = sum[ra];
    long long sb = sum[rb];
    long long ea = emax[ra];
    long long eb = emax[rb];
    if (!uf.same(a, b)) {
      uf.unite(a, b);
      int r = uf.root(a);
      sum[r] = sa + sb;
      emax[r] = y;
      ng.erase(ra);
      ng.erase(rb);
      if (sa + sb < y) {
        ng.insert(r);
      }
      if (ng.empty()) {
        k = i;
      }
    }
  };
  uf = UnionFind(n);
  vector<bool> used(m);
  sum = vector<long long>(x);
  for (int i = 0; i <= k; i++) {
    long long y = get<0>(yab[i]);
    int a = get<1>(yab[i]);
    int b = get<2>(yab[i]);
    int ra = uf.root(a);
    int rb = uf.root(b);
    long long sa = sum[ra];
    long long sb = sum[rb];
    if (!uf.same(a, b)) {
      uf.unite(a, b);
      sum[uf.root(a)] = sa + sb;
      used[i] = true;
    }
  }
  for (int i = 0; i < m; i++) {
    long long y = get<0>(yab[i]);
    int a = get<1>(yab[i]);
    int b = get<2>(yab[i]);
    int ra = uf.root(a);
    int rb = uf.root(b);
    long long sa = sum[ra];
    long long sb = sum[rb];
    if (!uf.same(a, b)) continue;
    if (sa >= y) {
      used[i] = true;
    }
  }
  int ans = 0;
  for (int i = 0; i < m; i++) {
    if (!used[i]) ans++;
  }
  cout << ans << endl;
  return 0;
}
