#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;
const ll MOD = 1e9 + 7;
const int inf = (1 << 30) - 1;
const ll INF = (1LL << 60) - 1;
const ld EPS = 1e-10;
template <typename T>
bool chmax(T &x, const T &y) {
  return (x < y) ? (x = y, true) : false;
};
template <typename T>
bool chmin(T &x, const T &y) {
  return (x > y) ? (x = y, true) : false;
};
struct edge {
  int to, id;
  ll cost;
};
const int MAX_V = 1e5;
vector<edge> es[MAX_V];
vector<bool> check(MAX_V, false), used(MAX_V, false);
ll X[MAX_V];
void dfs(int now, int MAX) {
  for (auto &e : es[now]) {
    if (e.cost > MAX || used[e.id]) continue;
    used[e.id] = true;
    dfs(e.to, MAX);
  }
}
struct Union_Find_Tree {
  vector<int> par, rank;
  vector<ll> num;
  Union_Find_Tree(int N) {
    par.assign(N, -1);
    rank.assign(N, 0);
    for (int i = 0; i < N; i++) num.push_back(X[i]);
  }
  int root(int x) {
    if (par[x] < 0 || par[x] == x) return x;
    return root(par[x]);
  }
  void unite(int x, int y) {
    x = root(x), y = root(y);
    if (x == y)
      return;
    else if (rank[x] < rank[y]) {
      par[x] = y, num[y] += num[x];
    } else {
      par[y] = x, num[x] += num[y];
      if (rank[x] == rank[y]) rank[x]++;
    }
  }
  int size(int x) { return num[root(x)]; }
  bool same(int x, int y) { return root(x) == root(y); }
  void clear() {
    fill(par.begin(), par.end(), -1);
    fill(rank.begin(), rank.end(), 0);
    fill(num.begin(), num.end(), 1);
  }
};
int main() {
  int N, M;
  cin >> N >> M;
  for (int i = 0; i < N; i++) cin >> X[i];
  int A[M], B[M];
  ll Y[M];
  pli p[M];
  for (int i = 0; i < M; i++) {
    cin >> A[i] >> B[i];
    A[i]--, B[i]--;
    cin >> Y[i];
    es[A[i]].emplace_back((edge){B[i], i, Y[i]});
    p[i] = pli(Y[i], i);
  }
  sort(p, p + M);
  Union_Find_Tree uft(N);
  for (int i = 0; i < M; i++) {
    int j = p[i].second;
    uft.unite(A[j], B[j]);
    if (uft.size(A[j]) >= Y[j]) check[j] = true;
  }
  int rem = 0;
  for (int i = M - 1; i >= 0; i--) {
    int j = p[i].second;
    if (!check[j] && !used[j])
      continue;
    else {
      rem++;
      if (!used[j]) {
        dfs(A[j], Y[j]);
        dfs(B[j], Y[j]);
      }
    }
  }
  cout << M - rem << endl;
}
