#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
template <class T>
bool chmax(T& a, const T& b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
bool chmin(T& a, const T& b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class S, class T>
ostream& operator<<(ostream& os, const pair<S, T> v) {
  os << "(" << v.first << ", " << v.second << ")";
  return os;
}
template <class T>
ostream& operator<<(ostream& os, const vector<T> v) {
  for (int i = 0; i < (int)v.size(); i++) {
    if (i > 0) {
      os << " ";
    }
    os << v[i];
  }
  return os;
}
template <class T>
ostream& operator<<(ostream& os, const vector<vector<T>> v) {
  for (int i = 0; i < (int)v.size(); i++) {
    if (i > 0) {
      os << endl;
    }
    os << v[i];
  }
  return os;
}
template <typename T>
void debug(vector<vector<T>>& v, long long h, long long w) {
  for (long long i = 0; i < h; i++) {
    cerr << v[i][0];
    for (long long j = 1; j < w; j++) cerr << " " << v[i][j];
    cerr << endl;
  }
};
void debug(vector<string>& v, long long h, long long w) {
  for (long long i = 0; i < h; i++) {
    for (long long j = 0; j < w; j++) cerr << v[i][j];
    cerr << endl;
  }
};
template <typename T>
void debug(vector<T>& v, long long n) {
  if (n != 0) cerr << v[0];
  for (long long i = 1; i < n; i++) cerr << " " << v[i];
  cerr << endl;
};
string num2bit(long long num, long long len) {
  string bit = "";
  for (long long i = 0; i < (long long)len; i++) {
    bit += char('0' + (num >> i & 1));
  }
  return bit;
}
struct edge {
  long long u, v, w;
};
struct UnionFindSize {
  vector<int> par;
  UnionFindSize(int n) : par(n, -1) {}
  void init(int n) { par.assign(n, -1); }
  int root(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = root(par[x]);
  }
  bool issame(int x, int y) { return root(x) == root(y); }
  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  int size(int x) { return -par[root(x)]; }
};
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  long long N, M;
  cin >> N >> M;
  vector<long long> X(N);
  for (long long i = 0; i < (long long)N; i++) cin >> X[i];
  vector<edge> E(M);
  for (long long i = 0; i < (long long)M; i++) {
    cin >> E[i].u >> E[i].v >> E[i].w;
    E[i].u--;
    E[i].v--;
  }
  sort(E.begin(), E.end(),
       [](const edge& x, const edge& y) { return x.w < y.w; });
  UnionFindSize uf(N);
  vector<long long> sum(N, 0), enu(N, 0), ema(N, 0), sude(N, 0);
  for (long long i = 0; i < (long long)N; i++) sum[i] = X[i];
  for (long long i = 0; i < (long long)M; i++) {
    edge e = E[i];
    long long ru = uf.root(e.u);
    long long rv = uf.root(e.v);
    if (uf.issame(e.u, e.v)) {
      if (e.w > ema[ru]) {
        continue;
      } else {
        enu[ru]++;
        chmax(ema[ru], e.w);
        sude[ru]++;
      }
    } else {
      uf.merge(e.u, e.v);
      long long rr = uf.root(e.u);
      sum[rr] = sum[ru] + sum[rv];
      enu[rr] = enu[ru] + enu[rv] + 1;
      ema[rr] = max(max(ema[ru], ema[rv]), e.w);
      if (ema[rr] > sum[rr]) {
        sude[rr] = sude[ru] + sude[rv];
        if (rr == ru) sude[rv] = 0;
        if (rr == rv) sude[ru] = 0;
      } else {
        sude[ru] = 0;
        sude[rv] = 0;
        sude[rr] = enu[rr];
      }
    }
  }
  long long res = M;
  for (long long i = 0; i < (long long)N; i++) res -= sude[i];
  cout << res << endl;
  return 0;
}
