#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  int *data;
  UnionFind(int size) {
    data = new int[size];
    for (int i = 0; i < size; i++) data[i] = -1;
  }
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
UnionFind uf(100000);
pair<int, pair<int, int> > ee[100000];
long long rs[100000];
int n, m;
vector<pair<int, int> > edge[100000];
int ncost[100000], ecost[100000];
int used[100000];
vector<pair<int, int> > cuse;
int usedp;
void dfs(int p, int c, int q) {
  if (used[p]) return;
  used[p] = 1;
  for (int i = 0; i < edge[p].size(); i++) {
    if (edge[p][i].first <= c && edge[p][i].second != q) {
      usedp++;
      dfs(edge[p][i].second, c, p);
    }
  }
}
void solve() {
  int i, j;
  string str;
  cin >> n >> m;
  for (i = 0; i < n; i++) {
    cin >> ncost[i];
    rs[i] = ncost[i];
  }
  for (i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b >> ee[i].first;
    a--;
    b--;
    ee[i].second = make_pair(a, b);
    edge[a].push_back(make_pair(ee[i].first, b));
    edge[b].push_back(make_pair(ee[i].first, a));
  }
  sort(ee, ee + m);
  long long ans = 0;
  for (i = 0; i < m; i++) {
    int a = ee[i].second.first;
    int b = ee[i].second.second;
    int ra = uf.root(a);
    int rb = uf.root(b);
    long long snc;
    if (uf.findSet(a, b)) {
      snc = rs[ra];
    } else {
      snc = rs[ra] + rs[rb];
      uf.unionSet(a, b);
      rs[uf.root(a)] = snc;
    }
    int r = uf.root(a);
    if (snc >= ee[i].first) {
      cuse.push_back(make_pair(snc, ee[i].second.first));
    }
  }
  sort(cuse.begin(), cuse.end());
  for (i = cuse.size() - 1; i >= 0; i--) {
    dfs(cuse[i].second, cuse[i].first, -1);
  }
  cout << m - usedp << endl;
}
int main() { solve(); }
