import std.stdio, std.string, std.conv, std.algorithm;

void main() {
    auto S = readln.split.to!(ulong[]);
    auto N = S[0], M = S[1];
    auto dist = new ulong[][](N, N);
    foreach (i; 0..N) {
        foreach (j; i+1..N) {
            dist[i][j] = 1000000000;
        }
        dist[i][i] = 0;
    }
    auto edges = new ulong[][M];
    foreach (i; 0..M) {
        auto edge = readln.split.to!(ulong[]);
        if (edge[0] > edge[1]) swap(edge[0], edge[1]);
        edge[0]--;
        edge[1]--;
        dist[edge[0]][edge[1]] = edge[2];
        edges[i] = edge;
    }

    alias getDist = (i, j) => dist[min(i,j)][max(i,j)];
    foreach (i; 0..N) {
        foreach (j; 0..N) {
            foreach (k; j+1..N) {
                dist[j][k] = min(dist[j][k], getDist(j, i) + getDist(i, k));
            }
        }
    }
    auto cnt = 0;
    foreach (edge; edges) {
        foreach (i; 0..N) {
            if (i == edge[0]) continue;
            if (i == edge[1]) continue;
            if (getDist(i, edge[0]) == getDist(i, edge[1]) + getDist(edge[0], edge[1])) {
                cnt++;
                break;
            }
            if (getDist(i, edge[1]) == getDist(i, edge[0]) + getDist(edge[0], edge[1])) {
                cnt++;
                break;
            }
        }
    }
    writeln(M-cnt);
}