#include <bits/stdc++.h>
using namespace std;
const int maxn(2e5 + 5);
typedef struct {
  int len;
  int x;
  int y;
} edge;
int p[maxn];
vector<edge> q;
bool comp(const edge& a, const edge& b) { return a.len < b.len; }
int getID(int v) { return p[v] == v ? p[v] : p[v] = getID(p[v]); }
void concat(int x, int y) {
  x = getID(x);
  y = getID(y);
  p[x] = y;
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < n; i++) p[i] = i;
  q.resize(m);
  for (int i = 0; i < m; i++) {
    int x, y, z;
    cin >> x >> y >> z;
    x--, y--;
    q[i] = {z, x, y};
  }
  sort(q.begin(), q.end(), comp);
  q.push_back({INT_MAX, 0, 0});
  int ans = 0;
  int curGood = 1, curQ = 0;
  vector<int> good(1, 0);
  for (int i = 1; i < m + 1; i++) {
    if (q[i - 1].len != q[i].len) {
      for (int j = 0; j < good.size(); j++)
        if (getID(q[good[j]].x) != getID(q[good[j]].y))
          curQ++, concat(q[good[j]].x, q[good[j]].y);
      ans += curGood - curQ;
      curGood = 0;
      curQ = 0;
      good.clear();
      if (getID(q[i].x) != getID(q[i].y)) {
        curGood++;
        good = vector<int>(1, i);
      }
    } else {
      if (getID(q[i].x) != getID(q[i].y)) {
        curGood++;
        good.push_back(i);
      }
    }
  }
  cout << ans;
}
