#include <bits/stdc++.h>
constexpr int dx[8] = {1, 1, 0, -1, -1, -1, 0, 1};
constexpr int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
using namespace std;
using ll = long long;
using vi = vector<int>;
using vl = vector<ll>;
using vvi = vector<vi>;
using vvl = vector<vl>;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <class T>
bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
struct UnionFind {
  std::vector<int> par;
  std::vector<int> sizes;
  vl val;
  UnionFind(vl v) {
    int n = v.size();
    val = v;
    par.resize(n);
    sizes.resize(n);
    for (int i = 0; i < n; ++i) {
      par[i] = i;
      sizes[i] = 1;
    }
  }
  int root(int a) { return par[a] == a ? a : par[a] = root(par[a]); }
  bool same(int x, int y) { return root(x) == root(y); }
  void unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return;
    if (sizes[x] < sizes[y]) std::swap(x, y);
    par[y] = x;
    sizes[x] += sizes[y];
    val[x] += val[y];
  }
  int size(int x) { return sizes[root(x)]; }
};
struct Edge {
  ll from, to, cost, index;
  bool operator<(const Edge &rhs) const { return this->cost < rhs.cost; }
};
using Graph = vector<vector<Edge>>;
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vl v(n);
  for (ll i = 0; i < ll(n); ++i) cin >> v[i];
  vector<Edge> e(m);
  Graph g(n);
  for (ll i = 0; i < ll(m); ++i) {
    int a, b, c;
    cin >> a >> b >> c;
    a--;
    b--;
    e[i] = Edge{a, b, c, i};
    g[a].push_back(Edge{a, b, c, i});
    g[b].push_back(Edge{b, a, c, i});
  }
  UnionFind uf(v);
  sort((e).begin(), (e).end());
  vi b(m, 0);
  for (ll i = 0; i < ll(m); ++i) {
    uf.unite(e[i].from, e[i].to);
    if (uf.val[uf.root(e[i].from)] >= e[i].cost) b[i] = 1;
  }
  vi visited(n, 0);
  int ans = 0;
  for (ll i = ll(m) - 1; i >= 0; --i) {
    if (b[i] == 0) {
      ans++;
      continue;
    }
    queue<int> q;
    q.push(e[i].from);
    while (!q.empty()) {
      int p = q.front();
      q.pop();
      for (ll i = 0; i < ll(g[p].size()); ++i) {
        if (e[i].cost < g[p][i].cost) continue;
        b[g[p][i].index] = 1;
        if (visited[g[p][i].to] == 0) {
          q.push(g[p][i].to);
          visited[g[p][i].to] = 1;
        }
      }
    }
  }
  cout << ans << endl;
}
