#include <bits/stdc++.h>
      
#define FOR(i,a,b) for(ll i = (a); i < (ll)(b); i++)
#define REP(i,n) FOR(i,0,n)
#define YYS(x,arr) for(auto& x:arr)
#define PW(x) (1LL<<(x))
#define SZ(x) ((ll)(x).size())

#define pb emplace_back
#define fi first
#define se second

using namespace std;

using ld = long double;
using ll = long long int;

const ll INF = (ll)1e9 + 10;
const ll INFLL = (ll)1e18 + 10;
const ll MOD = 1e9+7;
     
template<class T> T &chmin( T &a , const T &b ){ return a = min(a,b); }
template<class T> T &chmax( T &a , const T &b ){ return a = max(a,b); }
template<class T> void UNIQUE(vector<T> &a){ a.erase(unique(a.begin(), a.end()), a.end()); }

template<class S, class T> ostream& operator << (ostream& os, const pair<S, T> v){
  os << "(" << v.first << ", " << v.second << ")"; return os;
}
template<class T> ostream& operator << (ostream& os, const vector<T> v){
  for(int i = 0; i < v.size(); i++){if(i > 0){os << " ";} os << v[i];} return os;
}
template<class T> ostream& operator << (ostream& os, const vector<vector<T>> v){
  for(int i = 0; i < v.size(); i++){if(i > 0){os << endl;} os << v[i];} return os;
}

ll in(){long long int x; scanf("%lld", &x); return x;}
ld fin(){double x; scanf("%lf", &x); return x;}
char yuyushiki[1000010]; string stin(){scanf( "%s", yuyushiki ); return yuyushiki;}

// head

struct Unionfind{
  vector<ll> size, par;
  Unionfind(){}
  Unionfind(int n) :  size(n, 1), par(n){
    for(int i = 0; i < n; i++){
      par[i] = i;
    }
  }
  int find(int x){
    if(par[x] == x){
      return x;
    }
    return par[x] = find(par[x]);
  }
  bool unite(int x, int y){
    x = find(x);
    y = find(y);
    if(x == y){
      return false;
    }
    if(size[y] < size[x]){
      swap( x , y );
    }
    par[x] = y;
    size[y] += size[x];
    return true;
  }
  bool same(int x, int y){
    return find(x) == find(y);
  }
};

using T = tuple<ll, ll, ll>;
using pl = pair<ll, ll>;

int main(){

  ll n = in();
  ll m = in();
  Unionfind uf(n);
  vector<ll> x(n);
  REP(i, n){
    x[i] = in();
    uf.size[i] = x[i];
  }
  vector<T> es(0);
  REP(i, m){
    ll a = in() - 1;
    ll b = in() - 1;
    ll c = in();
    es.pb(c, a, b);
  }

  sort(es.begin(), es.end());

  vector<bool> use(m, true);
  vector<ll> cau(n, -1);
  vector<pl> ch(m);
  vector<ll> sz(m);
  ll rr = -1;
  
  REP(i, m){
    ll c, a, b;
    tie(c, a, b) = es[i];
    a = uf.find(a);
    b = uf.find(b);
    if(!uf.same(a, b)){
      rr = i;
      ch[i] = pl(cau[a], cau[b]);
      uf.unite(a, b);
      ll r = uf.find(a);
      sz[i] = uf.size[r];
      cau[r] = i;
    }
  }

  queue<ll> que;
  que.push(rr);
  while(!que.empty()){
    ll i = que.front();
    que.pop();
    if(i == -1){
      continue;
    }
    ll c, a, b;
    tie(c, a, b) = es[i];
    if(sz[i] < c){
      use[i] = false;
      que.push(ch[i].fi);
      que.push(ch[i].se);
    }
  }

  uf = Unionfind(n);
  REP(i, n){
    uf.size[i] = x[i];
  }
  REP(i, m){
    ll c, a, b;
    tie(c, a, b) = es[i];
    if(use[i]){
      uf.unite(a, b);
    }
  }
  REP(i, m){
    ll c, a, b;
    tie(c, a, b) = es[i];
    if(use[i]){
      ll d = uf.size[uf.find(a)];
      if(d < c){
        use[i] = false;
      }
    }
  }

  ll ans = 0;
  REP(i, m){
    if(!use[i]){
      ans++;
    }
  }

  cout << ans << endl;
  
  return 0;
}


Measured memory_bytes: 10352