#include <bits/stdc++.h>
using namespace std;
const long long INF = 1000000000000;
long long pre[345678];
long long cost[3456][3456];
long long d[345678];
bool used[345678];
void dijkstra(long long V, long long s) {
  fill(d, d + V + 1, INF);
  fill(used, used + V + 1, false);
  fill(pre, pre + V + 1, -1);
  d[s] = 0;
  while (true) {
    long long v = -1;
    for (long long u = 1; u <= V; u++) {
      if (!used[u] && (v == -1 || d[u] < d[v])) v = u;
    }
    if (v == -1) break;
    used[v] = true;
    for (long long u = 1; u <= V; u++) {
      if (d[u] > d[v] + cost[v][u]) {
        d[u] = d[v] + cost[v][u];
        pre[u] = v;
      }
    }
  }
}
vector<long long> get_path(long long t) {
  vector<long long> path;
  for (; t != -1; t = pre[t]) path.push_back(t);
  reverse(path.begin(), path.end());
  return path;
}
long long cnt[3456][3456], test[345678][2];
signed main() {
  long long n, m, a, b, c, ans = 0;
  cin >> n >> m;
  for (long long h = 0; h < m; h++) {
    cin >> a >> b >> c;
    test[h][0] = a;
    test[h][1] = b;
    cost[a][b] = c;
    cost[b][a] = c;
  }
  for (long long h = 1; h < n; h++) {
    for (long long i = h + 1; i <= n; i++) {
      dijkstra(n, h);
      for (long long j = 1; j < get_path(i).size(); j++) {
        cnt[get_path(i)[j - 1]][get_path(i)[j]] = 1;
        cnt[get_path(i)[j]][get_path(i)[j - 1]] = 1;
      }
    }
  }
  for (long long h = 0; h < m; h++) {
    if (cnt[test[h][0]][test[h][1]] == 0) ans++;
  }
  cout << ans << endl;
  return 0;
}
