#include <bits/stdc++.h>
using namespace std;
const long long int E = 1e18 + 7;
const long long int MOD = 1000000007;
template <typename K, typename I, typename U>
struct LCT {
  K key;
  K left, right;
  function<bool(K, K)> Comp;
  const I I_E;
  const U U_E;
  I item, data;
  U up;
  const function<I(I, I)> first;
  const function<I(I, U, K, K, int)> G;
  const function<U(U, U)> H;
  LCT *P;
  LCT *L;
  LCT *R;
  int children;
  LCT(const K &key, const function<bool(K, K)> &Comp, const I &I_E,
      const U &U_E, const function<I(I, I)> &first,
      const function<I(I, U, K, K, int)> &G, const function<U(U, U)> &H)
      : key(key),
        left(key),
        right(right),
        Comp(Comp),
        I_E(I_E),
        U_E(U_E),
        item(I_E),
        data(I_E),
        up(U_E),
        first(first),
        G(G),
        H(H),
        P(NULL),
        L(NULL),
        R(NULL),
        children(1) {}
  bool is_root() const { return P == NULL; }
  bool is_small_root() const {
    return P == NULL || (P->R != this && P->L != this);
  }
  void down() {
    item = G(item, up, key, key, 1);
    if (L != NULL) {
      L->up = L->H(L->up, up);
      L->data = L->G(L->data, up, L->left, L->right, L->children);
    }
    if (R != NULL) {
      R->up = R->H(R->up, up);
      R->data = R->G(R->data, up, R->left, R->right, R->children);
    }
    up = U_E;
  }
  void RENEW() {
    children = 1;
    if (L != NULL) {
      data = first(L->data, item);
      left = L->left;
      children += L->children;
    } else {
      data = item;
      left = key;
    }
    if (R != NULL) {
      data = first(data, R->data);
      right = R->right;
      children += R->children;
    } else {
      right = key;
    }
    data = G(data, up, left, right, children);
  }
  LCT *Rotate_R() {
    assert(L);
    down();
    L->down();
    LCT *ret = L;
    ret->P = P;
    if (P != NULL && P->L == this) {
      P->L = ret;
    } else if (P != NULL && P->R == this) {
      P->R = ret;
    }
    if (ret->R) {
      L = ret->R;
      L->P = this;
    } else {
      L = NULL;
    }
    P = ret;
    ret->R = this;
    RENEW();
    ret->RENEW();
    return ret;
  }
  LCT *Rotate_L() {
    assert(R);
    down();
    R->down();
    LCT *ret = R;
    ret->P = P;
    if (P != NULL && P->L == this) {
      P->L = ret;
    } else if (P != NULL && P->R == this) {
      P->R = ret;
    }
    if (ret->L) {
      R = ret->L;
      R->P = this;
    } else {
      R = NULL;
    }
    P = ret;
    ret->L = this;
    RENEW();
    ret->RENEW();
    return ret;
  }
  void Link() {
    Splay();
    while (!is_root()) {
      P->Splay();
      P->down();
      P->R = this;
      P->RENEW();
      Splay();
    }
  }
  void Splay() {
    while (!is_small_root()) {
      if (P->is_small_root()) {
        if (P->L == this) {
          P->Rotate_R();
        } else {
          P->Rotate_L();
        }
      } else {
        bool p1 = (P->L == this);
        bool p2 = (P->P->L == P);
        if (p1 == p2) {
          if (p1) {
            P->P->Rotate_R()->Rotate_R();
          } else {
            P->P->Rotate_L()->Rotate_L();
          }
        } else {
          if (p1) {
            P->Rotate_R();
            P->Rotate_L();
          } else {
            P->Rotate_L();
            P->Rotate_R();
          }
        }
      }
    }
  }
  LCT *expose() {
    Link();
    LCT *ret = R;
    R = NULL;
    RENEW();
    return ret;
  }
  LCT *min() {
    if (L == NULL) {
      return this;
    }
    return L->min();
  }
  void update(const U &u) {
    expose();
    up = H(up, u);
    data = G(data, u, left, right, children);
  }
  void small_tree_update(const U &u) {
    Splay();
    up = H(up, u);
    data = G(data, u, left, right, children);
  }
  void node_update(const U &u) {
    Splay();
    item = G(item, u, key, key, 1);
    RENEW();
  }
};
vector<long long int> uft;
long long int parent(long long int w) {
  return (uft[w] == w ? w : uft[w] = parent(uft[w]));
}
void merge(long long int a, long long int b) { uft[parent(a)] = parent(b); }
vector<pair<long long int, long long int>> uft2;
long long int parent2(long long int w) {
  return (uft2[w].first == w ? w : uft2[w].first = parent2(uft2[w].first));
}
void merge2(long long int a, long long int b) {
  if (parent2(a) == parent2(b)) {
    return;
  }
  uft2[parent2(b)].second += uft2[parent2(a)].second;
  uft2[parent2(a)].first = parent2(b);
}
vector<vector<long long int>> EDGE;
vector<long long int> P;
void dfs(long long int w, long long int p) {
  P[w] = p;
  for (auto &I : EDGE[w]) {
    if (I == p) {
      continue;
    }
    dfs(I, w);
  }
}
int main() {
  long long int n, m;
  cin >> n >> m;
  vector<long long int> X(n);
  for (auto &I : X) {
    cin >> I;
  }
  uft.resize(n);
  uft2.resize(n);
  for (int i = 0; i < n; i++) {
    uft[i] = uft2[i].first = i;
    uft2[i].second = X[i];
  }
  EDGE.resize(n);
  P.resize(n, -1);
  auto first = [](long long int a, long long int b) { return a + b; };
  auto G = [](long long int a, long long int b, long long int l,
              long long int r, int children) { return a + b * children; };
  auto H = [](long long int a, long long int b) { return a + b; };
  vector<LCT<long long int, long long int, long long int>> A(
      n, LCT<long long int, long long int, long long int>(
             0, greater<long long int>(), 0, 0, first, G, H));
  for (int i = 0; i < n; i++) {
    A[i].key = i;
    A[i].RENEW();
  }
  vector<pair<long long int, pair<long long int, long long int>>> edge(m);
  for (auto &I : edge) {
    cin >> I.second.first >> I.second.second >> I.first;
    I.second.first--;
    I.second.second--;
  }
  sort(edge.begin(), edge.end());
  priority_queue<pair<long long int, long long int>> Q;
  vector<bool> used(m, false);
  for (int i = 0; i < m; i++) {
    if (parent(edge[i].second.first) != parent(edge[i].second.second)) {
      used[i] = true;
      merge(edge[i].second.first, edge[i].second.second);
      EDGE[edge[i].second.first].push_back(edge[i].second.second);
      EDGE[edge[i].second.second].push_back(edge[i].second.first);
      Q.push({edge[i].first, i});
    }
  }
  dfs(0, -1);
  for (int i = 1; i < n; i++) {
    A[i].P = &A[P[i]];
  }
  for (int i = 0; i < n; i++) {
    A[i].update(X[i]);
  }
  long long int ans = n - 1;
  while (!Q.empty()) {
    pair<long long int, long long int> w = Q.top();
    Q.pop();
    if (P[edge[w.second].second.first] != edge[w.second].second.second) {
      swap(edge[w.second].second.first, edge[w.second].second.second);
    }
    A[edge[w.second].second.second].expose();
    auto p = A[edge[w.second].second.second].min();
    p->Splay();
    if (p->item < edge[w.second].first) {
      A[edge[w.second].second.second].expose();
      A[edge[w.second].second.first].Splay();
      A[edge[w.second].second.first].P = NULL;
      A[edge[w.second].second.second].update(
          -A[edge[w.second].second.first].item);
      ans--;
    } else {
      merge2(edge[w.second].second.second, edge[w.second].second.first);
    }
  }
  for (int i = 0; i < m; i++) {
    if (used[i]) {
      continue;
    }
    if (parent2(edge[i].second.first) == parent2(edge[i].second.second) &&
        uft2[parent2(edge[i].second.second)].second >= edge[i].first) {
      ans++;
    }
  }
  cout << m - ans << endl;
  return 0;
}
