#include <bits/stdc++.h>
#include <boost/range/algorithm.hpp>
#include <boost/range/numeric.hpp>
#include <boost/range/irange.hpp>
#include <boost/range/adaptor/indexed.hpp>

using namespace std;
using namespace boost::adaptors;
using namespace std::string_literals;
using ll = int64_t;
using vecint = vector<int>;
using vecll = vector<ll>;
using boost::irange;

struct UnionFind {
  vector<int> parent;
  vector<ll> sum;
  UnionFind (int n) : parent(n, -1), sum(n, 0) {}
  int root(int x) { return parent[x] < 0 ? x : parent[x] = root(parent[x]); }
  bool merge(int x, int y) {
    x = root(x); y = root(y);
    if (x == y) return false;
    if (parent[y] < parent[x]) swap(x, y);
    if (parent[x] == parent[y]) --parent[x];
    parent[y] = x;
    sum[x] += sum[y];
    return true;
  }
};

void dfs(vector<vector<tuple<int,ll,int>>>& g, vector<bool>& save, int v, ll y) {
  for (auto& e : g[v]) {
    int to,i;
    ll w;
    tie(to, w, i) = e;
    if (w > y) continue;
    if (save[i]) continue;
    save[i] = true;
    dfs(g, save, to, y);
  }
}

int main()
{
  int n,m;
  cin>>n>>m;
  vecll x(n);
  for(auto& e:x) cin>>e;
  vector<tuple<ll,int,int,int>> ve;
  vector<vector<tuple<int,ll,int>>> g(n);
  for(int i:irange(0,m)) {
    int a,b;
    ll y;
    cin>>a>>b>>y;
    --a;--b;
    g[a].emplace_back(b, y, i);
    g[b].emplace_back(a, y, i);
    ve.emplace_back(y,a,b,i);
  }
  boost::sort(ve);
  vector<bool> candi(m);
  UnionFind uf(n);
  uf.sum = x;
  for(auto p:index(ve)) {
    ll y;
    int a,b,i;
    tie(y,a,b,i) = p.value();
    uf.merge(a, b);
    if (uf.sum[uf.root(a)] >= y) {
      candi[p.index()] = true;
    }
  }
  vector<bool> save(m);
  for(int i:irange(0,m)) {
    int j=m-i-1;
    if (!candi[j]) continue;
    ll y;
    int a,b,k;
    tie(y,a,b,k) = ve[j];
    if (save[k]) continue;
    save[k] = true;
    dfs(g, save, a, y);
  }
  cout<<boost::count(save, false)<<endl;
  return 0;
}
