#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  int size;
  vector<int> parent;
  UnionFind() {}
  UnionFind(int size) {
    this->size = size;
    parent.resize(size + 1);
    init();
  }
  void init() {
    for (int i = 0; i <= size; i++) parent[i] = i;
  }
  int root(int i) {
    if (parent[i] == i) return i;
    return parent[i] = root(parent[i]);
  }
  bool same(int i, int j) { return root(i) == root(j); }
  void unite(int i, int j) {
    int root_i = root(i), root_j = root(j);
    if (root_i == root_j) return;
    parent[root_i] = root_j;
  }
};
struct node {
  long long w, sum, sz, left, right, id;
  node() { w = left = right = -1; };
};
long long n, m;
long long x[100005];
vector<pair<long long, pair<long long, long long> > > e, rem;
UnionFind uf(100005), uf2(100005);
vector<long long> vec;
long long s[100005];
long long rt[100005];
vector<node> tree;
void dfs2(long long v) {
  if (tree[v].w == -1) return;
  vec.push_back(tree[v].id);
  dfs2(tree[v].left), dfs2(tree[v].right);
}
long long dfs(long long v) {
  if (tree[v].w == -1) return 0;
  if (tree[v].sum >= tree[v].w) {
    dfs2(v);
    return tree[v].sz - 1;
  }
  return dfs(tree[v].left) + dfs(tree[v].right);
}
int main(void) {
  cin >> n >> m;
  for (int i = 1; i <= n; i++) cin >> x[i];
  long long a, b, y;
  for (int i = 1; i <= m; i++) {
    cin >> a >> b >> y;
    e.push_back(make_pair(y, make_pair(a, b)));
  }
  sort(e.begin(), e.end());
  for (int i = 1; i <= n; i++) {
    tree.push_back(node());
    tree.back().sz = 1;
    tree.back().sum = x[i];
  }
  for (int i = 1; i <= n; i++) rt[i] = i - 1;
  long long ans = 0;
  for (int i = 0; i < e.size(); i++) {
    int u = e[i].second.first, v = e[i].second.second, w = e[i].first;
    if (uf.same(u, v)) {
      rem.push_back(e[i]);
      continue;
    }
    tree.push_back(node());
    tree.back().id = i;
    tree.back().w = w;
    tree.back().left = rt[uf.root(u)];
    tree.back().right = rt[uf.root(v)];
    tree.back().sum = tree[tree.back().left].sum + tree[tree.back().right].sum;
    tree.back().sz = tree[tree.back().left].sz + tree[tree.back().right].sz;
    uf.unite(u, v);
    rt[uf.root(u)] = tree.size() - 1;
  }
  set<int> S;
  for (int i = 1; i <= n; i++) S.insert(uf.root(i));
  for (auto it = S.begin(); it != S.end(); it++)
    ans += (tree[rt[*it]].sz - 1) - dfs(rt[*it]);
  for (int i = 1; i <= n; i++) s[i] = x[i];
  for (int i = 0; i < vec.size(); i++) {
    pair<long long, pair<long long, long long> > edge = e[vec[i]];
    int u = e[i].second.first, v = e[i].second.second, w = e[i].first;
    s[uf2.root(v)] += s[uf2.root(u)];
    uf2.unite(u, v);
  }
  for (int i = 0; i < rem.size(); i++) {
    int u = rem[i].second.first, v = rem[i].second.second, w = rem[i].first;
    if (!uf2.same(u, v) || s[uf2.root(u)] < w) ans++;
  }
  cout << ans << endl;
  return 0;
}
