#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string>
#include <cmath>
#include <vector>
#include <functional>
#include <stack>
#include <utility>
#include <map>
#include <queue>
#include <set>
#include <array>
#include <climits>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

const ll MOD = 1000000000 + 7;
const ll INF = 99999999;
const ll MAX_V = 105;
const double EPS = 10e-6;
const double PI = 3.14159265359;

ll dx[] = { 1,0,-1,0 }, dy[] = { 0,1,0,-1 };
//int d[] = {0,1,0,-1};
//int nx = x + d[i];
//int ny = y + d[(i+1)%4]




struct edge { int from, to, cost; bool used = false; }; //辺の始点、終点、重み

vector<edge> es; //辺

int d[MAX_V]; //最短距離
int V, E; //Vは頂点数、Eは辺数

		  //S番目の頂点から各頂点への最短経路を求める
void shortest_path(int s, int no) {
	for (int i = 0; i<V; i++)d[i] = INF;
	d[s] = 0;
	while (true) {
		bool update = false;
		for (int i = 0; i<es.size(); i++) {
			if (i == no)continue;
			edge e = es[i];
			if (d[e.from] != INF && d[e.to] > d[e.from] + e.cost) {
				d[e.to] = d[e.from] + e.cost;
				update = true;
			}
		}
		if (!update)break;
	}
}
int main() {
	int cnt = 0;
	cin >> V >> E;
	for (int i = 0; i < E; i++) {
		int a, b, c;
		cin >> a >> b >> c;
		a--; b--;
		es.push_back({ a,b,c });
		es.push_back({ b,a,c });
	}
	for (int i = 0; i < V; i++) {
		shortest_path(i, 999);
		int d1[105];
		for (int j = 0; j < V; j++)d1[j] = d[j];
		for (int j = 0; j < E*2; j++) {
			if (es[j].used)continue;
			shortest_path(i, j);
			for (int k = 0; k < V; k++) {
				if (d1[k] != d[k]) {
					es[j].used = true;
					if (j % 2 == 0)es[j + 1].used = true;
					else es[j - 1].used = true;
					cnt++;
					break;
				}
			}
		}

	}
	cout << E - cnt << endl;
	return 0;
}