#include <bits/stdc++.h>
 
#define ll long long
#define OK puts("ok");
 
using namespace std;
 
const int N = (int)1e5 + 7;
 
struct edge {
  int u, v, w;
  edge() {}
  edge(int _u, int _v, int _w) {
    u = _u;
    v = _v;
    w = _w;
  }
};
 
int roll[N];
pair <int, int> asd[N];
int cnt = 0;
 
struct DSU {
  int par[N], siz[N];
  ll sum[N];
  DSU() {
    iota(par, par + N, 0);
    fill(siz, siz + N, 1);
  }
  int getpar(int a) {
    if (par[a] == a) return a;
    return getpar(par[a]);
  }
  void connect(int a, int b) {
    a = getpar(a);
    b = getpar(b);
    if (a != b) {
      if (siz[a] > siz[b]) swap(a, b);
      asd[cnt] = {a, b};
      roll[cnt++] = par[a];
      par[a] = b;
      sum[b] += sum[a];
      siz[b] += siz[a];
    }
  }
  void rollback() {
    int a = asd[cnt].first;
    int b = asd[cnt].second;
    siz[b] -= siz[a];
    sum[b] -= sum[a];
    par[a] = roll[cnt];
  }
};
DSU dsu;
 
int n, m;
vector <edge> vec;
 
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%lld", &dsu.sum[i]);
  }
  for (int i = 1; i <= m; i++) {
    int u, v, w;
    scanf("%d %d %d", &u, &v, &w);
    vec.push_back({u, v, w});
  }
  sort(vec.begin(), vec.end(), [&](const edge &A, const edge &B) {
    return A.w < B.w;
  });
  vector <int> ind;
  {
    int i = 0;
    for (auto to : vec) {
      int a, b;
      a = to.u;
      b = to.v;
      if (dsu.getpar(a) != dsu.getpar(b)) {
        ind.push_back(i);
        dsu.connect(a, b);
      }
      i++;
    }
  }
  reverse(ind.begin(), ind.end());
  for (int i = 0; i < ind.size(); i++) {
    cnt--;
    if (vec[ind[i]].w > dsu.sum[dsu.getpar(vec[ind[i]].u)]) {
      dsu.rollback();
    }
  }
  int ans = 0;
  for (auto to : vec) {
    if (dsu.getpar(to.v) != dsu.getpar(to.u) || to.w > dsu.sum[dsu.getpar(to.u)]) {
      ans++;
    }
  }
  cout << ans;
}