#include <bits/stdc++.h>
using namespace std;
int X[100010];
bool seen[100010];
vector<pair<int, pair<int, int> > > V;
class UFDS {
 public:
  vector<int> p, rank, bad;
  vector<long long> sz;
  UFDS(const int N) {
    p.assign(N, 0);
    rank.assign(N, 0);
    sz.assign(N, 0);
    bad.assign(N, 0);
    for (int i = 1; i < N; i++) p[i] = i, sz[i] = X[i];
  }
  int findSet(const int i) { return p[i] == i ? i : p[i] = findSet(p[i]); }
  int getSize(const int i) { return sz[findSet(i)]; }
  bool isSameSet(const int i, const int j) { return findSet(i) == findSet(j); }
  void clearBad(const int i) { bad[i] = 0; }
  void incBad(const int i) { bad[i]++; }
  int getBad(const int i) { return bad[i]; }
  void unite(const int i, const int j) {
    int r1 = findSet(i), r2 = findSet(j);
    if (r1 == r2) return;
    rank[r1] >= rank[r2] ? (p[r2] = r1, sz[r1] += sz[r2], bad[r1] += bad[r2])
                         : (p[r1] = r2, sz[r2] += sz[r1], bad[r2] += bad[r1]);
    if (rank[r1] == rank[r2]) rank[r1]++;
  }
};
int main() {
  int N, M, A, B, Y;
  scanf("%d %d", &N, &M);
  for (int i = 1; i <= N; i++) scanf("%d", &X[i]);
  UFDS U(N + 5);
  while (M--) {
    scanf("%d %d %d", &A, &B, &Y);
    V.push_back(pair<int, pair<int, int> >(Y, pair<int, int>(A, B)));
  }
  sort(V.begin(), V.end());
  for (int i = 0; i < (int)V.size(); i++) {
    int p1 = U.findSet(V[i].second.first);
    int p2 = U.findSet(V[i].second.second);
    U.unite(p1, p2);
    if (U.getSize(U.findSet(p1)) < V[i].first)
      U.incBad(U.findSet(p1));
    else
      U.clearBad(U.findSet(p1));
  }
  int ans = 0;
  for (int i = 1; i <= N; i++)
    if (!seen[U.findSet(i)])
      seen[U.findSet(i)] = 1, ans += U.getBad(U.findSet(i));
  printf("%d\n", ans);
  return 0;
}
