#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<set>
#include<queue>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<climits>

#define MOD (1000000007)
#define N_MAX (100010)

using namespace std;

typedef long long int Int;

int N,M;
Int A[N_MAX];

class Disjoint_Set {
    private:
        int parent[N_MAX]; //parent node of the node x
    public:
        Int node_weight[N_MAX]; //weight of the node
        int edge_num[N_MAX]; //the number of edge in the node x
  
        Disjoint_Set(int n) {
            for(int i = 0;i < n;i++) {
                parent[i] = i;
                node_weight[i] = A[i];
                edge_num[i] = 0;
            }
        }

        int root(int x) {
            return parent[x] == x ? x : parent[x] = root(parent[x]);
        }

        void merge(int x,int y) {
            x = root(x);
            y = root(y);
            if(x != y) {
                parent[x] = y;
                node_weight[y] += node_weight[x];
                edge_num[y] += edge_num[x];
                node_weight[x] = edge_num[x] = 0;
            }
            edge_num[y]++;
        }
};

struct Edge {
    int from;
    int to;
    Int cost;
    bool operator < (const struct Edge &right) const {
        return cost < right.cost;
    }
};

int main(void) {
    cin>>N>>M;

    for(int i = 0;i < N;i++) {
        cin>>A[i];
    }

    Disjoint_Set DS(N);
    vector<struct Edge> e;
    struct Edge edge;
    for(int i = 0;i < M;i++) {
        int a,b;
        Int c;
        cin>>a>>b>>c;
        edge.from = --a;
        edge.to = --b;
        edge.cost = c;
        e.push_back(edge);
    }

    sort(e.begin(),e.end());
    Int ans = M;
    for(int i = 0;i < M;i++) {
        DS.merge(e[i].from,e[i].to);
        int r = DS.root(e[i].from);
        if(DS.node_weight[r] >= e[i].cost) {
            ans -= DS.edge_num[r];
            DS.edge_num[r] = 0;
        }
    }

    cout<<ans<<endl;

    return 0;
}
