#include<bits/stdc++.h>
using namespace std;
#define len(val) static_cast<long long>(val.size())
#define rep(i, n) for(int i=0; i<(n); i++)
typedef long long ll;
typedef pair<int, int> P;

struct UnionFind
{
    std::vector<int> data;
    std::vector<ll> sum;
    std::vector<int> cnt;
    UnionFind(int size) : data(size, 0), sum(size, 0), cnt(size, 0){}
    void initialize(void){
        for(int i=0; i<(int)data.size(); i++){
            data[i] = i;
            sum[i] = 0;
            cnt[i] = 0;
        }
    }
    bool merge(int x, int y){
        x = find(x); y = find(y);
        if(x == y) return false;
        else{ data[x] = y; sum[y] += sum[x]; cnt[y] += cnt[x]; return true;}
    }
    ll get(int x){
        x = find(x);
        return sum[x];
    }
    void add(int x){
        cnt[find(x)]++;
    }
    int find(int x){ //根っこを見つける関数
        if(data[x] == x) return x;
        else return data[x] = find(data[x]); //経路圧縮
    }
    bool isSame(int x, int y){
        return find(x) == find(y);
    }
};

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false); int N, M;
    cin >> N >> M;
    int X[N];
    for(int i=0; i<N; i++) cin >> X[i];
    int A[M], B[M], Y[M];
    for(int i=0; i<M; i++) cin >> A[i] >> B[i] >> Y[i];
    vector<pair<int, pair<int, int>>> edge;
    for(int i=0; i<M; i++){
        edge.push_back(make_pair(Y[i], make_pair(A[i]-1, B[i]-1)));
    }
    sort(edge.begin(), edge.end());
    UnionFind uf(N);
    uf.initialize();
    ll ret = 0;

    for(int i=0; i<N; i++){
        uf.sum[i] = X[i];
    }
    for(int i=0; i<M; i++){
        ll w = edge[i].first;
        int u = edge[i].second.first;
        int v = edge[i].second.second;
        uf.merge(u, v);
        uf.add(u);
        if(w <= uf.get(u)){
            int r = uf.find(u);
            ret += uf.cnt[r];
            uf.cnt[r] = 0;
        }
    }
    cout << M-ret << endl;
}
