#include <bits/stdc++.h>
using namespace std;
class UnionFind {
 private:
  vector<long long> data;
  vector<long long> sum;

 public:
  UnionFind(long long n, vector<long long> sum) : data(n, -1), sum(sum) {}
  long long size(long long i) { return -data[find(i)]; }
  bool root(long long i) { return data[i] < 0; }
  bool same(long long i, long long j) { return find(i) == find(j); }
  long long find(long long i) {
    return root(i) ? i : (data[i] = find(data[i]));
  }
  bool unite(long long i, long long j) {
    if (same(i, j)) return false;
    sum[find(i)] += sum[find(j)];
    data[find(i)] += data[find(j)];
    data[find(j)] = find(i);
    return true;
  }
  long long get(long long i) { return sum[find(i)]; }
};
struct edge {
  long long u, v, w;
};
int main(void) {
  long long N, M;
  cin >> N >> M;
  vector<long long> W(N);
  for (long long i = ((long long)0); i < ((long long)N); i++) cin >> W[i];
  vector<edge> edges(M);
  for (long long i = ((long long)0); i < ((long long)M); i++)
    cin >> edges[i].u >> edges[i].v >> edges[i].w, edges[i].u--, edges[i].v--;
  sort(edges.begin(), edges.end(),
       [](const edge x, const edge y) { return x.w < y.w; });
  long long cnt = 0, ans = 0;
  vector<bool> ok(N, true);
  UnionFind uf(N, W);
  for (long long i = ((long long)0); i < ((long long)M); i++) {
    edge e = edges[i];
    long long u = e.u, v = e.v, w = e.w;
    if (!uf.same(u, v)) {
      if (!ok[uf.find(u)]) cnt--;
      if (!ok[uf.find(v)]) cnt--;
      uf.unite(u, v);
    } else {
      if (!ok[uf.find(u)]) cnt--;
    }
    if (uf.get(u) < w) {
      ok[uf.find(u)] = false;
      cnt++;
    } else {
      ok[uf.find(u)] = true;
    }
    if (cnt == 0) ans = i + 1;
  }
  cout << M - ans << endl;
}
