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 eval(n: int; es: seq[Edge]; x: seq[int]; k: int; used: var seq[bool]; eraseFlag: bool): int =
  var uft = initUnionFindTree(n)

  for e in es:
    if e.y > k:
      continue
    if used[e.a] or used[e.b]:
      continue
    uft.union(e.a, e.b)

  var rootCount = 0
  var rootTab = initTable[int, int]()
  for v in 0..<n:
    if used[v]:
      continue
    if uft.find(v) == v:
      rootTab[v] = rootCount
      rootCount += 1

  var sumX = newSeq[int](rootCount)
  for v in 0..<n:
    if used[v]:
      continue
    let r = rootTab[uft.find(v)]
    sumX[r] += x[v]

  var maxY = newSeq[int](rootCount)
  for e in es:
    if e.y > k:
      continue
    if used[e.a] or used[e.b]:
      continue

    let v = e.a
    let r = rootTab[uft.find(v)]
    maxY[r] = max(maxY[r], e.y)

  var id = -1
  for i in 0..<rootCount:
    if sumX[i] >= maxY[i]:
      id = i
      break

  if not eraseFlag:
    return id

  var ans = 0
  for e in es:
    if e.y > k:
      continue
    if used[e.a] or used[e.b]:
      continue
    if rootTab[uft.find(e.a)] == id:
      ans += 1

  for v in 0..<n:
    if used[v]:
      continue
    if rootTab[uft.find(v)] == id:
      used[v] = true

  return ans

proc main() =
  let (n, m) = readInt2()
  let x = readSeq().map(parseInt)
  var es = newSeq[Edge](0)
  for i in 0..<m:
    let (a, b, y) = readInt3()
    es.add((y, a - 1, b - 1))

  var used = newSeq[bool](n)
  var ans = 0
  while used.any(it => not it):
    var lb = 0
    var ub = int(1e9 + 1)
    while ub - lb > 1:
      let mid = (ub + lb) div 2
      if eval(n, es, x, mid, used, false) >= 0:
        lb = mid
      else:
        ub = mid
    if lb <= 0:
      break
    ans += eval(n, es, x, lb, used, true)
  echo m - ans

main()

