#include <bits/stdc++.h>
using namespace std;
pair<long long, int> p[100000];
long long sum[100000];
long long X[100000];
int A[100000], B[100000];
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
      long long tmp = sum[x];
      sum[x] += sum[y];
      sum[y] += tmp;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
};
int cnt;
vector<int> G[100000];
vector<bool> used[100000];
void dfs(int v) {
  for (int i = 0; i < G[v].size(); i++) {
    if (!used[v][i]) {
      cnt++;
      used[v][i] = true;
      dfs(G[v][i]);
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << setprecision(10) << fixed;
  int N, M;
  cin >> N >> M;
  for (int i = 0; i < N; i++) {
    cin >> X[i];
    sum[i] += X[i];
  }
  for (int i = 0; i < M; i++) {
    long long Y;
    cin >> A[i] >> B[i] >> Y;
    A[i]--;
    B[i]--;
    p[i] = pair<long long, int>(Y, i);
  }
  sort(p, p + N);
  UnionFind uf(N);
  for (int i = 0; i < M; i++) {
    int idx = p[i].second;
    long long w = p[i].first;
    uf.unionSet(A[idx], B[idx]);
    G[A[idx]].push_back(B[idx]);
    G[B[idx]].push_back(A[idx]);
    used[A[idx]].push_back(false);
    used[B[idx]].push_back(false);
    if (sum[uf.root(A[idx])] > w) {
      dfs(A[idx]);
    }
  }
  cout << M - cnt / 2 << endl;
}
