package main
 
import (
  "fmt"
  "math"
)
 
const inf = math.MaxInt32
 
type edge struct {
  from int
  to   int
  cost int
}
 
func main() {
  var n,m int
  fmt.Scan(&n,&m)
  
  edges := make([]edge ,m)
  for i := range edges {
    fmt.Scan(&edges[i].from)
    fmt.Scan(&edges[i].to)
    fmt.Scan(&edges[i].cost)
  }
  
  //ノードi,j間の最短経路を定義
  dist := make([][]int, n)
  for i := 0; i < n; i++ {
    dist[i] = make([]int, n)
    for j := 0; j < n; j++ {
      if i == j {
        dist[i][j] = 0
      } else {
        dist[i][j] = inf
      }
    }
  }
  
  //既知の経路
  for i := 0; i < m; i++ {
    dist[edges[i].from-1][edges[i].to-1] = edges[i].cost
    dist[edges[i].to-1][edges[i].from-1] = edges[i].cost
  }
  
  //最短経路を更新
    for i := 0; i < n; i++ {
      for j := 0; j < n; j++ {
        for k := 0; k < n; k++ {
        //スタートとゴールが同じ場合は計算不要
        if i == j {
          continue
        }
        //経由した方が低コストの場合、最短経路を更新
        if dist[i][k]+dist[k][j] < dist[i][j] {
          dist[i][j] = dist[j][i]+dist[i][k]
          dist[j][i] = dist[j][i]+dist[i][k]
        }
      }
    }
  }
  
  ans := 0
  
  //最短経路に含まれていない辺をカウント
  for i := 0; i < m; i++ {
    if dist[edges[i].from-1][edges[i].to-1] > edges[i].cost {
      ans++
    }
  }
  
  fmt.Println(ans)
}