#include <bits/stdc++.h>
const int INF = 1e9;
const int MOD = 1e9 + 7;
const long long LINF = 1e18;
using namespace std;
typedef struct DP {
  int dist;
  int from;
  bool sure;
} DP;
int main(int argc, char const* argv[]) {
  int n, m;
  cin >> n >> m;
  int G[n][n];
  bool E[n][n];
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (n); ++j) G[i][j] = INF;
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (n); ++j) E[i][j] = false;
  for (int i = 0; i < (m); ++i) {
    int a, b, c;
    cin >> a >> b >> c;
    G[a - 1][b - 1] = G[b - 1][a - 1] = c;
  }
  for (int I = 0; I < n; ++I) {
    DP dp[n];
    for (int i = 0; i < (n); ++i) {
      dp[i].dist = INF;
      dp[i].from = INF;
      dp[i].sure = false;
    }
    priority_queue<pair<int, int>, vector<pair<int, int>>,
                   greater<pair<int, int>>>
        pq;
    pair<int, int> p = pair<int, int>(0, I);
    pq.push(p);
    dp[I].dist = 0;
    dp[I].from = I;
    dp[I].sure = true;
    while (!pq.empty()) {
      pair<int, int> now = pq.top();
      int v = now.second;
      dp[v].sure = true;
      pq.pop();
      for (int i = 0; i < (n); ++i) {
        if (G[v][i] != INF && dp[i].sure == false) {
          if (dp[v].dist + G[v][i] <= dp[i].dist) {
            dp[i].dist = dp[v].dist + G[v][i];
            dp[i].from = v;
          } else
            dp[i].dist = dp[i].dist;
          pair<int, int> temp = pair<int, int>(dp[i].dist, i);
          pq.push(temp);
        }
      }
    }
    for (int i = 0; i < (n); ++i)
      if (i != dp[i].from) E[dp[i].from][i] = E[i][dp[i].from] = true;
  }
  int c = 0;
  for (int i = 0; i < (n); ++i) {
    for (int j = 0; j < (n); ++j) {
      if (E[i][j]) c++;
    }
  }
  int ans = m - (c / 2);
  cout << ans << std::endl;
  return 0;
}
