#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
const double eps = 1e-10;
const ll MOD = 1000000007;
const int INF = 1000000000;
const ll LINF = 1ll << 50;
template <typename T>
void printv(const vector<T> &s) {
  for (int i = 0; i < (int)(s.size()); ++i) {
    cout << s[i];
    if (i == (int)(s.size()) - 1)
      cout << endl;
    else
      cout << " ";
  }
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> p) {
  os << p.first << ":" << p.second;
  return os;
}
struct UnionFind {
  vector<int> par, sz;
  UnionFind(int n) : par(n), sz(n, 1) {
    for (int i = 0; i < n; ++i) par[i] = i;
  }
  int root(int x) {
    if (par[x] == x) return x;
    return par[x] = root(par[x]);
  }
  void merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return;
    if (sz[x] < sz[y]) swap(x, y);
    par[y] = x;
    sz[x] += sz[y];
    sz[y] = 0;
  }
  bool issame(int x, int y) { return root(x) == root(y); }
  int size(int x) { return sz[root(x)]; }
};
struct Edge {
  int a, b, y, id;
  Edge(int a, int b, int y, int id) : a(a), b(b), y(y), id(id) {}
};
bool operator<(const Edge &e1, const Edge &e2) { return e1.y < e2.y; }
vector<bool> sel;
int ans = 0;
void dfs(int a, int y, const vector<vector<Edge>> &g) {
  for (auto &e : g[a]) {
    if (sel[e.id]) continue;
    if (e.y <= y) {
      sel[e.id] = true;
      ans++;
      dfs(e.b, y, g);
    }
  }
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
  int n, m;
  cin >> n >> m;
  vector<int> x(n);
  for (int i = 0; i < n; ++i) {
    cin >> x[i];
  }
  vector<vector<Edge>> g(n);
  vector<Edge> edges;
  for (int i = 0; i < m; ++i) {
    int a, b, y;
    cin >> a >> b >> y;
    a--;
    b--;
    g[a].push_back(Edge(a, b, y, i));
    g[b].push_back(Edge(b, a, y, i));
    edges.push_back(Edge(a, b, y, i));
  }
  sort(edges.begin(), edges.end());
  UnionFind uf(n);
  for (int i = 0; i < n; ++i) {
    uf.sz[i] = x[i];
  }
  stack<int> st;
  for (int i = 0; i < m; ++i) {
    uf.merge(edges[i].a, edges[i].b);
    if (uf.size(edges[i].a) >= edges[i].y) st.push(edges[i].id);
  }
  sel.resize(m + 1, false);
  while (!st.empty()) {
    int now = st.top();
    st.pop();
    if (sel[now]) continue;
    dfs(edges[now].a, edges[now].y, g);
  }
  cout << m - ans << endl;
}
