#include <bits/stdc++.h>
using namespace std;
bool chmin(int& a, int b) {
  if (a > b) {
    a = b;
    return true;
  } else
    return false;
}
map<pair<int, int>, int> weight;
map<pair<int, int>, int> best_weight;
map<pair<int, int>, bool> seen;
int dfs(int start_node, int end_node, map<int, bool>& passed,
        vector<vector<int>> connectTo) {
  if (seen[make_pair(start_node, end_node)]) {
    return best_weight[make_pair(start_node, end_node)];
  }
  int best = 1000000;
  passed[start_node] = true;
  for (auto i : connectTo[start_node]) {
    if (i == end_node) {
      chmin(best, weight[make_pair(start_node, i)]);
    } else if (passed[i])
      continue;
    else {
      passed[i] = true;
      chmin(best, weight[make_pair(start_node, i)] +
                      dfs(i, end_node, passed, connectTo));
    }
    passed.erase(i);
  }
  best_weight[make_pair(start_node, end_node)] = best;
  return best;
}
int main() {
  int N, M;
  cin >> N >> M;
  vector<vector<int>> connectTo(N);
  vector<tuple<int, int, int>> edge;
  for (int i = 0; i < M; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    connectTo[a - 1].push_back(b - 1);
    connectTo[b - 1].push_back(a - 1);
    weight[make_pair(a - 1, b - 1)] = c;
    weight[make_pair(b - 1, a - 1)] = c;
    edge.push_back(make_tuple(a - 1, b - 1, c));
  }
  int ans = 0;
  map<int, bool> passed;
  for (auto X : edge) {
    passed.clear();
    if (dfs(get<0>(X), get<1>(X), passed, connectTo) != get<2>(X)) ans++;
  }
  cout << ans << endl;
  return 0;
}
