#include <bits/stdc++.h>
using namespace std;
template <class T1, class T2>
ostream& operator<<(ostream& os, const pair<T1, T2>& a) {
  return os << "(" << a.first << "," << a.second << ")";
}
template <class T>
void pv(T a, T b) {
  for (T i = a; i != b; ++i) cout << (*i) << " ";
  cout << endl;
}
template <class T>
void chmin(T& a, const T& b) {
  if (a > b) a = b;
}
template <class T>
void chmax(T& a, const T& b) {
  if (a < b) a = b;
}
int nextInt() {
  int x;
  scanf("%d", &x);
  return x;
}
const int MAX_N = 112345;
const int MAX_M = 112345;
struct Edge {
  int a, b;
  long long w;
  bool alive;
  bool operator<(const Edge& o) const { return w < o.w; }
};
long long X[MAX_N];
vector<Edge> edge;
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool link(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (data[y] < data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
  bool same(int x, int y) { return root(x) == root(y); }
  int num() {
    int res = 0;
    for (int i = 0, _n = (int)(data.size()); i < _n; ++i) res += root(i) == i;
    return res;
  }
};
long long S[MAX_N];
bool check(int N) {
  for (int i = 0, _n = (int)(N); i < _n; ++i) S[i] = X[i];
  UnionFind uf(N);
  for (int i = 0, _n = (int)(edge.size()); i < _n; ++i) {
    if (edge[i].alive) {
      long long s1 = S[uf.root(edge[i].a)];
      long long s2 = S[uf.root(edge[i].b)];
      if (uf.link(edge[i].a, edge[i].b)) {
        S[uf.root(edge[i].a)] = s1 + s2;
      }
    }
  }
  bool ok = true;
  for (int i = 0, _n = (int)(edge.size()); i < _n; ++i) {
    Edge& e = edge[i];
    if (e.alive) {
      int r = uf.root(e.a);
      if (S[r] < e.w) {
        ok = false;
        e.alive = false;
      }
    }
  }
  return ok;
}
int main2() {
  int N = nextInt();
  int M = nextInt();
  for (int i = 0, _n = (int)(N); i < _n; ++i) X[i] = nextInt();
  edge.clear();
  for (int i = 0, _n = (int)(M); i < _n; ++i) {
    int a = nextInt() - 1;
    int b = nextInt() - 1;
    long long y = nextInt();
    edge.push_back((Edge){a, b, y, true});
  }
  random_shuffle((edge).begin(), (edge).end());
  for (;;) {
    if (check(N)) break;
    vector<Edge> nxt;
    for (Edge e : edge)
      if (e.alive) nxt.push_back(e);
    edge = nxt;
  }
  int ans = M - edge.size();
  cout << ans << endl;
  return 0;
}
int main() {
  for (; !cin.eof(); cin >> ws) main2();
  return 0;
}
