#include <bits/stdc++.h>
using namespace std;
const double EPS = 1e-10;
const double PI = acos(-1.0);
const int MOD = 1000000007;
struct edge {
  int from, to;
  long long cost;
  bool operator<(const edge& e) const {
    return (this->to < e.to or this->from < e.from);
  }
};
int main(int argc, char const* argv[]) {
  long long n, m;
  cin >> n >> m;
  vector<vector<long long> > dp(n, vector<long long>(n, INT32_MAX));
  vector<edge> edges;
  set<edge> used;
  for (int i = 0; i < n; i++) {
    dp[i][i] = 0;
  }
  for (int i = 0; i < m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    a--, b--;
    edges.push_back(edge{a, b, c});
    dp[a][b] = c;
    dp[b][a] = c;
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      for (int k = 0; k < n; k++) {
        dp[j][k] = min(dp[j][k], dp[j][i] + dp[i][k]);
      }
    }
  }
  for (int s = 0; s < n; s++) {
    for (int g = s + 1; g < n; g++) {
      for (auto&& e : edges) {
        if (dp[s][e.from] + e.cost + dp[e.to][g] == dp[s][g]) {
          used.insert(e);
        }
      }
    }
  }
  cout << m - used.size() << endl;
  return 0;
}
