#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> data;
  vector<long long> sum;
  UnionFind(int s) : data(s, -1), sum(s, 0) {}
  int root(int x) {
    if (data[x] < 0) return x;
    return data[x] = root(data[x]);
  }
  bool set(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    data[x] += data[y];
    sum[x] += sum[y];
    data[y] = x;
    sum[y] = 0;
    return true;
  }
  bool check(int x, int y) { return root(x) == root(y); }
  int size(int x) { return -data[root(x)]; }
};
int main() {
  int n, m;
  int x[200010];
  vector<pair<int, pair<int, int> > > vec;
  scanf("%d%d", &n, &m);
  UnionFind uf(n);
  for (int i = 0; i < n; i++) {
    scanf("%d", x + i);
    uf.sum[i] = x[i];
  }
  for (int i = 0; i < m; i++) {
    int a, b, y;
    scanf("%d%d%d", &a, &b, &y);
    vec.push_back({y, {a - 1, b - 1}});
  }
  sort(vec.begin(), vec.end());
  int ans = 0;
  priority_queue<pair<int, pair<int, int> > > pq;
  for (int i = 0; i < m; i++) {
    int a = vec[i].second.first;
    int b = vec[i].second.second;
    int y = vec[i].first;
    uf.set(a, b);
    pq.push({-y, {a, b}});
    while (pq.size()) {
      int c = uf.root(pq.top().second.first);
      if (uf.sum[c] >= -pq.top().first)
        pq.pop();
      else
        break;
    }
    if (pq.size() == 0) ans = i + 1;
  }
  cout << m - ans << endl;
  return 0;
}
