#include <bits/stdc++.h>
struct edge {
  int dst;
  int d;
  int id;
};
std::vector<edge> edges[104];
int main() {
  int N, M;
  scanf("%d", &N);
  scanf("%d", &M);
  int a, b, c;
  for (int i = 0; i < M; i++) {
    scanf("%d", &a);
    scanf("%d", &b);
    scanf("%d", &c);
    a--;
    b--;
    edges[a].push_back((edge){b, c, i});
    edges[b].push_back((edge){a, c, i});
  }
  std::vector<bool> used(M + 4, false);
  for (int i = 0; i < N; i++) {
    std::vector<int> dist(N + 4, -1);
    std::priority_queue<std::pair<int, int> > queue;
    dist[i] = 0;
    queue.push(std::make_pair(0, i));
    while (queue.size() > 0) {
      int v = queue.top().second;
      int d = queue.top().first;
      queue.pop();
      if (dist[v] != -1 && dist[v] < d) continue;
      for (auto &entry : edges[v]) {
        int vv = entry.dst;
        int dd = entry.d;
        if (dist[vv] == -1 || dist[vv] > d + dd) {
          dist[vv] = d + dd;
          queue.push(std::make_pair(d + dd, vv));
        }
      }
    }
    for (int j = 0; j < N; j++) {
      if (j == i) continue;
      int d = dist[j];
      int v = j;
      while (d > 0) {
        for (auto &entry : edges[v]) {
          int dd = entry.d;
          int vv = entry.dst;
          int id = entry.id;
          if (d - dd == dist[vv]) {
            d -= dd;
            v = vv;
            used[id] = true;
            break;
          }
        }
      }
    }
  }
  int ans = 0;
  for (int i = 0; i < M; i++) {
    if (!used[i]) ans++;
  }
  std::cout << ans << std::endl;
  return 0;
}
