#include <bits/stdc++.h>
using namespace std;
const long inf = 1e7;
struct dat {
  long at, cost, from;
  dat() { at = cost = from = -1; }
  dat(long a, long b, long c) : at(a), cost(b), from(c) {}
};
signed main() {
  long n, m;
  cin >> n >> m;
  vector<vector<long>> G(n, vector<long>(n, inf));
  vector<vector<bool>> H(n, vector<bool>(n, false));
  for (long i = 0; i < m; ++i) {
    long a, b, c;
    cin >> a >> b >> c;
    --a;
    --b;
    G[a][b] = G[b][a] = c;
  }
  auto f = [](dat a, dat b) { return a.cost > b.cost; };
  for (long src = 0; src < n; ++src) {
    priority_queue<dat, vector<dat>, decltype(f)> que(f);
    vector<bool> vis(n, false);
    que.push(dat(src, 0, -1));
    for (long vsn = 0; vsn < n; ++vsn) {
      dat q = que.top();
      que.pop();
      if (vis[q.at]) continue;
      vis[q.at] = true;
      if (q.from != -1) {
        H[q.at][q.from] = H[q.from][q.at] = true;
      }
      for (long i = 0; i < n; ++i) {
        if (vis[i]) continue;
        if (G[q.at][i] < inf) que.push(dat(i, G[q.at][i] + q.cost, q.at));
      }
    }
  }
  long r = 0;
  for (long i = 0; i < n - 1; ++i)
    for (long j = i + 1; j < n; ++j)
      if (H[i][j]) ++r;
  assert(m - r >= 0);
  cout << m - r;
}
