#include <bits/stdc++.h>
using namespace std;
template <typename S, typename T>
ostream &operator<<(ostream &out, const pair<S, T> &p) {
  out << "(" << p.first << ", " << p.second << ")";
  return out;
}
template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  out << "[";
  for (int i = (int)(0); i < (int)(v.size()); i++) {
    if (i > 0) out << ", ";
    out << v[i];
  }
  out << "]";
  return out;
}
class UnionFind {
 public:
  int num_components;
  std::vector<int> parent;
  std::vector<long long> weight;
  std::vector<int> rank;

 public:
  UnionFind(int N, const vector<long long> weight)
      : num_components(N),
        parent(std::vector<int>(N)),
        weight(weight),
        rank(std::vector<int>(N, 0)) {
    for (int i = 0; i < N; i++) parent[i] = i;
  }
  int find(int x) {
    if (x == parent[x])
      return x;
    else
      return parent[x] = find(parent[x]);
  }
  int size(int x) { return weight[find(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;
    num_components--;
    if (rank[x] < rank[y]) {
      weight[y] += weight[x];
      parent[x] = y;
    } else {
      weight[x] += weight[y];
      parent[y] = x;
      if (rank[x] == rank[y]) rank[y]++;
    }
  }
  int count() { return num_components; }
};
int main(int argc, char *argv[]) {
  int N, M;
  cin >> N >> M;
  vector<long long> WN(N);
  for (int i = (int)(0); i < (int)(N); i++) cin >> WN[i];
  vector<pair<long long, pair<int, int>>> E(M);
  for (int i = (int)(0); i < (int)(M); i++) {
    int a, b, y;
    cin >> a >> b >> y;
    a--;
    b--;
    E[i] = make_pair(y, make_pair(a, b));
  }
  sort((E).begin(), (E).end());
  UnionFind uf(N, WN);
  vector<tuple<long long, long long, long long>> op;
  vector<int> valid(N - 1, true);
  vector<int> last_op(N, -1);
  vector<vector<int>> ch_ops(N - 1);
  for (int i = (int)(0); i < (int)(M); i++) {
    int w = E[i].first;
    cout << w << endl;
    int a = E[i].second.first;
    int b = E[i].second.second;
    if (uf.same(a, b)) {
      continue;
    }
    a = uf.find(a);
    b = uf.find(b);
    int c = op.size();
    if (last_op[a] != -1) {
      ch_ops[c].push_back(last_op[a]);
    }
    if (last_op[b] != -1) {
      ch_ops[c].push_back(last_op[b]);
    }
    op.push_back(make_tuple(uf.weight[a], uf.weight[b], i));
    uf.unite(a, b);
    last_op[uf.find(a)] = c;
  }
  assert(int(op.size()) == N - 1);
  queue<int> que;
  que.push(N - 2);
  while (!que.empty()) {
    int i = que.front();
    que.pop();
    long long s0 = get<0>(op[i]);
    long long s1 = get<1>(op[i]);
    long long w = E[get<2>(op[i])].first;
    if (w > s0 + s1) {
      valid[i] = false;
      for (int j : ch_ops[i]) {
        que.push(j);
      }
    }
  }
  UnionFind new_uf = UnionFind(N, WN);
  for (int i = (int)(0); i < (int)(N - 1); i++) {
    if (valid[i]) {
      int eid = get<2>(op[i]);
      int a = E[eid].second.first;
      int b = E[eid].second.second;
      new_uf.unite(a, b);
    }
  }
  long long res = 0;
  for (int i = (int)(0); i < (int)(M); i++) {
    int w = E[i].first;
    int a = new_uf.find(E[i].second.first);
    int b = new_uf.find(E[i].second.second);
    if (!new_uf.same(a, b) || w > new_uf.weight[a]) {
      res++;
    }
  }
  cout << res << endl;
  return 0;
}
