using System;
﻿﻿﻿﻿﻿using System.Collections.Generic;
﻿﻿﻿﻿﻿using System.Globalization;
﻿﻿﻿﻿﻿using System.IO;
﻿﻿﻿﻿﻿using System.Linq;

namespace CF317
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var sr = new InputReader(Console.In);
            //var sr = new InputReader(new StreamReader("input.txt"));
            var task = new Task();
            using (var sw = Console.Out)
            //using (var sw = new StreamWriter("output.txt"))
            {
                task.Solve(sr, sw);
                //Console.ReadKey();
            }
        }
    }

    internal class Task
    {
        public void Solve(InputReader sr, TextWriter sw)
        {
            var input = sr.ReadArray(Int32.Parse);
            var n = input[0];
            var m = input[1];
            var graph = new Graph(n);
            for (var i = 0; i < m; i++) {
                input = sr.ReadArray(Int32.Parse);
                graph.Insert(input[0] - 1, input[1] - 1, input[2]);
            }

            sw.Write(graph.AllPairsShortestPath());
        }
    }

    class Graph
    {
        private int[,] matrix;
        private readonly int n;

        public Graph(int n)
        {
            matrix = new int[n, n];
            this.n = n;
        }

        public void Insert(int x, int y, int c)
        {
            matrix[x, y] = c;
            matrix[y, x] = c;
        }

        public int AllPairsShortestPath()
        {
            const long Max = (long) 1e15;
            var distances = new long[n, n];
            var parents = new int[n, n];
            for (var i = 0; i < n; i++)
            {
                for (var j = 0; j < n; j++)
                {
                    parents[i, j] = -1;
                }
            }
            for (var i = 0; i < n; i++) {
                for (var j = 0; j < n; j++) {
                    if (i == j) {
                        distances[i, j] = 0;
                    }
                    else {
                        if (matrix[i, j] == 0) {
                            distances[i, j] = Max;
                        }
                        else {
                            distances[i, j] = matrix[i, j];
                        }
                    }
                }
            }
            for (var k = 0; k < n; k++) {
                for (var i = 0; i < n; i++) {
                    for (var j = 0; j < n; j++) {
                        if (distances[i, j] > distances[i, k] + distances[k, j]) {
                            distances[i, j] = distances[i, k] + distances[k, j];
                            parents[i, j] = k;
                        }
                    }
                }
            }
            var inPaths = new bool[n, n];
            for (var i = 0; i < n; i++) {
                for (var j = 0; j < n; j++) {
                    if (i == j) {
                        inPaths[i, j] = true;
                    }
                }
            }
            var processed = new bool[n, n];
            for (var i = 0; i < n; i++) {
                for (var j = 0; j < n; j++) {
                    if (!processed[i, j]) {
                        Parents(parents, i, j, inPaths);
                    }
                    processed[i, j] = true;
                    processed[j, i] = true;
                }
            }
            var count = 0;
            for (var i = 0; i < n; i++) {
                for (var j = 0; j < n; j++) {
                    if (matrix[i, j] != 0) {
                        if (!inPaths[i, j]) {
                            count++;
                        }
                    }
                    inPaths[j, i] = true;
                }
            }

            return count;
        }

        private void Parents(int[,] parents, int x, int y, bool[,] inPaths)
        {
            var p = parents[x, y];
            if (p == -1) {
                inPaths[x, y] = true;
                inPaths[y, x] = true;
            }
            else {
                Parents(parents, x, p, inPaths);
                Parents(parents, p, y, inPaths);
            }
        }
    }
}

internal class InputReader : IDisposable
{
    private bool isDispose;
    private readonly TextReader sr;

    public InputReader(TextReader stream)
    {
        sr = stream;
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    public string NextString()
    {
        var result = sr.ReadLine();
        return result;
    }

    public int NextInt32()
    {
        return Int32.Parse(NextString());
    }

    public long NextInt64()
    {
        return Int64.Parse(NextString());
    }

    public string[] NextSplitStrings()
    {
        return NextString()
            .Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public T[] ReadArray<T>(Func<string, CultureInfo, T> func)
    {
        return NextSplitStrings()
            .Select(s => func(s, CultureInfo.InvariantCulture))
            .ToArray();
    }

    public T[] ReadArrayFromString<T>(Func<string, CultureInfo, T> func, string str)
    {
        return
            str.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(s => func(s, CultureInfo.InvariantCulture))
                .ToArray();
    }

    protected void Dispose(bool dispose)
    {
        if (!isDispose)
        {
            if (dispose)
                sr.Close();
            isDispose = true;
        }
    }

    ~InputReader()
    {
        Dispose(false);
    }
}

Measured memory_bytes: 3672