#include <bits/stdc++.h>
using namespace std;
string YN(bool y) { return (y ? "YES" : "NO"); }
string yn(bool y) { return (y ? "Yes" : "No"); }
string ON(bool y) { return (y ? "OK" : "NG"); }
vector<vector<long long>> cost;
vector<int> Dijkstra(int start, int n) {
  vector<int> dist(n, 1e9);
  vector<bool> used(n, true);
  vector<int> prev(n, 1e9);
  dist[start] = 0;
  for (int i = 0; i < n; i++) {
    int min = 1e9 + 1, min_j;
    for (int j = 0; j < n; j++) {
      if (min > dist[j] && used[j]) {
        min = dist[j];
        min_j = j;
      }
    }
    used[min_j] = false;
    for (int j = 0; j < n; j++) {
      if (dist[j] > dist[min_j] + cost[min_j][j] && used[j]) {
        dist[j] = dist[min_j] + cost[min_j][j];
        prev[j] = min_j;
      }
    }
  }
  return prev;
}
int main(void) {
  long long n, m;
  cin >> n >> m;
  cost = vector<vector<long long>>(n, vector<long long>(n, 1e18));
  vector<vector<bool>> flag(n, vector<bool>(n, true));
  vector<int> prev;
  for (long long i = (long long)(0); i < (long long)(m); i++) {
    long long a, b, c;
    cin >> a >> b >> c;
    cost[a - 1][b - 1] = c;
    cost[b - 1][a - 1] = c;
    flag[a - 1][b - 1] = false;
    flag[b - 1][a - 1] = false;
  }
  for (long long i = (long long)(0); i < (long long)(n); i++) {
    prev = Dijkstra(i, n);
    for (long long i = (long long)(0); i < (long long)(n); i++) {
      flag[i][prev[i]] = true;
      flag[prev[i]][i] = true;
    }
  }
  long long ans = 0;
  for (long long i = (long long)(0); i < (long long)(n); i++) {
    for (long long j = (long long)(i + 1); j < (long long)(n); j++) {
      if (!flag[i][j]) ans++;
    }
  }
  cout << ans << endl;
}
