#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

int X[100010];
bool seen[100010];
vector<tuple<int, int, int>> V;

class UFDS {
   public:
      vector<int> p, rank, bad;
      vector<LL> sz;
      UFDS(const int N) {
         p.assign(N, 0);
         rank.assign(N, 0);
         sz.assign(N, 0);
         bad.assign(N, 0);
         for (int i = 1; i < N; i++)
            p[i] = i, sz[i] = X[i];
      }//constructor
      int findSet(const int i) {
         return p[i] == i ? i : p[i] = findSet(p[i]);
      }//findSet
      LL getSize(const int i) {
         return sz[findSet(i)];
      }//getSize
      void clearBad(const int i) {
         bad[findSet(i)] = 0;
      }//clearBad
      void incBad(const int i) {
         bad[findSet(i)]++;
      }//incBad
      int getBad(const int i) {
         return bad[findSet(i)];
      }//getBad
      void unite(const int i, const int j) {
         int r1 = findSet(i), r2 = findSet(j);
         if (r1 == r2)
            return;
         rank[r1] >= rank[r2] ? (p[r2] = r1, sz[r1] += sz[r2], bad[r1] += bad[r2]) : (p[r1] = r2, sz[r2] += sz[r1], bad[r2] += bad[r1]);
         if (rank[r1] == rank[r2])
            rank[r1]++;
      }//unite
};

int main() {
   int N, M, A, B, Y;
   scanf("%d %d", &N, &M);
   for (int i = 1; i <= N; i++)
      scanf("%d", &X[i]);
   UFDS U(N + 5);
   while (M--) {
      scanf("%d %d %d", &A, &B, &Y);
      V.push_back(make_tuple(Y, A, B));
   }//while
   sort(V.begin(), V.end());
   for (int i = 0; i < (int)V.size(); i++) {
      int p1 = U.findSet(get<1>(V[i]));
      int p2 = U.findSet(get<2>(V[i]));
      U.unite(p1, p2);
      if (U.getSize(p1) < get<0>(V[i]))
         U.incBad(p1);
      else
         U.clearBad(p1);
   }//for
   int ans = 0;
   for (int i = 1; i <= N; i++)
      if (!seen[U.findSet(i)])
         seen[U.findSet(i)] = 1, ans += U.getBad(i);
   printf("%d\n", ans);
   return 0;
}//main
