#include <bits/stdc++.h>
using namespace std;
const long long MOD = 1e9 + 7;
const long long INF = 1e18;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
const int MAX_N = 100010;
vector<tuple<int, int, int> > edge(100010);
vector<tuple<int, int, int> > g;
vector<int> indeg(100010);
int n, m;
int par[MAX_N];
int ranks[MAX_N];
int size_UF;
int ans;
void init(int n) {
  size_UF = n;
  for (int i = 0; i < n; i++) {
    par[i] = i;
    ranks[i] = 0;
  }
}
int find(int x) {
  if (par[x] == x) {
    return x;
  } else {
    return par[x] = find(par[x]);
  }
}
bool same(int x, int y) { return find(x) == find(y); }
void unite(int x, int y) {
  x = find(x);
  y = find(y);
  if (x == y) return;
  size_UF--;
  if (ranks[x] < ranks[y]) {
    par[x] = y;
  } else {
    par[y] = x;
  }
  if (ranks[x] == ranks[y]) {
    ranks[x]++;
  }
}
void kruskal(int n) {
  init(n);
  int res = 0;
  for (int i = 0; i < m; i++) {
    int cost, cv, nv;
    tie(cost, cv, nv) = edge[i];
    if (!same(cv, nv)) {
      unite(cv, nv);
      g.emplace_back(tuple<int, int, int>(cost, cv, nv));
      res += cost;
    }
  }
}
int main() {
  cin >> n >> m;
  ans = n - 1;
  vector<int> x(n);
  long long xsum = 0;
  for (int i = 0; i < n; i++) {
    cin >> x[i];
    xsum += x[i];
  }
  for (int i = 0; i < m; i++) {
    int a, b, y;
    cin >> a >> b >> y;
    a--, b--;
    edge[i] = tuple<int, int, int>(y, a, b);
  }
  sort(edge.begin(), edge.begin() + m);
  kruskal(n);
  sort(g.begin(), g.end());
  vector<int> e(100010, 0);
  for (int i = 0; i < g.size(); i++) {
    int cost, cv, nv;
    tie(cost, cv, nv) = g[i];
    e.emplace_back(cost);
    indeg[cv]++;
    indeg[nv]++;
  }
  for (int i = 0; i < g.size(); i++) {
    int cost, cv, nv;
    tie(cost, cv, nv) = g[i];
    indeg[cv]--;
    if (indeg[cv] == 0) xsum -= x[cv];
    indeg[nv]--;
    if (indeg[nv] == 0) xsum -= x[nv];
    ans--;
    if (e[i + 1] <= xsum) {
      cout << ans << endl;
      return 0;
    }
  }
}
