#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using PII = pair<int, int>;
int inv(LL x, int m) {
  return x > m ? inv(x % m, m) : x > 1 ? inv(m % x, m) * (m - m / x) % m : x;
}
int mpow(LL a, LL k, int m) {
  int r(1);
  for (a %= m; k; k >>= 1, a = a * a % m)
    if (k & 1) r = r * a % m;
  return r;
}
struct PDSU {
  const int n;
  vector<array<int, 2>> D;
  vector<LL> V;
  vector<int> R;
  PDSU(const vector<LL> &SZ) : n(SZ.size()), D(n), V(SZ), R(1, 1) {
    for (int i = n - 1; i; i--) D[i] = {i << 1, i << 1 | 1};
    for (auto &d : D)
      for (int i : {0, 1})
        if (d[i] >= n) d[i] -= n;
  }
  int get_ver(int t) { return t < 0 ? t + (int)R.size() : t; }
  void new_ver(int t = -1) { R.push_back(R[get_ver(t)]); }
  void modify(int p, LL x, int t = -1) {
    int h = 30 - __builtin_clz(p += n), no = D.size(), tmp = no, o, i;
    assert(n <= p && p < n + n), D.resize((int)D.size() + h + 1);
    for (o = R[get_ver(t)]; h; ++no, --h)
      i = !!(1 << h & p), D[no] = D[o], D[no][i] = no + 1, o = D[o][i];
    D[no] = D[o], D[no][p & 1] = V.size(), V.push_back(x), R[get_ver(t)] = tmp;
  }
  LL query(int p, int t = -1) {
    int o = R[get_ver(t)];
    for (int h = 30 - __builtin_clz(p += n); h >= 0; h--)
      o = D[o][!!(1 << h & p)];
    return V[o];
  }
  int root(int x, int t = -1) {
    int p = query(x, t);
    return p < 0 ? x : root(p, t);
  }
  bool same(int x, int y, int t = -1) { return root(x, t) == root(y, t); }
  LL size(int x, int t = -1) { return -query(root(x, t), t); }
  bool unite(int x, int y, int t = -1) {
    x = root(x, t), y = root(y, t);
    if (x != y) {
      LL sx = size(x, t), sy = size(y, t);
      if (sx < sy) swap(x, y);
      modify(x, -sx - sy, t), modify(y, x, t);
    }
    return x != y;
  }
};
const int N = 1e5 + 5;
int n, m, X[N];
struct Edge {
  int u, v, w;
} E[N];
int main() {
  cin >> n >> m;
  for (int i = (1); i <= (n); ++i) scanf("%d", &X[i]), X[i] = -X[i];
  for (int i = (1); i <= (m); ++i) scanf("%d%d%d", &E[i].u, &E[i].v, &E[i].w);
  sort(E + 1, E + 1 + m, [](Edge a, Edge b) { return a.w < b.w; });
  PDSU uf(vector<LL>(X, X + 1 + n));
  for (int i = (1); i <= (m); ++i) {
    uf.new_ver();
    uf.unite(E[i].u, E[i].v);
  }
  int ans = 0, ver = m;
  for (int i = (m); i >= (1); --i) {
    if (uf.size(E[i].u, ver) < E[i].w) {
      ans++;
      ver = i - 1;
    }
  }
  cout << ans << endl;
}
