#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const ll MOD = 110;

const ll MAX_N = 100010;
const ll INF = 1e12;

vector<pair<ll, ll> > g[MAX_N]; // firstに最短距離, secondに頂点番号
ll d[MAX_N];
int n; // 頂点数

bool used[MAX_N][MAX_N];

int pr[MAX_N]; // 最短路の直前の頂点

// bellman ford法で負辺がない場合。計算量はO(|E|log|V|)
void dijkstra(int s){
  priority_queue<pair<ll, ll>, vector<pair<ll, ll> >, greater<pair<ll, ll> > > PQ;
  for(int i=1;i<=n;i++) d[i] = INF;
  for(int i=1;i<=n;i++) pr[i] = -1;
  d[s] = 0;
  PQ.push(make_pair(0, s));

  while(!PQ.empty()){
    pair<ll, ll> p = PQ.top(); PQ.pop();
    int v = p.second;
    if(d[v] < p.first) continue;
    for(auto gvi: g[v]){
      ll cost = gvi.first;
      int u = gvi.second;
      if(d[u] > d[v] + cost){
        d[u] = d[v] + cost;
        PQ.push(make_pair(d[u], u));
        pr[u] = v;
      }
    }
  }
}

// 頂点tへの最短路
void get_path(int t){
  for(;t!=-1;t=pr[t]){
    used[t][pr[t]] = true;
    used[pr[t]][t] = true;
  }
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);
  int m; cin >> n >> m;
  for(int i=1;i<=n;i++){
    for(int j=1;j<=n;j++){
      used[i][j] = true;
    }
  }
  for(int i=0;i<m;i++){
    ll a, b, c; cin >> a >> b >> c;
    g[a].push_back(make_pair(c, b));
    g[b].push_back(make_pair(c, a));
    used[a][b] = false;
    used[b][a] = false;
  }
  for(int i=1;i<=n;i++){
    dijkstra(i);
    for(int j=i+1;j<=n;j++){
      // cout << i << " " << j << " " << d[j] << endl;
      get_path(j);
    }
  }
  int cnt = 0;
  for(int i=1;i<=n;i++){
    for(int j=i+1;j<=n;j++){
      if(used[i][j] == false) cnt++;
    }
  }
  cout << cnt << endl;
}