#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int N = (int)1e5 + 10;
const long long inf = (long long)1e18;
vector<pair<long long, int> > T[N];
int vv[N];
int dv[N];
int par[N];
int fin(int x) {
  if (x == par[x]) return x;
  return par[x] = fin(par[x]);
}
void unite(int a, int b) {
  a = fin(a);
  b = fin(b);
  if (a == b) return;
  dv[b] += dv[a];
  par[a] = b;
}
struct Edge {
  int ai;
  int bi;
  int wei;
  bool operator<(const Edge &R) const { return wei < R.wei; }
};
bool vis[N];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  ;
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    cin >> vv[i];
    dv[i] = vv[i];
    par[i] = i;
    vis[i] = false;
  }
  vector<Edge> edg(m);
  vector<bool> cool(m);
  for (int i = 0; i < m; i++) {
    cin >> edg[i].ai >> edg[i].bi >> edg[i].wei;
  }
  sort(edg.begin(), edg.end());
  for (int i = 0; i < m; i++) {
    unite(edg[i].ai, edg[i].bi);
    if (dv[fin(edg[i].ai)] > edg[i].wei) {
      cool[i] = true;
    }
    T[edg[i].ai].push_back(make_pair(edg[i].bi, i));
    T[edg[i].bi].push_back(make_pair(edg[i].ai, i));
  }
  for (int i = m - 1; i >= 0; i--) {
    if (vis[edg[i].ai]) continue;
    if (!cool[i]) continue;
    queue<int> bf;
    bf.push(edg[i].ai);
    vis[edg[i].ai] = true;
    int node;
    while (!bf.empty()) {
      node = bf.front();
      bf.pop();
      for (auto x : T[node]) {
        if (vis[x.first]) continue;
        if (edg[x.second].wei > edg[i].wei) continue;
        vis[x.first] = true;
        cool[x.second] = true;
        bf.push(x.first);
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < m; i++) ans += !cool[i];
  cout << ans << "\n";
  return 0;
}
