#include <bits/stdc++.h>
using namespace std;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
double pi = 3.141592653589793;
long long mod = 1000000007;
int intmax = 2147483647;
int intmin = -2147483648;
long long llmax = 9223372036854775807;
long long llmin = -9223372036854775807;
int iinf = intmax / 8;
long long inf = llmax / 8;
double eps = 1e-12;
struct persistentUnionFind {
  vector<int> parent;
  vector<int> sz;
  vector<int> height;
  vector<vector<pair<long long, long long>>> S;
  vector<long long> time;
  vector<long long> X;
  vector<long long> wt;
  vector<vector<pair<long long, long long>>> W;
  persistentUnionFind(int N, vector<long long> X)
      : parent(N, 0),
        sz(N, 1),
        height(N, 1),
        S(N, vector<pair<long long, long long>>(
                 1, pair<long long, long long>(0, 1))),
        time(N, inf),
        X(X),
        wt(N),
        W(N, vector<pair<long long, long long>>()) {
    for (int i = 0; i < N; i++) {
      parent[i] = i;
      wt[i] = X[i];
      W[i].push_back(pair<long long, long long>(0, X[i]));
    }
  }
  int root(int x, long long t) {
    while (time[x] <= t) {
      x = parent[x];
    }
    return x;
  }
  bool unite(int x, int y, long long t) {
    int px = root(x, t);
    int py = root(y, t);
    if (px == py) {
      return false;
    }
    if (height[py] < height[px]) {
      parent[py] = px;
      time[py] = t;
      sz[px] += sz[py];
      S[px].push_back(pair<long long, long long>(t, sz[px]));
      wt[px] += wt[py];
      W[px].push_back(pair<long long, long long>(t, wt[px]));
    } else {
      parent[px] = py;
      time[px] = t;
      sz[py] += sz[px];
      S[py].push_back(pair<long long, long long>(t, sz[py]));
      wt[py] += wt[px];
      W[py].push_back(pair<long long, long long>(t, wt[py]));
      height[py] = max(height[py], height[px] + 1);
    }
    return true;
  }
  long long size(int x, long long t) {
    int y = root(x, t);
    int idx = lower_bound(S[y].begin(), S[y].end(),
                          pair<long long, long long>(t, inf)) -
              S[y].begin() - 1;
    return S[y][idx].second;
  }
  long long weight(int x, long long t) {
    int y = root(x, t);
    int idx = lower_bound(W[y].begin(), W[y].end(),
                          pair<long long, long long>(t, inf)) -
              W[y].begin() - 1;
    return W[y][idx].second;
  }
};
tuple<long long, long long, long long> dat[100010];
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  long long N, M;
  cin >> N >> M;
  vector<long long> X(N);
  for (long long i = (long long)0; i < (long long)N; i++) {
    cin >> X[i];
  }
  for (long long i = (long long)0; i < (long long)M; i++) {
    long long a, b, y;
    cin >> a >> b >> y;
    dat[i] = tuple<long long, long long, long long>(y, a - 1, b - 1);
  }
  sort(dat, dat + M);
  persistentUnionFind u(N, X);
  for (long long i = (long long)0; i < (long long)M; i++) {
    tuple<long long, long long, long long> t = dat[i];
    u.unite(get<1>(t), get<2>(t), i + 1);
  }
  long long ans = 0;
  long long now = M;
  for (long long i = (long long)M - 1; i > (long long)-1; i--) {
    tuple<long long, long long, long long> t = dat[i];
    if (u.weight(get<1>(t), now) < get<0>(t)) {
      now = i;
      ans++;
    }
  }
  cout << ans << endl;
}
