#include <iostream>
#include<cstdlib>
#include<queue>
#include<set>
#include<vector>
#include<string>
#include<algorithm>
#include<stack>
#include<map>
#include<deque>
#include<cstdio>
using namespace std;
#define rep(i,a) for(int i=0;i<a;i++)
#define mp make_pair
#define pb push_back
#define ll __int64
//#define __int64 long long
#define P pair<ll,ll>
string s;

int n,m;
vector<P>G[1000];
bool ok[100][100];
int dist[100];
const int INF=100000000;

void daiku(int from,int to){
	priority_queue<P,vector<P>,greater<P>()>bfs;
	bfs.push(mp(0,from));
	rep(i,n)dist[i]=INF;

	while(!bfs.empty()){
		P t=bfs.top();
		bfs.pop();
		int next=t.second,cost=t.first;
		if(dist[next]!=INF)continue;
		dist[next]=cost;
		rep(i,G[next].size()){
			bfs.push(mp(cost+G[next][i].second,G[next][i].first));
		}
	}
	//cout<<from<<" "<<to<<" "<<dist[to]<<endl;
	int now=to;

	rep(co,n){
		if(now==from)break;
		rep(i,G[now].size()){
			int next=G[now][i].first,cost=G[now][i].second;
			if(dist[next]+cost==dist[now]){
				ok[now][next]=ok[next][now]=1;
				//cout<<now<<" "<<next<<endl;
				now=next;

			}
		}
	}
	//cout<<"B"<<endl;
}

int main(){
	cin>>n>>m;	
	int a,b,c;
	rep(i,m){
		cin>>a>>b>>c;
		a--;b--;
		G[a].pb(mp(b,c));
		G[b].pb(mp(a,c));
	}
	for(int i=0;i<n;i++){
		for(int j=i+1;j<n;j++){
			daiku(i,j);
		}
	}
	int ans=0;
	rep(i,n){
		rep(j,G[i].size())if(!ok[i][G[i][j].first])ans++;
	}
	if(ans>0)ans/=2;
	cout<<ans<<endl;
}