#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
long long ans;
int n, m, t1, t2, t3, sz[N], par[N];
vector<pair<int, pair<int, int> > > edge;
bool block[N];
int get_par(int v) {
  if (par[v] == v) return v;
  par[v] = get_par(par[v]);
  return par[v];
}
void merg(int v, int u) {
  v = get_par(v);
  u = get_par(u);
  if (sz[v] < sz[u]) swap(u, v);
  par[u] = v;
  sz[v] += sz[u];
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 1; i <= n; i++) sz[i] = 1, par[i] = i;
  for (int i = 1; i <= m; i++) {
    cin >> t1 >> t2 >> t3;
    edge.push_back({t3, {t1, t2}});
  }
  int lim;
  sort(edge.begin(), edge.end());
  for (int i = 0; i < edge.size(); i++) {
    for (int j = i; j < edge.size(); j++) {
      if (edge[j].first > edge[i].first) {
        lim = j;
        break;
      }
      if (j == edge.size() - 1) {
        lim = edge.size();
        break;
      }
    }
    for (int j = i; j < lim; j++) {
      t1 = get_par(edge[j].second.first);
      t2 = get_par(edge[j].second.second);
      if (t1 == t2) block[j] = 1;
    }
    for (int j = i; j < lim; j++) {
      if (block[j])
        continue;
      else {
        t1 = get_par(edge[j].second.first);
        t2 = get_par(edge[j].second.second);
        if (t1 == t2)
          ans++;
        else {
          merg(t1, t2);
        }
      }
    }
    i = lim - 1;
  }
  return cout << ans, 0;
}
