#include <bits/stdc++.h>
using namespace std;
void _main();
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  _main();
}
const int inf = INT_MAX / 2;
const long long infl = 1LL << 60;
template <class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return 1;
  }
  return 0;
}
struct UnionFind {
  vector<int> par;
  UnionFind() {}
  UnionFind(int NV) { init(NV); }
  void init(int NV) {
    par.clear();
    for (int i = 0; i < NV; i++) par.push_back(i);
  }
  void reset() {
    for (int i = 0; i < par.size(); i++) par[i] = i;
  }
  int operator[](int x) {
    return par[x] == x ? x : par[x] = operator[](par[x]);
  }
  void operator()(int x, int y) {
    x = operator[](x);
    y = operator[](y);
    if (x != y) par[x] = y;
  }
};
int N, M, X[101010];
int A[101010], B[101010], Y[101010];
int ng[101010];
long long sm[101010];
int ma[101010];
int memo_ng[101010], memo_ng_a[101010], memo_ng_b[101010];
vector<pair<int, int>> E[101010];
int ok[101010];
void dfs(int cu, int lim) {
  ok[cu] = 1;
  for (auto &p : E[cu])
    if (p.second <= lim) {
      int to = p.first;
      if (!ok[to]) dfs(to, lim);
    }
}
void _main() {
  cin >> N >> M;
  for (int i = 0; i < N; i++) cin >> X[i];
  for (int i = 0; i < M; i++) {
    cin >> A[i] >> B[i] >> Y[i];
    A[i]--;
    B[i]--;
    E[A[i]].push_back({B[i], Y[i]});
    E[B[i]].push_back({A[i], Y[i]});
  }
  vector<pair<int, int>> edges;
  for (int i = 0; i < M; i++) edges.push_back({Y[i], -i});
  sort((edges).begin(), (edges).end());
  UnionFind uf(N);
  for (int i = 0; i < N; i++) {
    ng[i] = 0;
    sm[i] = X[i];
    ma[i] = -1;
  }
  map<int, map<int, vector<int>>> query;
  int cnt = 0;
  for (auto &p : edges) {
    int id = -p.second;
    int a = A[id];
    int b = B[id];
    int c = p.first;
    cnt++;
    memo_ng_a[id] = ng[uf[a]];
    memo_ng_b[id] = ng[uf[b]];
    if (uf[a] == uf[b]) {
      int u = uf[a];
      chmax(ma[u], p.first);
      if (sm[u] < ma[u]) ng[u] = 1;
      memo_ng[id] = ng[u];
    } else {
      int ua = uf[a];
      int ub = uf[b];
      long long sm2 = sm[ua] + sm[ub];
      int ma2 = c;
      chmax(ma2, ma[ua]);
      chmax(ma2, ma[ub]);
      int ng2 = 0;
      if (sm2 < ma2) ng2 = 1;
      uf(a, b);
      int u = uf[a];
      int u2 = ua + ub - u;
      sm[u] = sm2;
      ma[u] = ma2;
      ng[u] = ng2;
      memo_ng[id] = ng[u];
    }
    if (memo_ng[id]) query[-c][uf[a]].push_back(id);
  }
  int ans = 0;
  for (auto &p : query) {
    int cs = -p.first;
    for (auto &p2 : p.second) {
      int u = p2.first;
      auto &v = p2.second;
      int skip = 0;
      if (ok[u]) continue;
      for (auto &i : v)
        if (memo_ng[i] == 0) skip = 1;
      if (skip)
        dfs(u, cs);
      else {
        ans += v.size();
        for (auto &i : v) {
          int a = A[i];
          int b = B[i];
          if (memo_ng_a[i] == 0) dfs(a, cs - 1);
          if (memo_ng_b[i] == 0) dfs(b, cs - 1);
        }
      }
    }
  }
  cout << ans << endl;
}
