N, M = readline.split(' ').map(&:to_i)
Edges = Hash.new {|h,k| h[k]=Hash.new }

M.times do |idx|
  n1, n2, dist = readline.split(' ').map(&:to_i)
  Edges[n1-1][n2-1] = [dist, idx]
  Edges[n2-1][n1-1] = [dist, idx]
end

class Path
  attr_reader :distance, :node_seq
  def initialize(distance, node_seq)
    @distance = distance
    @node_seq = node_seq
  end
end

def merge_sorted_paths(a, b)
  return b if a.length==0
  return a if b.length==0

  # build a holder array that is the size of both input arrays
  # O(n) space
  result = []

  # get lower head value
  if a[0].distance < b[0].distance
    result << a.shift
  else
    result << b.shift
  end

  # check to see if either array is empty
  if a.length == 0
    return result + b
  elsif b.length ==0
    return result + b
  else
    return result + merge_sorted_paths(a, b)
  end
end

def find_a_path_less_than(src, dest, max)
  sorted_paths = [Path.new(0, [src])] # sorted_paths: [Path] sorted by Path.distance

  while head = sorted_paths.shift
    if head.distance >= max
      return nil
    end

    if head.node_seq[-1]==dest
      return head.node_seq
    end

    new_paths = []
    Edges[head.node_seq[-1]].each do |dest2, edge|
      distance, = *edge
      if head.distance + distance < max
        p = Path.new(head.distance + distance, head.node_seq+[dest2])
        new_paths.unshift(p)
      end
    end

    #sorted_paths.push(*new_paths)
    #sorted_paths.sort_by!(&:distance)
    new_paths.sort_by!(&:distance)
    sorted_paths = merge_sorted_paths(sorted_paths, new_paths)
  end

  return nil
end


count=0
Edges.keys.sort.each do |src|
  Edges[src].keys.sort.each do |dst|
    if src<=dst then
      break
    end

    e = Edges[src][dst]
    if find_a_path_less_than(src, dst, e[0])
      count += 1
    end
  end
end

puts count


