#include <bits/stdc++.h>
using namespace std;
using vecint = vector<int>;
using ll = int64_t;
using Edge = tuple<int, int, ll>;
using Edges = vector<Edge>;
struct UnionFind {
  vector<int> parent;
  vector<ll> weight;
  vector<ll> ok;
  UnionFind(int n) : parent(n, -1), weight(n, 0), ok(n, 0) {}
  int root(int x) { return parent[x] < 0 ? 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;
    weight[x] += weight[y];
    return true;
  }
  ll ok_max(int x) {
    return parent[x] < 0 ? ok[x] : max(ok[x], ok_max(parent[x]));
  }
};
int main() {
  int n, m;
  cin >> n >> m;
  UnionFind uf(n);
  for (int i = (0); i < (n); ++i) cin >> uf.weight[i];
  Edges ve;
  for (int i = (0); i < (m); ++i) {
    int a, b, y;
    cin >> a >> b >> y;
    --a;
    --b;
    ve.emplace_back(y, a, b);
  }
  sort(begin(ve), end(ve));
  for (int i = (0); i < (m); ++i) {
    int a, b, y;
    tie(y, a, b) = ve[i];
    uf.merge(a, b);
    if (y <= uf.weight[uf.root(a)]) {
      uf.ok[uf.root(a)] = uf.weight[uf.root(a)];
    }
  }
  int cnt = 0;
  for (int i = (0); i < (m); ++i) {
    int a, b, y;
    tie(y, a, b) = ve[i];
    if (min(uf.ok_max(a), uf.ok_max(b)) < y) {
      ++cnt;
    }
  }
  cout << cnt << endl;
  return 0;
}
