import numpy as np

from scipy.sparse.csgraph import floyd_warshall as fw

import sys

sdin = sys.stdin.readline





n,m = list(map(int, sdin().split()))



INF = float("inf")

adj_mat = INF * np.ones((n, n))





for _ in range(m):

    a,b,c = list(map(int, sdin().split()))

    a -= 1

    b -= 1

    adj_mat[a,b] = c

    adj_mat[b,a] = c



    

for i in range(n):

    adj_mat[i,i] = 0



    

shortest = fw(adj_mat)





ans = 0

for i in range(n):

    for j in range(i+1,n):

        if adj_mat[i][j] != INF and adj_mat[i][j] > shortest[i][j]:

            ans += 1



print(ans)
import sys

stdin = sys.stdin

 

sys.setrecursionlimit(10**5) 

 

def li(): return list(map(int, stdin.readline().split()))

def li_(): return [int(x)-1 for x in stdin.readline().split()]

def lf(): return list(map(float, stdin.readline().split()))

def ls(): return stdin.readline().split()

def ns(): return stdin.readline().rstrip()

def lc(): return list(ns())

def ni(): return int(stdin.readline())

def nf(): return float(stdin.readline())



from heapq import heappush, heappop



def dijkstra(graph:list, node:int, start:int) -> list:

    # 未探索のノードは距離INF

    INF = float("inf")

    dist = [INF]*node

    

    # 始点ノードの距離を0とし、dfsのためのpriority queを作成

    dist[start] = 0

    heap = [(0,start)]

    

    # 未探索のノードをpriority queueに入れる

    while heap:

        cost, cur_node = heappop(heap)

        

        for nex_cost, nex_node in graph[cur_node]:

            dist_cand = dist[cur_node] + nex_cost

            if dist_cand < dist[nex_node]:

                dist[nex_node] = dist_cand

                heappush(heap, (dist[nex_node], nex_node))

    

    return dist



n,m = li()



edges = []

graph = [[] for _ in range(n)]

adj_mat = [[0]*n for _ in range(n)]



for _ in range(m):

    a,b,c = li()

    a -= 1

    b -= 1

    graph[a].append((c,b))

    graph[b].append((c,a))

    edges.append((a,b,c))

    

# 各点からの最短dist

for i in range(n):

    adj_mat[i] = dijkstra(graph, n, i)

    

    

# 最短路とedgeの比較

ans = 0

for ai, bi, ci in edges:

    if adj_mat[ai][bi] < ci:

        ans += 1

        

print(ans)
import numpy as np
from scipy.sparse.csgraph import floyd_warshall as fw
import sys

sdin = sys.stdin.readline
n, m = list(map(int, sdin().split()))
INF = float("inf")
adj_mat = INF * np.ones((n, n))
for _ in range(m):
    a, b, c = list(map(int, sdin().split()))
    a -= 1
    b -= 1
    adj_mat[a, b] = c
    adj_mat[b, a] = c
for i in range(n):
    adj_mat[i, i] = 0
shortest = fw(adj_mat)
ans = 0
for i in range(n):
    for j in range(i + 1, n):
        if adj_mat[i][j] != INF and adj_mat[i][j] > shortest[i][j]:
            ans += 1
print(ans)

import sys

stdin = sys.stdin
sys.setrecursionlimit(10**5)


def li():
    return list(map(int, stdin.readline().split()))


def li_():
    return [int(x) - 1 for x in stdin.readline().split()]


def lf():
    return list(map(float, stdin.readline().split()))


def ls():
    return stdin.readline().split()


def ns():
    return stdin.readline().rstrip()


def lc():
    return list(ns())


def ni():
    return int(stdin.readline())


def nf():
    return float(stdin.readline())


from heapq import heappush, heappop


def dijkstra(graph: list, node: int, start: int) -> list:
    # 未探索のノードは距離INF
    INF = float("inf")
    dist = [INF] * node
    # 始点ノードの距離を0とし、dfsのためのpriority queを作成
    dist[start] = 0
    heap = [(0, start)]
    # 未探索のノードをpriority queueに入れる
    while heap:
        cost, cur_node = heappop(heap)
        for nex_cost, nex_node in graph[cur_node]:
            dist_cand = dist[cur_node] + nex_cost
            if dist_cand < dist[nex_node]:
                dist[nex_node] = dist_cand
                heappush(heap, (dist[nex_node], nex_node))
    return dist


n, m = li()
edges = []
graph = [[] for _ in range(n)]
adj_mat = [[0] * n for _ in range(n)]
for _ in range(m):
    a, b, c = li()
    a -= 1
    b -= 1
    graph[a].append((c, b))
    graph[b].append((c, a))
    edges.append((a, b, c))
# 各点からの最短dist
for i in range(n):
    adj_mat[i] = dijkstra(graph, n, i)
# 最短路とedgeの比較
ans = 0
for ai, bi, ci in edges:
    if adj_mat[ai][bi] < ci:
        ans += 1
print(ans)

-import numpy as np -from scipy.sparse.csgraph import floyd_warshall as fw -sdin = sys.stdin.readline -n, m = list(map(int, sdin().split())) -INF = float("inf") -adj_mat = INF * np.ones((n, n)) +stdin = sys.stdin +sys.setrecursionlimit(10**5) + + +def li(): +    return list(map(int, stdin.readline().split())) + + +def li_(): +    return [int(x) - 1 for x in stdin.readline().split()] + + +def lf(): +    return list(map(float, stdin.readline().split())) + + +def ls(): +    return stdin.readline().split() + + +def ns(): +    return stdin.readline().rstrip() + + +def lc(): +    return list(ns()) + + +def ni(): +    return int(stdin.readline()) + + +def nf(): +    return float(stdin.readline()) + + +from heapq import heappush, heappop + + +def dijkstra(graph: list, node: int, start: int) -> list: +    # 未探索のノードは距離INF +    INF = float("inf") +    dist = [INF] * node +    # 始点ノードの距離を0とし、dfsのためのpriority queを作成 +    dist[start] = 0 +    heap = [(0, start)] +    # 未探索のノードをpriority queueに入れる +    while heap: +        cost, cur_node = heappop(heap) +        for nex_cost, nex_node in graph[cur_node]: +            dist_cand = dist[cur_node] + nex_cost +            if dist_cand < dist[nex_node]: +                dist[nex_node] = dist_cand +                heappush(heap, (dist[nex_node], nex_node)) +    return dist + + +n, m = li() +edges = [] +graph = [[] for _ in range(n)] +adj_mat = [[0] * n for _ in range(n)] -    a, b, c = list(map(int, sdin().split())) +    a, b, c = li() -    adj_mat[a, b] = c -    adj_mat[b, a] = c +    graph[a].append((c, b)) +    graph[b].append((c, a)) +    edges.append((a, b, c)) +# 各点からの最短dist -    adj_mat[i, i] = 0 -shortest = fw(adj_mat) +    adj_mat[i] = dijkstra(graph, n, i) +# 最短路とedgeの比較 -for i in range(n): -    for j in range(i + 1, n): -        if adj_mat[i][j] != INF and adj_mat[i][j] > shortest[i][j]: -            ans += 1 +for ai, bi, ci in edges: +    if adj_mat[ai][bi] < ci: +        ans += 1