#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(int (i) = (s);(i) <= (e);(i)++)
#define all(x) x.begin(),x.end()

#include <vector>
#include <set>
using namespace std;

struct union_find {
  vector<int> par;
  vector<int> rank;
  union_find(int n) : par(n) , rank(n) {
    for(int i = 0;i < n;i++) par[i] = i;
  }
  int root(int i) {
    return par[i] == i ? i : par[i] = root(par[i]);
  }
  pair<int,int> unite(int x,int y) {
    x = root(x);
    y = root(y);
    if(x == y) return pair<int,int>(-1,-1);
    if(rank[x] < rank[y]) {
      par[x] = y;
      return {y , x};
    }
    else {
      par[y] = x;
      if(rank[x] == rank[y]) rank[x]++;
      return {x,y};
    }
  }
  bool same(int x,int y) {
    return root(x) == root(y);
  }
};

int N,M;
vector<i64> X;
vector<i64> A,B,Y;

i64 w[101010];
i64 reg[101010];
i64 cnt = 0;

int main() {
  cin >> N >> M;
  X.resize(N);
  rep(i,0,N - 1) cin >> X[i];
  A.resize(M);
  B.resize(M);
  Y.resize(M);
  rep(i,0,M - 1) {
    cin >> A[i] >> B[i] >> Y[i];
    A[i]--;
    B[i]--;
  }
  i64 ans = 0;
  vector<pair<i64,i64>> vec;
  rep(i,0,M - 1) vec.push_back({Y[i], i});
  rep(i,0,N - 1) w[i] = X[i];
  union_find uf(N);
  sort(all(vec));
  for(auto p : vec) {
    i64 i = p.second;
    i64 y = p.first;
    i64 a = A[i];
    i64 b = B[i];
    if(uf.same(a, b)) {
      i64 r = uf.root(a);
      if(w[r] < y) reg[r]++;
      else ans++;
    }
    else {
      auto pp = uf.unite(a,b);
      a = pp.first;
      b = pp.second;
      w[a] += w[b];
      reg[a] += reg[b];
      w[b] = 0;
      reg[b] = 0;
      if(w[a] < y) {
        reg[a]++;
      }
      else {
        ans++;
        ans += reg[a];
        reg[a] = 0;
      }
    }
  }
  cout << M - ans << endl;
}
