/* 
	Author: ankrypt
*/

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;
template<class T> using oset=tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define MOD 1000000007
#define ll long long int
#define u64 unsigned long long int
#define ff first
#define ss second
#define all(x) x.begin(), x.end() 
#define ub upper_bound
#define lb lower_bound
#define MAX_INT 1005
#define PI 3.141592653589793
#define trace1(x)                cerr<<#x<<": "<<x<<endl
#define trace2(x, y)             cerr<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x, y, z)          cerr<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a, b, c, d)       cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define trace5(a, b, c, d, e)    cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define trace6(a, b, c, d, e, f) cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl
#define go ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define fi(a, b, c, d) for(int a = b; a < c; a += d)
#define fl(a, b, c, d) for(ll a = b; a < c; a += d)
#define fei(a, b, c, d) for(int a = b; a <= c; a += d)
#define fel(a, b, c, d) for(ll a = b; a <= c; a += d)
#define quit exit(0)
#define mem(x, a) memset(x, a, sizeof x)
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pcl pair<char, ll>
#define psl pair<string, ll>


ll N, M, A, B, C;
ll arr[MAX_INT], arr1[MAX_INT], data[MAX_INT];
vector<pll> adj[MAX_INT];
map<pll, ll> mp;
std::vector<pair<pll, ll>> V;
set<ll> s;
ll vis[MAX_INT][MAX_INT];
string S = "";
ll cases;
ll dist[MAX_INT][MAX_INT];

void bfs(int node) {
	queue<pll> q;
	while(!q.empty()) {
		q.pop();
	}
	q.push({node, 0ll});
	dist[node][node] = 1;
	while(!q.empty()) {
		ll temp = q.front().ff;
		dist[node][temp] = q.front().ss;
		q.pop();
		fi(i, 0, adj[temp].size(), 1) {
			if(!vis[node][adj[temp][i].ff]) {
				vis[node][adj[temp][i].ff] = 1;
				q.push({adj[temp][i].ff, dist[node][temp] + 1});
			}
		}
	}
}

int main() {
	go;
    cin >> N >> M;
    fi(i, 0, M, 1) {
    	cin >> A >> B >> C;
   		A--;
   		B--;
   		adj[A].push_back({B, C});
   		adj[B].push_back({A, C});
   		V.push_back({{A, B}, C});
   		// mp[{{A, B}, C}] = 1;
    }
    fi(i, 0, N, 1) {
    	bfs(i);
    }
    ll cnt = 0;
    fi(i, 0, M, 1) {
    	if(dist[V[i].ff.ff][V[i].ff.ss] < V[i].ss) {
    		cnt++;
    	}
    }
    cout << cnt << "\n";
	return 0;
}
/*
	Powered by Buggy Plugin
*/


