#include <bits/stdc++.h>
using namespace std;
std::unordered_map<long long,
                   std::vector<pair<pair<long long, long long>, long long>>>
    connection;
long long N, M;
int result = 0;
int main() {
  cin >> N >> M;
  long long* a = new long long[N];
  long long* b = new long long[N];
  long long* c = new long long[N];
  bool* result = new bool[M];
  for (long long i = 0; i < M; i++) {
    cin >> a[i] >> b[i] >> c[i];
    result[i] = false;
    a[i]--;
    b[i]--;
    connection[a[i]].push_back(make_pair(make_pair(i, b[i]), c[i]));
    connection[b[i]].push_back(make_pair(make_pair(i, a[i]), c[i]));
  }
  for (long long i = 0; i < N; i++) {
    priority_queue<pair<long long, long long>> pq;
    long long weight[N];
    bool searched[N];
    long long parent[N];
    for (long long i = 0; i < N; i++) {
      searched[i] = false;
      weight[i] = LLONG_MAX;
    }
    pq.push(make_pair(0, i));
    while (!pq.empty()) {
      pair<long long, long long> first = pq.top();
      pq.pop();
      long long node = first.second;
      long long u = -first.first;
      searched[node] = true;
      for (pair<pair<long long, long long>, long long> target :
           connection[node]) {
        long long targetNode = target.first.second;
        long long targetCost = target.second;
        if (searched[targetNode]) continue;
        if (targetCost + u < weight[targetNode]) {
          parent[targetNode] = target.first.first;
          weight[targetNode] = targetCost + u;
          pair<long long, long long> newPair =
              make_pair(weight[targetNode] * -1, targetNode);
          pq.push(newPair);
        }
      }
    }
    for (long long n = 0; n < N; n++) {
      if (n == i) continue;
      result[parent[n]] = true;
    }
  }
  long long answer = 0;
  for (long long i = 0; i < M; i++) {
    if (result[i] == false) {
      answer++;
    }
  }
  cout << answer;
  return 0;
}
