#include <bits/stdc++.h>
using namespace std;
const int MX = 100010;
int n, m;
int X[MX];
struct edge {
  int u, v, c;
  void in() { cin >> u >> v >> c; }
  bool operator<(const edge &e) const { return c < e.c; }
} E[MX];
int U[MX], sub[MX];
long long sz[MX];
multiset<int> wait[MX];
void init() {
  for (int i = 1; i <= n; i++) U[i] = i, sz[i] = X[i], sub[i] = 1;
}
int find(int x) { return x == U[x] ? x : U[x] = find(U[x]); }
void unite(int x, int y) {
  x = find(x), y = find(y);
  if (x == y) return;
  if (sub[x] < sub[y]) swap(x, y);
  U[y] = x;
  sz[x] += sz[y];
  sub[x] += sub[y];
  for (int e : wait[y]) wait[x].insert(e);
  wait[y].clear();
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= n; i++) cin >> X[i];
  for (int i = 1; i <= m; i++) E[i].in();
  init();
  sort(E + 1, E + m + 1);
  int used = 0, sum = 0;
  for (int i = 1; i <= m; i++) {
    unite(E[i].u, E[i].v);
    int x = find(E[i].u);
    wait[x].insert(E[i].c), sum++;
    while (!wait[x].empty()) {
      auto it = wait[x].begin();
      int y = *it;
      if (sz[x] < y) break;
      wait[x].erase(it), sum--;
    }
    if (sum == 0) {
      used = i;
    }
  }
  cout << m - used << '\n';
  return 0;
  return 0;
}
