#include <bits/stdc++.h>
using namespace std;
const long long int INF = 1e9;
struct road {
  int id;
  long long int cost;
};
int main() {
  int N, M;
  cin >> N >> M;
  vector<vector<road> > R(N + 1, vector<road>(N + 1, {-1, INF}));
  vector<vector<int> > Rv(N + 1, vector<int>());
  for (int m = 0; m < M; m++) {
    int a, b;
    long long int c;
    cin >> a >> b >> c;
    R[a][b] = {m, c};
    R[b][a] = {m, c};
    Rv[a].push_back(b);
    Rv[b].push_back(a);
  }
  vector<bool> road_used(M, false);
  vector<bool> vertex_seen(N + 1, false);
  vector<long long int> cost_from_s(N + 1, INF);
  vector<vector<int> > used_road_from_s(N + 1, vector<int>());
  auto cmp = [](pair<int, long long int> x, pair<int, long long int> y) {
    if (x.second != y.second) {
      return x.second > y.second;
    } else {
      return x.first < y.first;
    }
  };
  priority_queue<pair<int, long long int>, vector<pair<int, long long int> >,
                 decltype(cmp)>
      que(cmp);
  for (int s = 1; s <= N - 1; s++) {
    vertex_seen = vector<bool>(N + 1, false);
    cost_from_s = vector<long long int>(N + 1, INF);
    cost_from_s[s] = 0;
    que.push(make_pair(s, 0));
    for (int e = s + 1; e <= N; e++) {
      if (vertex_seen[e]) {
        for (int ui = 0; ui < used_road_from_s[e].size(); ui++) {
          road_used[used_road_from_s[e][ui]] = true;
        }
        continue;
      }
      while (!que.empty()) {
        int cur_v = que.top().first;
        que.pop();
        while (vertex_seen[cur_v]) {
          cur_v = que.top().first;
          que.pop();
        }
        for (int rvi = 0; rvi < Rv[cur_v].size(); rvi++) {
          int next_v = Rv[cur_v][rvi];
          if (vertex_seen[next_v]) {
            continue;
          } else {
            if (cost_from_s[next_v] >
                cost_from_s[cur_v] + R[cur_v][next_v].cost) {
              cost_from_s[next_v] = cost_from_s[cur_v] + R[cur_v][next_v].cost;
              used_road_from_s[next_v] = used_road_from_s[cur_v];
              used_road_from_s[next_v].push_back(R[cur_v][next_v].id);
              que.push(make_pair(next_v, cost_from_s[next_v]));
            }
          }
        }
        vertex_seen[cur_v] = true;
        if (vertex_seen[e]) {
          for (int ui = 0; ui < used_road_from_s[e].size(); ui++) {
            road_used[used_road_from_s[e][ui]] = true;
          }
          break;
        }
      }
    }
  }
  int count = 0;
  for (int m = 0; m < M; m++) {
    if (road_used[m]) continue;
    count++;
  }
  cout << count << endl;
  return 0;
}
