#include <bits/stdc++.h>
using namespace std;
const long long MAXN = 100005;
struct ii {
  long long a, b, c;
  bool operator<(ii o) const { return a < o.a; }
};
long long N, M, poin[MAXN], par[MAXN], sum[MAXN];
pair<long long, long long> ren[MAXN];
vector<long long> listen[MAXN];
ii edge[MAXN];
long long find(long long x) { return par[x] == x ? x : par[x] = find(par[x]); }
void merge(long long x, long long y) {
  x = find(x), y = find(y);
  if (x == y) return;
  par[x] = y;
  sum[y] += sum[x];
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> N >> M;
  for (long long i = 1; i <= N; i++) cin >> poin[i];
  for (long long i = 0; i < M; i++) {
    long long x, y, z;
    cin >> x >> y >> z;
    edge[i] = {z, x, y};
  }
  sort(edge, edge + M);
  for (long long i = 0; i < M; i++) {
    ren[i] = {i, M};
  }
  for (long long iter = 0; iter < 30; iter++) {
    for (long long j = 1; j <= N; j++) {
      par[j] = j;
      sum[j] = poin[j];
    }
    for (long long i = 0; i <= M; i++) listen[i].clear();
    for (long long i = 0; i < M; i++) {
      if (ren[i].first == ren[i].second) continue;
      listen[(ren[i].first + ren[i].second) / 2].push_back(i);
    }
    for (long long i = 0; i < M; i++) {
      merge(edge[i].b, edge[i].c);
      for (auto j : listen[i]) {
        long long x = find(edge[j].b);
        if (sum[x] >= edge[j].a)
          ren[j].second = i;
        else
          ren[j].first = i + 1;
      }
    }
  }
  for (long long i = M - 1; i >= 0; i--) {
    assert(ren[i].first == ren[i].second);
    if (ren[i].second <= i) {
      cout << M - 1 - i << "\n";
      return 0;
    }
  }
  cout << M << "\n";
}
