#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef pair<ll,P> P2;
#define int ll
P2 mk_P(ll a,ll b,ll c){
  return P2(a,P(b,c));
}
struct uftree{
private:
  vector<ll> par,val,rnk;
public:
  uftree(ll n){
    par.resize(n+5);
    val.resize(n+5);
    rnk.resize(n+5);
    for(int i=0;i<=n;i++){
      par[i]=i;
      val[i]=0;
      rnk[i]=0;
    }
  }
  ll find(ll pos){
    if(par[pos]==pos) return pos;
    else return par[pos]=find(par[pos]);
  }
  void set_val(ll pos,ll x){
    val[pos]=x;
  }
  bool same(ll a,ll b){
    return find(a)==find(b);
  }
  ll sum(ll pos){
    return val[find(pos)];
  }
  void unite(ll a,ll b){
    a=find(a);
    b=find(b);
    if(same(a,b)) return;
    if(rnk[a]<rnk[b]){
      par[a]=b;
      val[b]+=val[a];
    }
    else{
      par[b]=a;
      val[a]+=val[b];
      if(rnk[a]==rnk[b]) rnk[a]++;
    }
  }
};
bool kans[100005],ans[100005];
vector<P2> node[100005];
void dfs(ll pos,ll border){
  for(int i=0;i<node[pos].size();i++){
    ll to=node[pos][i].first,cos=node[pos][i].second.first;
    ll idx=node[pos][i].second.second;
    if(!ans[idx]&&cos<=border){
      ans[idx]=true;
      dfs(to,border);
    }
  }
}
signed main(){
  ll n,m;
  cin>>n>>m;
  uftree uf(n+5);
  for(int i=1;i<=n;i++){
    ll a;
    cin>>a;
    uf.set_val(i,a);
  }
  vector<P2> vec;
  for(int i=0;i<m;i++){
    kans[i]=false;
    ll a,b,c;
    cin>>a>>b>>c;
    vec.push_back(mk_P(c,a,b));
    node[a].push_back(mk_P(b,c,i));
    node[b].push_back(mk_P(a,c,i));
  }
  sort(vec.begin(),vec.end());
  for(int i=0;i<m;i++){
    ans[i]=false;
    ll s=vec[i].second.first,t=vec[i].second.second;
    ll cos=vec[i].first;
    uf.unite(s,t);
    if(uf.sum(s)>=cos) {
      kans[i]=true;
    }
  }
  for(int i=m-1;i>=0;i--){
    if(kans[i]){
      dfs(vec[i].second.first,vec[i].first);
    }
  }
  ll cnt=0;
  for(int i=0;i<m;i++) {
    if(!ans[i]) {
      cnt++;
      //cout<<i<<endl;
    }
  }
  cout<<cnt<<endl;
}
