import strutils
import sequtils
import algorithm
import math
import queues
import tables
import sets
import future

const INF* = int(1e18 + 373)

proc readLine*(): string =
  stdin.readLine()
proc readSeq*(): seq[string] =
  readLine().strip().split()
proc readSeq*(n: Natural): seq[string] =
  result = newSeq[string](n)
  for i in 0..<n:
    result[i] = readLine().strip()
proc readInt1*(): int =
  readSeq().map(parseInt)[0]
proc readInt2*(): (int, int) =
  let a = readSeq().map(parseInt)
  return (a[0], a[1])
proc readInt3*(): (int, int, int) =
  let a = readSeq().map(parseInt)
  return (a[0], a[1], a[2])
proc readInt4*(): (int, int, int, int) =
  let a = readSeq().map(parseInt)
  return (a[0], a[1], a[2], a[3])
proc newSeqWith*[T](n: Natural; e: T): seq[T] =
  result = newSeq[T](n)
  for i in 0..<n:
    result[i] = e
type seq2*[T] = seq[seq[T]]
proc newSeq2*[T](n1, n2: Natural): seq2[T] =
  newSeqWith(n1, newSeq[T](n2))
type seq3*[T] = seq[seq[seq[T]]]
proc newSeq3*[T](n1, n2, n3: Natural): seq3[T] =
  newSeqWith(n1, newSeqWith(n2, newSeq[T](n3)))

#------------------------------------------------------------------------------#
#------------------------------------------------------------------------------#
type UnionFindTree = object
  p: seq[int]
  h: seq[int]

proc initUnionFindTree(n: int): UnionFindTree =
  result.p = newSeq[int](n)
  result.p.fill(-1)
  result.h = newSeq[int](n)
  result.h.fill(0)

proc find(this: var UnionFindTree, v: int): int =
  if this.p[v] == -1:
    return v
  this.p[v] = find(this, this.p[v])
  return this.p[v]

proc same(this: var UnionFindTree, u, v: int): bool =
  this.find(u) == this.find(v)

proc union(this: var UnionFindTree, u, v: int) =
  var uRoot = this.find(u)
  var vRoot = this.find(v)
  if uRoot == vRoot:
    return

  if this.h[uRoot] < this.h[vRoot]:
    swap(uRoot, vRoot)

  this.p[vRoot] = uRoot
  if this.h[uRoot] == this.h[vRoot]:
    this.h[uRoot] += 1

#------------------------------------------------------------------------------#
type Edge = tuple [ y, a, b: int ]

proc dfs(g: seq2[(int, int, int)]; v, k: int; used: var seq[bool]): int =
  var ans = 0
  for i in 0..<g[v].len():
    let (u, y, j) = g[v][i]
    if y > k:
      continue
    if used[j]:
      continue
    used[j] = true
    ans += 1
    ans += dfs(g, u, k, used)

  return ans

proc main() =
  let (n, m) = readInt2()
  let x = readSeq().map(parseInt)

  var es = newSeq[Edge](m)
  var g = newSeq2[(int, int, int)](n, 0)
  for i in 0..<m:
    let (a, b, y) = readInt3()
    es[i] = (y, a - 1, b - 1);
  es.sort(cmp[Edge])

  for i in 0..<m:
    let (y, a, b) = es[i]
    g[a].add((b - 1, y, i))
    g[b].add((a - 1, y, i))

  var uft = initUnionFindTree(n)
  var useful = newSeq[bool](m)
  var xSum = x
  for i in 0..<m:
    if not uft.same(es[i].a, es[i].b):
      let ar = uft.find(es[i].a)
      let br = uft.find(es[i].b)
      let atmp = xSum[ar]
      let btmp = xSum[br]
      xSum[ar] += btmp
      xSum[br] += atmp

    uft.union(es[i].a, es[i].b)
    let r = uft.find(es[i].a)
    if xSum[r] >= es[i].y:
      useful[i] = true

  var ans = 0
  var used = newSeq[bool](m)
  for i in countdown(m - 1, 0):
    if not useful[i]:
      continue
    if used[i]:
      continue
    ans += dfs(g, es[i].a, es[i].y, used)
  echo m - ans

main()

