#include <bits/stdc++.h>
using namespace std;
template <class T>
void chmax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
void chmin(T &a, T b) {
  if (a > b) a = b;
}
constexpr long long INF = 1000000000000000000;
constexpr long long mod = 1000000007;
constexpr double eps = 1e-8;
const double pi = acos(-1);
long long dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};
long long Random(long long mi, long long ma) {
  random_device rnd;
  mt19937 mt(rnd());
  uniform_int_distribution<long long> engine(mi, ma);
  return engine(mt);
}
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
bool prime(long long a) {
  if (a == 1) return false;
  for (long long i = 2; i * i <= a; i++) {
    if (a % i == 0) return false;
  }
  return true;
}
long long modpow(long long a, long long b) {
  if (b == 0) return 1;
  if (b % 2) return modpow(a, b - 1) * a % mod;
  long long memo = modpow(a, b / 2);
  return memo * memo % mod;
}
vector<long long> kaijo, invkaijo;
void init_fact(long long n) {
  kaijo.resize(n + 1);
  invkaijo.resize(n + 1);
  kaijo[0] = 1;
  for (long long i = 1; i <= n; i++) {
    kaijo[i] = kaijo[i - 1] * i;
    kaijo[i] %= mod;
  }
  for (long long i = 0; i < n + 1; i++) invkaijo[i] = modpow(kaijo[i], mod - 2);
}
long long comb(long long a, long long b) {
  if (a < b) return 0;
  if (a < 0 || b < 0) return 0;
  return kaijo[a] * invkaijo[a - b] % mod * invkaijo[b] % mod;
}
long long inv(long long x) {
  x = modpow(x, mod - 2);
  return x;
}
long long x[100010];
struct UnionFind {
  vector<long long> par, siz;
  UnionFind(long long n) {
    par.resize(n);
    siz.resize(n);
    for (long long i = 0; i < n; i++) {
      par[i] = i;
      siz[i] = x[i];
    }
  }
  long long find(long long x) {
    if (par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  void unite(long long x, long long y) {
    x = find(x), y = find(y);
    if (x == y) return;
    if (siz[x] < siz[y]) swap(x, y);
    par[y] = x;
    siz[x] += siz[y];
  }
  bool same(long long x, long long y) { return find(x) == find(y); }
  long long size(long long x) { return siz[find(x)]; }
};
long long n, m, ans;
struct edge {
  long long u, v, cost;
  bool opt, used;
};
bool comp(const edge &e1, const edge &e2) { return e1.cost < e2.cost; }
long long Used[100010];
edge e[100010];
signed main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cin >> n >> m;
  for (long long i = 0; i < n; i++) cin >> x[i];
  for (long long i = 0; i < m; i++) {
    cin >> e[i].u >> e[i].v >> e[i].cost;
    e[i].u--, e[i].v--;
    e[i].opt = false;
    e[i].used = false;
  }
  sort(e, e + m, comp);
  UnionFind uf(n);
  for (long long i = 0; i < m; i++) {
    uf.unite(e[i].u, e[i].v);
    if (uf.size(e[i].u) >= e[i].cost) e[i].opt = true;
  }
  reverse(e, e + m);
  for (long long i = 0; i < m; i++) {
    if (!e[i].used && e[i].cost > Used[uf.find(e[i].u)]) {
      if (e[i].opt) {
        Used[uf.find(e[i].u)] = e[i].cost;
      } else
        ans++;
    }
    e[i].used = true;
  }
  cout << ans << endl;
  return 0;
}
