#include <bits/stdc++.h>
using namespace std;
long long INF = 1 << 28;
const double pi = acos(-1.0);
int fx[] = {1, -1, 0, 0};
int fy[] = {0, 0, 1, -1};
int dir[4][2] = {1, 0, -1, 0, 0, -1, 0, 1};
const long double EPS = 1e-7;
long long gcd(long long a, long long b) {
  if (b == 0)
    return a;
  else
    return gcd(b, a % b);
}
long long lcm(long long a, long long b) { return a / gcd(a, b) * b; }
bool cmp(int a, int b) { return a < b; }
int on(int mask, int pos) { return mask | (1 << pos); }
int off(int mask, int pos) { return mask & (~(1 << pos)); }
long long inf = 1e18;
long long mod = 993344777;
const int sz = 300005;
int n, m;
struct Edge {
  int u, v, w;
  bool operator<(const Edge& p) const { return w < p.w; }
};
bool cmpE(Edge a, Edge b) { return a.w < b.w; }
vector<Edge> v;
int parent[sz];
int findrep(int r) {
  if (parent[r] == r) return r;
  return parent[r] = findrep(parent[r]);
}
int unionn(int x, int y) {
  int p = findrep(x);
  int q = findrep(y);
  if (p != q) {
    parent[p] = q;
  }
  return p == q;
}
int kor[sz];
int main(void) {
  scanf("%d %d", &n, &m);
  int x, y, z;
  Edge tmp;
  for (int i = 0; i < sz; i++) {
    parent[i] = i;
  }
  for (int i = 0; i < m; i++) {
    scanf("%d %d %d", &x, &y, &z);
    tmp.u = x;
    tmp.v = y;
    tmp.w = z;
    v.push_back(tmp);
  }
  sort(v.begin(), v.end());
  int cost = 0;
  int ans = 0;
  int l = 0;
  for (int i = 0; i < m; i++) {
    x = v[i].u;
    y = v[i].v;
    z = v[i].w;
    while (z == v[l].w && l < m) {
      kor[l] = (findrep(v[l].u) != findrep(v[l].v));
      l++;
    }
    ans += (kor[i] * unionn(x, y));
  }
  cout << ans << endl;
  return 0;
}
