#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void maximize(T &a, T b) {
  a = max(a, b);
}
template <typename T>
inline void minimize(T &a, T b) {
  a = min(a, b);
}
template <typename T>
inline bool middle(T a, T b, T c) {
  return b <= a && a <= c;
}
template <class T>
inline bool MX(T &l, const T &r) {
  return l < r ? l = r, 1 : 0;
}
template <class T>
inline bool MN(T &l, const T &r) {
  return l > r ? l = r, 1 : 0;
}
inline void outputVI(vector<long long> x) {
  for (long long i = (0LL); i < (long long)((long long(x.size()))); i++) {
    cout << ((i) ? (" ") : ("")) << x[i];
  }
  cout << ("") << endl;
}
const long long SIZE1 = 3e5 + 1000;
const long long SIZE2 = 2010;
const long long SIZE3 = 430;
const long long SIZE = SIZE1;
const long long MAPSIZE = 40;
const long long p = 7 + 1e9;
const long long INF = 1LL << 60;
const long double EPS = 1e-7;
vector<long long> evals[SIZE];
long long maxim[SIZE];
long long anses = 0;
long long X[SIZE];
class UnionFind {
  vector<long long> unions, talls, sents, dists, sizes;
  long long size;

 public:
  UnionFind() {}
  UnionFind(long long size) : size(size) { init(); }
  void init() {
    unions = vector<long long>(size);
    talls = vector<long long>(size);
    sents = vector<long long>(size);
    dists = vector<long long>(size);
    sizes = vector<long long>(size);
    for (long long i = (0); i < (long long)(size); i++) {
      unions[i] = i;
      sents[i] = 0;
      sizes[i] = 0;
      talls[i] = 1;
    }
  }
  long long find(long long x, long long t = 0) {
    if (unions[x] == x || sents[x] > t) return x;
    return find(unions[x], t);
  }
  long long minisize(long long x) {
    if (x == unions[x]) return sizes[x];
    return minisize(find(x));
  }
  bool isFriend(long long a, long long b, long long t = 0) {
    return find(a, t) == find(b, t);
  }
  void unite(long long a, long long b, long long y, long long t = 0) {
    a = find(a, t);
    b = find(b, t);
    if (talls[a] < talls[b]) unite(b, a, t);
    if (isFriend(a, b, t)) {
      sizes[a] += 1;
      MX(maxim[a], y);
      assert(maxim[a] <= y);
      if (maxim[a] <= X[a]) {
        assert(sizes[a] == 1);
        anses += sizes[a];
        sizes[a] = 0;
      }
      return;
    } else {
      MX(maxim[a], maxim[b]);
      assert(maxim[a] <= y);
      MX(maxim[a], y);
      sizes[a] += sizes[b] + 1;
      sizes[b] = 0;
      X[a] += X[b];
      X[b] = 0;
      if (maxim[a] <= X[a]) {
        anses += sizes[a];
        sizes[a] = 0;
      }
      sents[b] = t;
      talls[a] = max(talls[a], talls[b] + 1);
      unions[b] = a;
      dists[b] = 1;
    }
  }
};
long long N, M, K, L, Q, D, H, W, R;
vector<long long> edges[SIZE];
long long vals[SIZE], answer = 0LL;
long long maps[SIZE2][SIZE2];
long long solve() {
  cin >> N >> M;
  for (long long i = (1); i <= (long long)(N); i++) cin >> X[i];
  vector<pair<long long, pair<long long, long long> > > v;
  for (long long i = (0LL); i < (long long)(M); i++) {
    long long a, b, y;
    cin >> a >> b >> y;
    v.emplace_back(y, pair<long long, long long>(a, b));
  }
  sort(v.begin(), v.end());
  UnionFind uf = UnionFind(N + 1);
  for (long long i = (0LL); i < (long long)(v.size()); i++) {
    long long a = v[i].second.first, b = v[i].second.second, y = v[i].first;
    uf.unite(a, b, y);
  }
  assert(0 <= anses and anses <= M);
  cout << M - anses << endl;
  return 0;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  string s;
  solve();
  return 0;
}
