#include <bits/stdc++.h>
using namespace std;
const int INF = 1 << 30;
struct edge {
  int to, cost;
};
vector<vector<edge>> graph;
vector<int> dist;
void dijkstra(int N, int s) {
  dist = vector<int>(N);
  for (int i = 0; i < N; i++) dist[i] = INF;
  dist[s] = 0;
  priority_queue<pair<int, int>, vector<pair<int, int>>,
                 greater<pair<int, int>>>
      queue;
  queue.push(pair<int, int>(0, s));
  while (!queue.empty()) {
    pair<int, int> p = queue.top();
    queue.pop();
    int node = p.second;
    if (dist[node] < p.first) continue;
    for (int i = 0; i < graph[node].size(); i++) {
      edge e = graph[node][i];
      if (dist[e.to] > dist[node] + e.cost) {
        dist[e.to] = dist[node] + e.cost;
        queue.push(pair<int, int>(dist[e.to], e.to));
      }
    }
  }
}
int main() {
  int N, M;
  cin >> N >> M;
  vector<int> A(N), B(N), C(N);
  for (int i = 0; i < M; i++) {
    cin >> A[i] >> B[i] >> C[i];
    A[i]--;
    B[i]--;
  }
  graph = vector<vector<edge>>(N);
  for (int i = 0; i < M; i++) {
    graph[A[i]].push_back((edge){B[i], C[i]});
    graph[B[i]].push_back((edge){A[i], C[i]});
  }
  vector<vector<int>> dist2d = vector<vector<int>>(N, vector<int>(N));
  for (int i = 0; i < N; i++) {
    dijkstra(N, i);
    dist2d[i] = dist;
  }
  int ans = 0;
  for (int i = 0; i < M; i++) {
    if (C[i] > dist2d[A[i]][B[i]]) {
      ans++;
    }
  }
  cout << ans << endl;
}
