#include <bits/stdc++.h>
using namespace std;
const int N = 1000050;
long long X[N];
long long p[N], sz[N];
vector<long long> E[N];
long long was[N];
long long Find(long long x) { return p[x] == x ? x : Find(p[x]); }
void Union(long long x, long long y) {
  x = Find(x);
  y = Find(y);
  if (sz[x] < sz[y]) swap(x, y);
  X[x] += X[y];
  p[y] = x;
  sz[x] += sz[y];
  E[x].push_back(y);
}
void Mark(long long u) {
  if (was[u]) return;
  was[u] = 1;
  for (long long v : E[u])
    if (!was[v]) Mark(v);
}
long long sol, bsol, n, m;
long long U[N], V[N], W[N];
long long XX[N];
void input() {
  scanf("%lld %lld", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%lld", &XX[i]);
  for (int i = 1; i <= m; i++) scanf("%lld %lld %lld", &U[i], &V[i], &W[i]);
}
void output() { printf("%lld\n", sol); }
void Solve() {
  long long u, v, w;
  for (int i = 1; i <= n; i++)
    sz[i] = 1, p[i] = i, X[i] = XX[i], E[i].clear(), was[i] = 0;
  vector<pair<long long, pair<long long, long long>>> edges;
  vector<pair<long long, long long>> ws;
  for (int i = 1; i <= m; i++)
    u = U[i], v = V[i], w = W[i],
    edges.push_back(make_pair(w, make_pair(u, v)));
  sort(edges.begin(), edges.end());
  for (int i = 0; i < edges.size(); i++) {
    u = edges[i].second.first;
    v = edges[i].second.second;
    if (Find(u) != Find(v)) Union(u, v);
    ws.push_back(make_pair(X[Find(u)], Find(u)));
  }
  int ans = 0;
  for (int i = m - 1; i >= 0; i--) {
    u = edges[i].second.first;
    v = edges[i].second.second;
    w = edges[i].first;
    if (w > ws[i].first && !was[u]) {
      ans++;
    } else {
      Mark(ws[i].second);
    }
  }
  sol = ans;
}
void Run() {
  input();
  Solve();
  output();
}
void BruteForce() {
  bsol = m;
  for (int mask = 0; mask < 1 << m; mask++) {
    for (int i = 1; i <= n; i++) p[i] = i, sz[i] = 1, X[i] = XX[i];
    for (int i = 1; i <= m; i++)
      if ((mask >> (i - 1)) & 1) {
        if (Find(U[i]) != Find(V[i])) Union(U[i], V[i]);
      }
    bool ok = 1;
    int cnt = 0;
    for (int i = 1; i <= m; i++)
      if ((mask >> (i - 1)) & 1) {
        if (W[i] > X[Find(U[i])]) ok = 0;
        cnt++;
      }
    if (ok) bsol = min(bsol, m - cnt);
  }
}
void MakeTestCase() {
  n = rand() % 10 + 1;
  m = rand() % 10 + n - 1;
  for (int i = 1; i <= n; i++) XX[i] = rand() % 100 + 1;
  m = min(m, n * (n - 1) / 2);
  set<pair<int, int>> st;
  for (int i = 1; i <= m; i++) {
    U[i] = rand() % n + 1, V[i] = rand() % n + 1;
    if (U[i] > V[i]) swap(U[i], V[i]);
    W[i] = rand() % 100 + 1;
    while (U[i] == V[i] || st.count(make_pair(U[i], V[i]))) {
      U[i] = rand() % n + 1, V[i] = rand() % n + 1;
      if (U[i] > V[i]) swap(U[i], V[i]);
    }
  }
}
bool Compare() { return sol == bsol; }
void Print() {
  printf("%i %i\n", n, m);
  for (int i = 1; i <= n; i++) printf("%i ", XX[i]);
  printf("\n");
  for (int i = 1; i <= m; i++) printf("%i %i %i\n", U[i], V[i], W[i]);
  printf("Solve: %i\n", sol);
  printf("Brute: %i\n", bsol);
}
double GetTime() { return (long double)clock() / CLOCKS_PER_SEC; }
double s_time, e_time, d_time;
void Start() { s_time = GetTime(); }
void Stop() {
  e_time = GetTime();
  d_time = e_time - s_time;
}
void Test() {
  srand(time(0));
  cout << fixed << setprecision(4);
  int work = 100000;
  double max_time = 0;
  bool speed_only = 0;
  for (int i = 1; i <= work; i++) {
    MakeTestCase();
    if (!speed_only) BruteForce();
    Start();
    Solve();
    Stop();
    if (!speed_only && !Compare()) {
      Print();
      return;
    }
    max_time = max(max_time, d_time);
    cout << i << ":OK, max time so far=" << max_time << "\n";
  }
  cout << ":D\n";
}
int main() {
  bool test = 0;
  if (test)
    Test();
  else
    Run();
  return 0;
}
