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

bool[100] USED_NODE;
bool[1000] USED_PATH;
int[2][1000][1000] PATH;

void main()
{
    auto nm = readln.split.to!(int[]);
    auto n = nm[0];
    auto m = nm[1];

    foreach (i; 0..m) {
        auto abc = readln.split.to!(int[]);
        auto a = abc[0] - 1;
        auto b = abc[1] - 1;
        auto c = abc[2];
        PATH[a][b][0] = i;
        PATH[a][b][1] = c;
        PATH[b][a][0] = i;
        PATH[b][a][1] = c;
    }

    foreach (x; 0..n) {
        auto p = x;
        USED_NODE = false;
        int node_cnt;
        long[3][] nexts;
        long len;
        for (;;) {
            auto min = long.max;
            int next = -1;
            int use_path = -1;

            foreach (path; nexts) {
                if (path[1] < min) {
                    min = path[1];
                    next = path[0].to!int;
                    use_path = path[2].to!int;
                }
            }

            if (!USED_NODE[p]) {
                foreach (i, path; PATH[p]) {
                    if (!path[1]) continue;
                    auto t_len = path[1] + len;
                    nexts ~= [i, t_len, path[0]];
                    if (t_len < min) {
                        min = t_len;
                        use_path = path[0];
                        next = i.to!int;
                    }
                }
                USED_NODE[p] = true;
                if (++node_cnt == n) break;
            }

            foreach (i, path; nexts)
                if (path[1] == min) {
                    nexts = nexts.length == i + 1 ? nexts[0..i] : nexts[0..i] ~ nexts[i+1..$];
                    break;
                }

            if (use_path != -1 && !USED_PATH[use_path])
                USED_PATH[use_path] = true;

            len = min;
            p = next;

        }
    }

    writeln(USED_PATH[0..m].count!"!a");
}