#include <bits/stdc++.h>
using namespace std;
int main() {
  int n, m;
  cin >> n >> m;
  struct edge {
    int a, b, c;
  };
  vector<edge> edges(m);
  for (int i = 0; i < m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    edges[i] = {a - 1, b - 1, c};
  }
  const int max_dist = 1000 * 1000 + 1;
  vector<vector<pair<int, int>>> dp(n,
                                    vector<pair<int, int>>(n, {max_dist, -1}));
  for (auto e : edges) {
    dp[e.a][e.b] = {e.c, e.a};
    dp[e.b][e.a] = {e.c, e.b};
  }
  for (int i = 0; i < n; i++) {
    dp[i][i] = {0, -1};
  }
  for (int k = 0; k < n; k++) {
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < n; j++) {
        if (dp[i][j].first > dp[i][k].first + dp[k][j].first) {
          dp[i][j].first = dp[i][k].first + dp[k][j].first;
          dp[i][j].second = k;
        }
      }
    }
  }
  vector<pair<int, int>> result;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (dp[i][j].second != -1) {
        if (dp[i][j].second == i) {
          int start = min(i, j);
          int end = max(i, j);
          result.push_back({start, end});
        } else {
          int start = min(i, dp[i][j].second);
          int end = max(i, dp[i][j].second);
          result.push_back({start, end});
          start = min(j, dp[i][j].second);
          end = max(j, dp[i][j].second);
          result.push_back({start, end});
        }
      }
    }
  }
  sort(result.begin(), result.end());
  auto itr = unique(result.begin(), result.end());
  result.erase(itr, result.end());
  cout << m - result.size() << endl;
  return 0;
}
