#include <bits/stdc++.h>
using namespace std;
using vint = vector<long long>;
using pint = pair<long long, long long>;
using vpint = vector<pint>;
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;
}
template <class A, class B>
ostream& operator<<(ostream& ost, const pair<A, B>& p) {
  ost << "{" << p.first << "," << p.second << "}";
  return ost;
}
template <class T>
ostream& operator<<(ostream& ost, const vector<T>& v) {
  ost << "{";
  for (long long i = 0; i < v.size(); i++) {
    if (i) ost << ",";
    ost << v[i];
  }
  ost << "}";
  return ost;
}
struct UnionFindTree {
  vector<int32_t> par, sz;
  UnionFindTree(int32_t n = 0) : par(n), sz(n) {
    for (int32_t i = 0; i < n; i++) {
      par[i] = i;
      sz[i] = 1;
    }
  }
  int32_t find(int32_t x) { return x == par[x] ? x : par[x] = find(par[x]); }
  void unite(int32_t x, int32_t 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;
  }
  bool same(int32_t x, int32_t y) { return find(x) == find(y); }
  int32_t size(int32_t x) { return sz[find(x)]; }
};
long long N, M;
long long X[111111];
long long sat[111111];
long long score[111111];
priority_queue<pint, vector<pint>, greater<pint>> que[111111];
set<pint> bucket[111111];
signed main() {
  scanf("%lld%lld", &N, &M);
  for (long long i = 0; i < (N); i++) scanf("%lld", &X[i]);
  UnionFindTree uf(N);
  vector<tuple<long long, long long, long long>> es;
  for (long long i = 0; i < (M); i++) {
    long long a, b, c;
    scanf("%lld%lld%lld", &a, &b, &c);
    a--;
    b--;
    es.emplace_back(c, a, b);
  }
  sort((es).begin(), (es).end());
  for (long long i = 0; i < (M); i++) {
    long long c, a, b;
    tie(c, a, b) = es[i];
    if (!uf.same(a, b)) {
      uf.unite(a, b);
    } else {
      bucket[a].insert(pint(i, c));
      bucket[b].insert(pint(i, c));
    }
  }
  uf = UnionFindTree(N);
  long long num = 0;
  for (long long i = 0; i < (M); i++) {
    long long c, a, b;
    tie(c, a, b) = es[i];
    a = uf.find(a);
    b = uf.find(b);
    if (a == b) continue;
    uf.unite(a, b);
    if (uf.find(a) != a) swap(a, b);
    X[a] += X[b];
    if (que[a].size() < que[b].size()) swap(que[a], que[b]);
    while (que[b].size()) {
      que[a].push(que[b].top());
      que[b].pop();
    }
    que[a].emplace(c, 0);
    num++;
    if (bucket[a].size() < bucket[b].size()) {
      swap(bucket[a], bucket[b]);
    }
    for (auto& p : bucket[b]) {
      if (bucket[a].find(p) == bucket[a].end()) {
        bucket[a].insert(p);
      } else {
        bucket[a].erase(p);
        que[a].emplace(p.second, 1);
      }
    }
    while (que[a].size() && que[a].top().first <= X[a]) {
      auto q = que[a].top();
      que[a].pop();
      if (q.second == 0) {
        sat[num]++;
      }
      score[num]++;
    }
  }
  long long ans = M;
  for (long long i = 0; i <= N - 1; i++) {
    sat[i + 1] += sat[i];
    score[i + 1] += score[i];
    if (sat[i] == i) chmin(ans, M - score[i]);
  }
  cout << ans << endl;
  return 0;
}
