#include <bits/stdc++.h>
using namespace std;
long long ans = 0;
struct UnionFind {
  vector<long long> data;
  UnionFind(long long size) : data(size, -1) {}
  bool unionSet(long long x, long long 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(long long x, long long y) { return root(x) == root(y); }
  long long root(long long x) {
    return data[x] < 0 ? x : data[x] = root(data[x]);
  }
  long long size(long long x) { return -data[root(x)]; }
};
struct edge {
  long long to, from;
  long long cost;
  bool ok = 0;
  edge() {}
  edge(long long from, long long to, long long cost)
      : from(from), to(to), cost(cost){};
};
bool cmp(const edge &a, const edge &b) { return a.cost < b.cost; }
int main() {
  long long n, m;
  cin >> n >> m;
  vector<long long> x(n);
  for (long long i = 0; i < (long long)(n); i++) {
    cin >> x[i];
  }
  vector<edge> g;
  for (long long i = 0; i < (long long)(m); i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    g.emplace_back(a - 1, b - 1, c);
  }
  sort(g.begin(), g.end(), cmp);
  UnionFind arr(n);
  vector<long long> sum = x;
  vector<bool> ch(n);
  for (long long i = 0; i < (long long)(m); i++) {
    if (arr.root(g[i].from) == arr.root(g[i].to)) {
      if (sum[arr.root(g[i].from)] >= g[i].cost) g[i].ok = 1;
    } else {
      long long sum1 = sum[arr.root(g[i].from)];
      long long sum2 = sum[arr.root(g[i].to)];
      arr.unionSet(g[i].from, g[i].to);
      sum[arr.root(g[i].from)] = sum1 + sum2;
      if (sum[arr.root(g[i].from)] >= g[i].cost) g[i].ok = 1;
    }
  }
  for (long long i = 0; i < (long long)(m); i++) {
    if (g[m - i - 1].ok) {
      ch[arr.root(g[m - i - 1].from)] = 1;
      ans++;
    } else if (ch[arr.root(g[m - i - 1].from)])
      ans++;
  }
  cout << m - ans << endl;
  return 0;
}
