#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
priority_queue<pair<int, pair<int, int> > > krus_lis;
vector<pair<int, int> > cnt_lis;
int head[N], head1[N];
int findd(int x) {
  while (head[x] > 0) {
    x = head[x];
  }
  return x;
}
void unionn(int x, int y) {
  x = findd(x), y = findd(y);
  if (head[x] > head[y]) {
    head[x] = y;
    return;
  }
  if (head[x] == head[y]) {
    head[x]--;
  }
  head[y] = x;
}
bool same(int x, int y) { return findd(x) == findd(y); }
int findd1(int x) {
  while (head1[x] > 0) {
    x = head1[x];
  }
  return x;
}
void unionn1(int x, int y) {
  x = findd1(x), y = findd1(y);
  if (head1[x] > head1[y]) {
    head1[x] = y;
    return;
  }
  if (head1[x] == head1[y]) {
    head1[x]--;
  }
  head1[y] = x;
}
bool same1(int x, int y) { return findd1(x) == findd1(y); }
int main() {
  int n, m, i, j, k, l, now = 0, sum = 0;
  cin >> n >> m;
  for (i = 1; i <= m; i++) {
    cin >> j >> k >> l;
    krus_lis.push({-l, {j, k}});
  }
  for (i = 1; i <= n; i++) {
    head[i] = -1;
    head1[i] = -1;
  }
  while (krus_lis.size()) {
    if (krus_lis.top().first < now) {
      while (cnt_lis.size()) {
        unionn1(cnt_lis[cnt_lis.size() - 1].first,
                cnt_lis[cnt_lis.size() - 1].second);
        cnt_lis.pop_back();
      }
      now = krus_lis.top().first;
    }
    if (!same(krus_lis.top().second.first, krus_lis.top().second.second)) {
      unionn(krus_lis.top().second.first, krus_lis.top().second.second);
      cnt_lis.push_back(
          {krus_lis.top().second.first, krus_lis.top().second.second});
    } else {
      if (!same1(krus_lis.top().second.first, krus_lis.top().second.second)) {
        sum++;
      }
    }
    krus_lis.pop();
  }
  cout << sum;
}
