#include <bits/stdc++.h>
using namespace std;
const int maxn = 100 * 1000 + 218;
struct TEdge {
  int a;
  int b;
  int w;
  TEdge() {}
  TEdge(int a, int b, int w) : a(a), b(b), w(w) {}
  void Load() {
    cin >> a >> b >> w;
    a--;
    b--;
  }
  bool operator<(const TEdge& other) const { return w < other.w; }
};
int n, m;
long long x[maxn];
int parent[maxn];
int weight[maxn];
int GetRoot(int v) {
  if (v == parent[v]) return v;
  int w = GetRoot(parent[v]);
  parent[v] = w;
  return w;
}
int GetWeight(int v) {
  int root = GetRoot(v);
  return weight[root];
}
void Merge(int v1, int v2) {
  if (rand() % 2) {
    swap(v1, v2);
  }
  v1 = GetRoot(v1);
  v2 = GetRoot(v2);
  if (v1 == v2) return;
  parent[v2] = v1;
  weight[v1] += weight[v2];
}
bool visited[maxn];
void DFS(int v, int maxW, const vector<vector<pair<int, int>>>& g,
         const vector<TEdge>& e, vector<bool>& used) {
  if (visited[v]) return;
  visited[v] = true;
  for (auto p : g[v]) {
    int to = p.first;
    int id = p.second;
    int w = e[id].w;
    if (w > maxW) continue;
    used[id] = true;
    DFS(to, maxW, g, e, used);
  }
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < n; ++i) cin >> x[i];
  vector<TEdge> e(m);
  for (int i = 0; i < m; ++i) e[i].Load();
  sort(e.begin(), e.end());
  for (int i = 0; i < n; ++i) {
    parent[i] = i;
    weight[i] = x[i];
  }
  vector<bool> valid(m);
  for (int i = 0; i < m; ++i) {
    Merge(e[i].a, e[i].b);
    if (e[i].w <= GetWeight(e[i].a)) {
      valid[i] = true;
    }
  }
  vector<vector<pair<int, int>>> g(n);
  for (int i = 0; i < m; ++i) {
    g[e[i].a].push_back({e[i].b, i});
    g[e[i].b].push_back({e[i].a, i});
  }
  vector<bool> used(m);
  for (int i = m; i >= 0; --i) {
    if (!valid[i]) continue;
    DFS(e[i].a, e[i].w, g, e, used);
  }
  int result = 0;
  for (int i = 0; i < m; ++i)
    if (!used[i]) result++;
  cout << result << endl;
  return 0;
}
