#include <bits/stdc++.h>
using namespace std;

// one-based numbering
struct UnionFind {
    vector<int> data;
    // i: (data[i] < 0) -> group size, (data[i] > 0) -> parent;
    UnionFind(int n) {
        data.resize(n+1, -1);
    }
    int find(int x) {
        if(data[x] < 0) return x;
        else return data[x] = find(data[x]);
    }
    int size(int x) {
        return -data[find(x)];
    }
    bool unite(int x, int y) {
        x = find(x); y = find(y);
        if(x == y) return false;
        if (data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        return true;
    }
    bool same(int x, int y) {
        x = find(x); y = find(y);
        return x == y;
    }
};

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n, m; cin >> n >> m;
    vector<long long> x(n+1, 0);
    for (int i = 0; i < n; i++) cin >> x[i+1];
    using edge = pair<long long, array<int, 2>>;
    vector<edge> v;
    vector<array<int, 3>> p(m);
    vector<array<long long, 2>> px(m);
    for (int i = 0; i < m; i++) {
        int a, b; long long y; cin >> a >> b >> y;
        v.push_back({y, {a, b}});
    }
    sort(v.begin(), v.end());
    UnionFind uf(n);
    for (int i = 0; i < m; i++) {
        int a = v[i].second[0], b = v[i].second[1];
        p[i][0] = uf.find(a), p[i][1] = uf.find(b);
        px[i][0] = x[p[i][0]], px[i][1] = x[p[i][1]];
        if (!uf.same(a, b)) {
            uf.unite(a, b);
            x[uf.find(a)] = x[p[i][0]] + x[p[i][1]];
        }
        p[i][2] = uf.find(a);
    }
    long long all = x[uf.find(1)];
    for (int i = 0; i < n; i++) x[i] = all;
    int ans = 0;
    for (int i = m-1; i >= 0; i--) {
        if (x[p[i][2]] < v[i].first) {
            ans++;
            x[p[i][0]] = px[i][0];
            x[p[i][1]] = px[i][1];
        }
    }
    cout << ans << "\n";
    return 0;
}