#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <set>
#define MAXN 100005
#define INF 0x3f3f3f3f
#define rint register int
#define LL long long
#define LD long double
using namespace std;

int n, m, cnt, ans, head[MAXN], f[MAXN], b[MAXN];
LL num[MAXN];

struct Edge {int next, to; LL dis;} edge[MAXN*2];
struct E {int x, y; LL z;} e[MAXN];

void addedge(int from, int to, LL dis)
{
    edge[++cnt].next=head[from];
    edge[cnt].to=to;
    edge[cnt].dis=dis;
    head[from]=cnt;
}

bool CMP(E x, E y)
{
    return x.z<y.z;
}

int find(int x)
{
    if(f[x]!=x) f[x]=find(f[x]);
    return f[x];
}

int main()
{
    scanf("%d%d", &n, &m);
    for(rint i=1; i<=n; ++i) scanf("%lld", &num[i]);
    for(rint i=1, x, y; i<=m; ++i)
    {
        scanf("%d%d%lld", &e[i].x, &e[i].y, &e[i].z);
        addedge(e[i].x, e[i].y, e[i].z);
        addedge(e[i].y, e[i].x, e[i].z);
    }
    for(rint i=1; i<=n; ++i) f[i]=i;
    sort(e+1, e+m+1, CMP);
    for(rint i=1; i<=m; ++i)
    {
        int fx=find(e[i].x), fy=find(e[i].y);
        if(fx==fy)
        {
            if(num[fx]<e[i].z) ans++, b[fx]++;
        }
        else
        {
            f[fx]=fy, num[fy]+=num[fx];
            b[fy]+=b[fx];
            if(num[fy]>=e[i].z)
            {
                ans-=b[fy];
                b[fy]=0;
            }
            else
            {
                b[fy]++;
                ans++;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}
