#include <bits/stdc++.h>
using namespace std;
template <class T>
bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}
using ll = long long;
using R = long double;
const R EPS = 1e-9L;
inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R sq(R x) { return sqrt(max(x, 0.0L)); }
const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
const pid_t pid = getpid();
const int limit = 100010;
int A[limit], B[limit], X[limit], Y[limit];
int sz = 1;
set<int> tree[limit];
int idx[limit];
ll total[limit];
vector<int> vs[2];
bool visited[limit];
void dfs(int i, int v) {
  if (visited[v]) return;
  visited[v] = true;
  vs[i].push_back(v);
  for (auto &v2 : tree[v]) {
    if (visited[v2]) continue;
    dfs(i, v2);
  }
}
void cut(int n, int a, int b) {
  if (tree[a].count(b) == 0) return;
  tree[a].erase(b);
  tree[b].erase(a);
  const int basis = idx[a];
  vs[0].clear();
  dfs(0, a);
  vs[1].clear();
  dfs(1, b);
  const int pos = (vs[0].size() > vs[1].size());
  for (auto &v : vs[pos]) {
    idx[v] = sz;
    total[basis] -= X[v];
    total[sz] += X[v];
  }
  for (int i = int(0); i < int(2); ++i) {
    for (auto &v : vs[i]) {
      visited[v] = false;
    }
  }
  sz++;
}
struct Union_find {
  Union_find(int n) { data.assign(n, -1); }
  int find(int x) { return (data[x] < 0) ? x : data[x] = find(data[x]); }
  void unite(int a, int b) {
    a = find(a), b = find(b);
    if (a != b) {
      if (data[a] < data[b]) swap(a, b);
      data[a] += data[b], data[b] = a;
    }
  }
  bool same(int a, int b) { return find(a) == find(b); }
  int size(int x) { return -data[x]; }
  vector<int> data;
};
int main(void) {
  int n, m;
  cin >> n >> m;
  for (int i = int(0); i < int(n); ++i) cin >> X[i];
  using edge = tuple<ll, int, int>;
  vector<edge> graph;
  for (int i = int(0); i < int(m); ++i) {
    cin >> A[i] >> B[i] >> Y[i];
    A[i]--, B[i]--;
    graph.push_back(edge(Y[i], A[i], B[i]));
  }
  Union_find uf(n);
  sort(begin(graph), end(graph));
  for (auto &e : graph) {
    int y, a, b;
    tie(y, a, b) = e;
    if (uf.same(a, b)) continue;
    tree[a].insert(b);
    tree[b].insert(a);
    uf.unite(a, b);
  }
  reverse(begin(graph), end(graph));
  for (int i = int(0); i < int(n); ++i) total[0] += X[i];
  int ans = 0;
  for (auto &e : graph) {
    int y, a, b;
    tie(y, a, b) = e;
    const ll cur = total[idx[a]];
    if (cur >= y) continue;
    ans++;
    cut(n, a, b);
  }
  cout << ans << endl;
  return 0;
}
