#include "bits/stdc++.h"

using namespace std;

using ll = long long;
using ld = long double;
using P = pair<ll, ll>;
constexpr ld EPS = 1e-12;
constexpr int INF = numeric_limits<int>::max() / 2;
constexpr int MOD = 1e9 + 7;

template <typename T>
void printv(const vector<T> &v)
{
    int sz = v.size();
    for (int i = 0; i < sz; i++)
    {
        cout << v[i] << " \n"[i == sz - 1];
    }
}

struct Edge
{
    int from, to, index;
    ll cost;
    Edge(int f, int t, int i, ll c) : from(f), to(t), index(i), cost(c) {}
};

bool operator<(const Edge &e, const Edge &f)
{
    return e.cost < f.cost;
}

class UnionFind
{
    std::vector<P> data; // 要素数, 連結成分中の頂点重み和

public:
    UnionFind(int size, const vector<ll> &w) : data(size)
    {
        assert(size == w.size());
        for (int i = 0; i < size; i++)
        {
            data[i] = P(-1, w[i]);
        }
    }
    ll unite(int x, int y)
    {
        x = root(x).first;
        y = root(y).first;
        if (x != y)
        {
            if (data[y].first < data[x].first)
                std::swap(x, y);
            data[x].first += data[y].first;
            data[x].second += data[y].second;
            data[y].first = x;
            data[y].second = data[x].second;
        }
        return data[x].second;
    }
    bool find(int x, int y)
    {
        return root(x) == root(y);
    }
    P root(int x)
    {
        return data[x].first < 0 ? P(x, data[x].second) : data[x] = root(data[x].first);
    }
    int size(int x)
    {
        return -data[root(x).first].first;
    }
};

int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);

    int n, m;
    cin >> n >> m;
    vector<vector<Edge>> g(n);
    vector<ll> x(n);
    for (int i = 0; i < n; i++)
    {
        cin >> x[i];
    }
    vector<ll> a(m), b(m), y(m);
    vector<Edge> es;
    for (int i = 0; i < m; i++)
    {
        cin >> a[i] >> b[i] >> y[i];
        a[i]--;
        b[i]--;
        g[a[i]].push_back(Edge{a[i], b[i], i, y[i]});
        g[b[i]].push_back(Edge{b[i], a[i], i, y[i]});
        es.push_back(Edge(a[i], b[i], i, y[i]));
    }
    sort(es.begin(), es.end());
    // 連結成分中で辺iは最大となりうるか
    vector<int> cand(m, 0);
    UnionFind uf(n, x);
    for (int i = 0; i < m; i++)
    {
        int from = es[i].from, to = es[i].to, index = es[i].index;
        ll cost = es[i].cost;
        ll sum = uf.unite(from, to);
        if (sum >= cost)
        {
            cand[index] = 1;
        }
    }
    sort(es.rbegin(), es.rend());
    vector<int> ret(m, 0);
    for (int i = 0; i < m; i++)
    {
        int from = es[i].from, to = es[i].to, index = es[i].index;
        ll cost = es[i].cost;
        if (ret[index])
            continue;
        if (cand[index] == 0)
            continue;
        ret[index] = 1;
        queue<int> que;
        que.push(from);
        que.push(to);
        while (!que.empty())
        {
            int cur = que.front();
            que.pop();
            for (const auto &e : g[cur])
            {
                if (e.cost > cost)
                    continue;
                if (ret[e.index])
                    continue;
                ret[e.index] = 1;
                que.push(e.to);
            }
        }
    }
    int cnt = 0;
    for (int i = 0; i < m; i++)
        if (ret[i] == 0)
            cnt++;
    cout << cnt << endl;
}


Measured memory_bytes: 17840