#include <bits/stdc++.h>
#define err(...) fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"), fflush(stderr)

typedef long long ll;

using namespace std;

const ll inf = static_cast<const ll>(1e18);
const int infi = static_cast<const int>(1e9);

vector<vector<pair<int, int> > > G;

struct Dsu {
    vector<int> R;
    Dsu(int n) : R(n) {
        for (int i = 0; i < n; i++) R[i] = i;
    }
    int get(int x) {
        if (R[x] == x) return x;
        return R[x] = get(R[x]);
    }
    bool merge(int a, int b) {
        a = get(a);
        b = get(b);
        if (a == b) return false;
        R[a] = b;
        return true;
    }
};

vector<set<int> > Tree;
vector<int> used;
int dfs_time = 1;

void iter_dfs(int v, int &k) {
    if (used[v] == dfs_time || k <= 0) return;
    used[v] = dfs_time;
    for (auto u : Tree[v]) {
        k--;
        if (k <= 0) return;
        iter_dfs(u, k);
    }
}

bool kdfs(int v, int k) {
    dfs_time++;
    iter_dfs(v, k);
    return k > 0;
}

struct Data {
    ll s, dx;
    set<int> V;


    ll sum() {
        return s + dx;
    }
};

vector<int> X;
map<int, Data*> S;

void dfs_split(int v, Data* part, Data *nw) {
    if (used[v] == dfs_time) return;
    used[v] = dfs_time;
    part->s -= X[v];
    part->V.erase(v);
    nw->V.insert(v);
    nw->s += X[v];
    S[v] = nw;
    for (auto u : Tree[v]) dfs_split(u, part, nw);

}

void split_sets(int a, int b) {
    dfs_time++;
    auto data = new Data();
    dfs_split(a, S[b], data);
}

void solve() {
    int n, m;
    cin >> n >> m;
    G.resize(n);
    used.resize(n);
    X.resize(n);
    Tree.resize(n);
    vector<pair<int, pair<int, int> > > E(m), T, Good;
    for (auto &x : X) {
        cin >> x;
    }
    for (int i = 0; i < m; i++) {
        int a, b, e;
        cin >> a >> b >> e;
        a--, b--;
        G[a].push_back({b, e});
        G[b].push_back({a, e});
        E[i] = {e, {a, b}};
    }
    sort(E.begin(), E.end());
    Dsu dsu(n);
    for (int i = 0; i < m; i++) {
        if (dsu.merge(E[i].second.first, E[i].second.second)) {
            T.push_back(E[i]);
            Tree[E[i].second.first].insert(E[i].second.second);
            Tree[E[i].second.second].insert(E[i].second.first);
        }
    }
    auto cur_D = new Data();
    for (int i = 0; i < n; i++) {
        cur_D->s += X[i];
        cur_D->V.insert(i);
        S[i] = cur_D;
    }
    reverse(T.begin(), T.end());
    for (auto e : T) {
        int a = e.second.first;
        int b = e.second.second;
        int l = e.first;
        ll s = S[a]->sum();
        if (s >= l) {
            Good.push_back(e);
            continue;
        }
        Tree[a].erase(b);
        Tree[b].erase(a);
        for (int k = 1; ; k *= 2) {
            bool q = kdfs(a, k);
            bool w = kdfs(b, k);
            if (q) {
                break;
            }
            if (w) {
                swap(a, b);
                break;
            }
        }
        split_sets(a, b);
    }

    Dsu ans(n);
    for (auto e : Good) {
        ans.merge(e.second.first, e.second.second);
    }
    map<int, ll> C;
    for (int i = 0; i < n; i++) {
        C[ans.get(i)] += X[i];
    }
    ll res = m;
    for (auto e : E) {
        int a = ans.get(e.second.first);
        int b = ans.get(e.second.second);
        if (a == b && C[a] >= e.first) {
            res--;
        }
    }
    cout << res;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
#ifdef SIR
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    solve();
};

Measured memory_bytes: 39860