#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

const int N = 100005;

int n, m, u, v, w, ans = 0, sz[N];
long long dsu[N];

struct SEdge
{
    int u, v;
    long long w;
};
vector<SEdge> ed, tr;
vector<pair<int, long long>> ch;

int trace(int u)
{
    return dsu[u] < 0 ? u : trace(dsu[u]);
}

bool unity(SEdge cur)
{
    if ((cur.u = trace(cur.u)) == (cur.v = trace(cur.v)))
        return false;
    if (sz[cur.u] < sz[cur.v])
        swap(cur.u, cur.v);
    ch.push_back(make_pair(cur.v, dsu[cur.v]));
    sz[cur.u] += sz[cur.v];
    dsu[cur.u] += dsu[cur.v];
    dsu[cur.v] = cur.u;
    return true;
}

int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld", dsu + i);
        dsu[i] = -dsu[i];
      	sz[i] = 1;
    }
    while (m--)
    {
        scanf("%d%d%d", &u, &v, &w);
        ed.push_back((SEdge){u, v, w});
    }
    sort(ed.begin(), ed.end(), [](const SEdge &a, const SEdge &b) {
        return a.w < b.w;
    });
    for (SEdge &v : ed)
        if (unity(v))
            tr.push_back(v);
    for (int i = n - 2; i >= 0; i--)
    {
        SEdge cur = tr[i];
        int u = trace(cur.u);
        if (-dsu[u] < cur.w)
            dsu[u] -= (dsu[ch[i].first] = ch[i].second);
    }
    for (SEdge &v : ed)
        if (trace(v.u) != trace(v.v) || -dsu[trace(v.u)] < v.w)
            ans++;
    printf("%d", ans);
}
