#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmin(T &x, T y) {
  return x > y ? x = y, 1 : 0;
}
template <typename T>
inline bool chkmax(T &x, T y) {
  return x < y ? x = y, 1 : 0;
}
inline void read(int &qwq) {
  char ch = getchar();
  int f = 1;
  qwq = 0;
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') qwq = qwq * 10 + ch - '0', ch = getchar();
  qwq *= f;
}
int n, m, val[100050], fa[100050], ok[100050], good[100050], vis[100050], ans;
long long sum[100050];
struct node {
  int u, v, w;
  bool operator<(const node &x) const { return w < x.w; }
} E[100050];
vector<node> adj[100050];
int get(int u) { return u == fa[u] ? u : fa[u] = get(fa[u]); }
void merge(int u, int v) {
  u = get(u), v = get(v);
  if (u != v) fa[v] = u, sum[u] += sum[v];
}
void search(int u, int w) {
  vis[u] = 1;
  for (auto pa : adj[u])
    if (!vis[pa.v]) {
      if (pa.w <= w) ok[pa.u] = 1, search(pa.v, w);
    }
}
int main() {
  int u, v, w;
  read(n), read(m);
  for (register int i = 1; i <= n; ++i)
    read(val[i]), fa[i] = i, sum[i] = val[i];
  for (register int i = 1; i <= m; ++i)
    read(u), read(v), read(w), E[i] = node{u, v, w};
  sort(E + 1, E + m + 1);
  for (register int i = 1; i <= m; ++i) {
    merge(E[i].u, E[i].v);
    adj[E[i].u].push_back(node{i, E[i].v, E[i].w}),
        adj[E[i].v].push_back(node{i, E[i].u, E[i].w});
    if (sum[get(E[i].u)] >= E[i].w) good[i] = 1;
  }
  for (register int i = m; i >= 1; --i) {
    if (ok[i])
      ++ans;
    else if (good[i])
      ++ans, search(E[i].u, E[i].w);
  }
  cout << m - ans << endl;
  return 0;
}
