#include <bits/stdc++.h>
using namespace std;
using T = tuple<int, int, int>;
struct UnionFind {
  vector<int> par, sz;
  vector<long long> sum;
  UnionFind() {}
  UnionFind(int n, vector<long long> x) : par(n), sz(n, 1), sum(x) {
    iota(par.begin(), par.end(), 0);
  }
  int find(int x) {
    if (x == par[x]) return x;
    return find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return;
    if (sz[x] < sz[y]) swap(x, y);
    sz[x] += sz[y];
    sum[x] += sum[y];
    par[y] = x;
  }
  void split(int x, int y) {
    sz[x] -= sz[y];
    sum[x] -= sum[y];
    par[y] = y;
  }
};
struct edge {
  int u, v, w;
  bool operator<(const edge &e) const { return w < e.w; }
};
int main() {
  int n, m;
  cin >> n >> m;
  vector<long long> x(n);
  for (int i = 0; i < n; i++) cin >> x[i];
  UnionFind uf(n, x);
  vector<edge> es(m);
  for (int i = 0; i < m; i++) {
    int u, v, w;
    cin >> u >> v >> w;
    es[i] = {u - 1, v - 1, w};
  }
  sort(es.begin(), es.end());
  vector<T> h;
  for (auto e : es) {
    int u = uf.find(e.u);
    int v = uf.find(e.v);
    if (u == v) continue;
    if (uf.sz[u] < uf.sz[v]) swap(u, v);
    uf.unite(u, v);
    h.push_back({u, v, e.w});
  }
  reverse(h.begin(), h.end());
  for (auto e : h) {
    int u, v, w;
    tie(u, v, w) = e;
    int p = uf.find(u);
    if (uf.sum[p] >= w) continue;
    uf.split(u, v);
  }
  int ans = 0;
  for (auto e : es) {
    int p = uf.find(e.u);
    if (uf.sum[p] >= e.w) ans++;
  }
  cout << m - ans << endl;
}
