#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> data;
  UnionFind(int n) { data.resize(n + 1, -1); }
  int find(int x) {
    if (data[x] < 0)
      return x;
    else
      return data[x] = find(data[x]);
  }
  int size(int x) { return -data[find(x)]; }
  bool unite(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return false;
    if (data[x] > data[y]) swap(x, y);
    data[x] += data[y];
    data[y] = x;
    return true;
  }
  bool same(int x, int y) {
    x = find(x);
    y = find(y);
    return x == y;
  }
};
int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  int n, m;
  cin >> n >> m;
  vector<long long> x(n + 1, 0);
  for (int i = 0; i < n; i++) cin >> x[i + 1];
  using edge = pair<long long, array<int, 2>>;
  vector<edge> v;
  vector<array<int, 3>> p(m);
  vector<array<long long, 2>> px(m);
  for (int i = 0; i < m; i++) {
    int a, b;
    long long y;
    cin >> a >> b >> y;
    v.push_back({y, {a, b}});
  }
  sort(v.begin(), v.end());
  UnionFind uf(n);
  for (int i = 0; i < m; i++) {
    int a = v[i].second[0], b = v[i].second[1];
    p[i][0] = uf.find(a), p[i][1] = uf.find(b);
    px[i][0] = x[p[i][0]], px[i][1] = x[p[i][1]];
    if (!uf.same(a, b)) {
      uf.unite(a, b);
      x[p[i][0]] += x[p[i][1]];
      x[p[i][1]] = x[p[i][0]];
    }
    p[i][2] = uf.find(a);
  }
  int ans = 0;
  for (int i = m - 1; i >= 0; i--) {
    if (x[p[i][2]] < v[i].first) {
      ans++;
      x[p[i][0]] = px[i][0];
      x[p[i][1]] = px[i][1];
    }
  }
  cout << ans << "\n";
  return 0;
}
