#include <bits/stdc++.h>
using namespace std;
vector<long long int> x;
struct UnionFind {
  vector<int> parent;
  vector<int> size;
  vector<int> rank;
  vector<int> sum;
  UnionFind(int n) {
    parent.resize(n);
    size.resize(n);
    rank.resize(n);
    sum.resize(n);
    for (int i = 0; i < n; i++) {
      parent[i] = i;
      size[i] = 1;
      rank[i] = 0;
      sum[i] = x[i];
    }
  }
  int root(int x) {
    if (parent[x] == x) {
      return x;
    }
    parent[x] = root(parent[x]);
    return parent[x];
  }
  void merge(int x, int y) {
    int rx = root(x);
    int ry = root(y);
    if (rx != ry) {
      if (rank[rx] < rank[ry]) {
        parent[rx] = ry;
        size[ry] += size[rx];
        sum[ry] += sum[rx];
      } else if (rank[rx] == rank[ry]) {
        parent[rx] = ry;
        size[ry] += size[rx];
        sum[ry] += sum[rx];
        rank[ry] += 1;
      } else if (rank[rx] > rank[ry]) {
        parent[ry] = rx;
        size[rx] += size[ry];
        sum[rx] += sum[ry];
      }
    }
    return;
  }
  bool same(int x, int y) { return root(x) == root(y); }
  int nodes(int x) { return size[root(x)]; }
  int total(int x) { return sum[root(x)]; }
};
vector<vector<pair<pair<int, long long int>, int>>> graph;
vector<bool> flag;
vector<bool> visited;
void DFS(int a, long long int y) {
  for (auto adjacent : graph[a]) {
    int b = adjacent.first.first;
    if (visited[b] == true || adjacent.first.second > y) continue;
    flag[adjacent.second] = true;
    visited[b] = true;
    DFS(b, y);
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  x.resize(n);
  for (int i = 0; i < n; i++) {
    cin >> x[i];
  }
  graph.resize(n);
  vector<pair<pair<long long int, pair<int, int>>, int>> edge(m);
  for (int i = 0; i < m; i++) {
    int a, b;
    long long int y;
    cin >> a >> b >> y;
    a -= 1;
    b -= 1;
    graph[a].push_back({{b, y}, i});
    graph[b].push_back({{a, y}, i});
    edge[i] = {{y, {a, b}}, i};
  }
  sort(edge.begin(), edge.end());
  flag.assign(m, false);
  UnionFind uf(n);
  for (int i = 0; i < m; i++) {
    int a = edge[i].first.second.first;
    int b = edge[i].first.second.second;
    long long int y = edge[i].first.first;
    int id = edge[i].second;
    if (uf.same(a, b) == true) {
      if (uf.total(a) >= y) flag[id] = true;
    }
    if (uf.same(a, b) == false) {
      if (uf.total(a) + uf.total(b) >= y) flag[id] = true;
      uf.merge(a, b);
    }
  }
  reverse(edge.begin(), edge.end());
  int ans = 0;
  visited.assign(n, false);
  for (int i = 0; i < m; i++) {
    int id = edge[i].second;
    if (flag[id] == false) ans += 1;
    if (flag[id] == true) {
      int a = edge[i].first.second.first;
      long long int y = edge[i].first.first;
      if (visited[a] == false) {
        visited[a] = true;
        DFS(a, y);
      }
      visited[a] = true;
    }
  }
  cout << ans << endl;
  return 0;
}
