Problem:
Score : 400 points

Problem Statement

You are given an undirected connected weighted graph with N vertices and M edges that contains neither self-loops nor double edges.

The i-th (1≤i≤M) edge connects vertex a_i and vertex b_i with a distance of c_i.

Here, a self-loop is an edge where a_i = b_i (1≤i≤M), and double edges are two edges where (a_i,b_i)=(a_j,b_j) or (a_i,b_i)=(b_j,a_j) (1≤i<j≤M).

A connected graph is a graph where there is a path between every pair of different vertices.

Find the number of the edges that are not contained in any shortest path between any pair of different vertices.

Constraints

2≤N≤100

N-1≤M≤min(N(N-1)/2,1000)

1≤a_i,b_i≤N

1≤c_i≤1000

c_i is an integer.

The given graph contains neither self-loops nor double edges.

The given graph is connected.

Input

The input is given from Standard Input in the following format:

N M
a_1 b_1 c_1
a_2 b_2 c_2
:
a_M b_M c_M

Output

Print the number of the edges in the graph that are not contained in any shortest path between any pair of different vertices.

Sample Input 1

3 3
1 2 1
1 3 1
2 3 3

Sample Output 1

1

In the given graph, the shortest paths between all pairs of different vertices are as follows:

The shortest path from vertex 1 to vertex 2 is: vertex 1 → vertex 2, with the length of 1.

The shortest path from vertex 1 to vertex 3 is: vertex 1 → vertex 3, with the length of 1.

The shortest path from vertex 2 to vertex 1 is: vertex 2 → vertex 1, with the length of 1.

The shortest path from vertex 2 to vertex 3 is: vertex 2 → vertex 1 → vertex 3, with the length of 2.

The shortest path from vertex 3 to vertex 1 is: vertex 3 → vertex 1, with the length of 1.

The shortest path from vertex 3 to vertex 2 is: vertex 3 → vertex 1 → vertex 2, with the length of 2.

Thus, the only edge that is not contained in any shortest path, is the edge of length 3 connecting vertex 2 and vertex 3, hence the output should be 1.

Sample Input 2

3 2
1 2 1
2 3 1

Sample Output 2

0

Every edge is contained in some shortest path between some pair of different vertices.

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;

class Program
{
    public void Proc()
    {
        Reader.IsDebug = false;
        int[] inpt = Reader.ReadLine().Split(' ').Select(a => int.Parse(a)).ToArray();
        int posCount = inpt[0];
        int roadCount = inpt[1];

        for (int i = 0; i < roadCount; i++)
        {
            inpt = Reader.ReadLine().Split(' ').Select(a => int.Parse(a)).ToArray();
            Road r = new Road(inpt[0], inpt[1], inpt[2]);
            if (!this.RoadDic.ContainsKey(r.Pos1))
            {
                this.RoadDic.Add(r.Pos1, new Dictionary<int, Road>());
            }
            this.RoadDic[r.Pos1].Add(r.Pos2, r);
            if (!this.RoadDic.ContainsKey(r.Pos2))
            {
                this.RoadDic.Add(r.Pos2, new Dictionary<int, Road>());
            }
            this.RoadDic[r.Pos2].Add(r.Pos1, r);
            this.RoadList.Add(r);
        }

        Queue<Task> que = new Queue<Task>();
        for (int i = 1; i <= posCount; i++)
        {
            Map.Add(i, new Dictionary<int, MapState>());
            Map[i].Add(i, new MapState(i, null, 0));
            que.Enqueue(new Task(i, i));
        }

        while (que.Count > 0)
        {
            Task t = que.Dequeue();
            int currentCost = this.Map[t.Pos][t.From].TotalCost;

            foreach (int nextPos in this.RoadDic[t.Pos].Keys)
            {
                if (nextPos == t.From)
                {
                    continue;
                }
                int nextCost = currentCost + this.RoadDic[t.Pos][nextPos].Cost;
                if (Map[nextPos].ContainsKey(t.From))
                {
                    if (Map[nextPos][t.From].TotalCost <= nextCost)
                    {
                        continue;
                    }
                }
                Map[nextPos][t.From] = new MapState(t.From, this.RoadDic[t.Pos][nextPos], nextCost);
                Task newT = new Task(nextPos, t.From);
                que.Enqueue(newT);
               
            }            
        }

        for (int i = 1; i <= posCount; i++)
        {
            foreach (int key in this.Map[i].Keys)
            {
                if (i == key)
                {
                    continue;
                }
                this.Map[i][key].Prev.Flag = true;
            }
        }

        Console.WriteLine(this.RoadList.Count(a => a.Flag == false));

    }

    private class Task
    {
        public int Pos;
        public int From;
        public Task(int pos, int from)
        {
            this.Pos = pos;
            this.From = from;
        }
    }

    private List<Road> RoadList = new List<Road>();
    private Dictionary<int, Dictionary<int, Road>> RoadDic = new Dictionary<int, Dictionary<int, Road>>();
    private Dictionary<int, Dictionary<int, MapState>> Map = new Dictionary<int, Dictionary<int, MapState>>();

    private class MapState
    {
        public int FromID;
        public Road Prev;
        public int TotalCost;
        public MapState(int from, Road prev, int total)
        {
            this.FromID = from;
            this.Prev = prev;
            this.TotalCost = total;
        }
    }

    private class Road {
        public int Pos1;
        public int Pos2;
        public int Cost;
        public bool Flag = false;
        public Road(int pos1, int pos2, int cost)
        {
            this.Pos1 = pos1;
            this.Pos2 = pos2;
            this.Cost = cost;
        }
    }

    public class Reader
    {
        public static bool IsDebug = true;
        private static String PlainInput = @"




3 2
1 2 1
2 3 1



";
        private static System.IO.StringReader Sr = null;
        public static string ReadLine()
        {
            if (IsDebug)
            {
                if (Sr == null)
                {
                    Sr = new System.IO.StringReader(PlainInput.Trim());
                }
                return Sr.ReadLine();
            }
            else
            {
                return Console.ReadLine();
            }
        }
    }
    static void Main()
    {
        Program prg = new Program();
        prg.Proc();
    }
}