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++14 (GCC 5.4.1) (judge verdict: Accepted)

#pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;i++)
#define cinf(n,x) for(int i=0;i<(n);i++)cin>>x[i];
#define max3(a,b,c) max(max(a,b),c)
#define min3(a,b,c) min(min(a,b),c)
#define ft first
#define sc second
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define all(v) (v).begin(),(v).end()
#define mod 1000000007
using namespace std;
typedef long long ll;
template<class T> using V=vector<T>;
using Graph = vector<vector<int>>;
using P=pair<ll,ll>;
typedef unsigned long long ull;
typedef long double ldouble;
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
//V,P(大文字)使用不可

const ll INF=1000000000000000000;

const ll max_V=1000;//大きすぎ注意

struct edge{ll to,cost;};

ll N;//頂点数
ll M;
ll cst[max_V][max_V];
vector<edge> G[max_V];
//bool used[max_V];
//ll d[max_V];//頂点sからの最短距離

//ll pr[max_V];

void dijkstra(ll s,V<ll> &d,V<ll> &pr){
    priority_queue<P,vector<P>,greater<P>> que;
    // fill(d,d+N,INF);
    d[s]=0;
    que.push(P(0,s));//pair...first->最短距離、second->頂点

    while(!que.empty()){
        P p=que.top();que.pop();
        ll v=p.second;
        if(d[v]<p.first) continue;
        for(int i=0;i<G[v].size();i++){
            edge e=G[v][i];
            if(d[e.to]>d[v]+e.cost){
                d[e.to]=d[v]+e.cost;
                que.push(P(d[e.to],e.to));
                pr[e.to]=v;
            }
        }
    }
}

void dijkstra_restore(ll s,V<ll> &d,V<ll> &pr,V<bool> &used){
    // fill(d,d+N,INF);
    // fill(used,used+N,0);
    // fill(pr,pr+N,-1);
    d[s]=0;

    while(true){
        ll v=-1;
        for(int u=0;u<N;u++){
            if(!used[u]&&(v==-1||d[u]<d[v])) v=u;
        }

        if(v==-1) break;
        used[v]=1;

        for(int u=0;u<N;u++){
            if(d[u]>d[v]+cst[v][u]){
                d[u]=d[v]+cst[v][u];
                pr[u]=v;
            }
        }
    }
}

//頂点tへの最短路
vector<ll> get_path(ll t,V<ll> pr){
    vector<ll> path;
    for(;t!=-1;t=pr[t]) path.push_back(t);//tがsになるまでprev[t]をたどっていく
    reverse(all(path));
    return path;
}

signed main(){
    cin>>N>>M;
    set<ll> st;
    map<P,ll> mp;
    rep(i,M){
        ll a,b,c;
        cin>>a>>b>>c;
        a--;b--;
        edge A,B;
        A.to=b;A.cost=c;
        B.to=a;B.cost=c;
        G[a].push_back(A);
        G[b].push_back(B);
        //cst[a][b]=cst[b][a]=c;
        mp[P(a,b)]=mp[P(b,a)]=i;
    }
    for(ll i=0;i<N-1;i++){
        for(ll j=i+1;j<N;j++){
            //if(i==j) continue;
            V<ll> dist(N,INF),pr(N,-1);
            V<bool> used(N,0);
            dijkstra(i,dist,pr);
            V<ll> path=get_path(j,pr);
            ll m=path.size();
            for(int k=0;k<m-1;k++){
                ll v=mp[P(path[k],path[k+1])];
                st.insert(v);
            }
        }
    }
    cout<<M-st.size()<<endl;
}