#include <bits/stdc++.h>
using namespace std;
const int N = 300010;
int w[N];
vector<pair<int, int> > v[N], g[N];
int a[N];
int rnk(int x) {
  while (a[x] != x) a[x] = a[a[x]], x = a[x];
  return x;
}
struct eg {
  int x, y, id;
} e[N];
bool cmp(eg a, eg b) { return w[a.id] < w[b.id]; }
bool vis[N], taken[N];
int ans = 0;
int dp[N][20], mx[N][20], l[N];
int lca(int x, int y) {
  int res = 0;
  if (l[x] > l[y]) swap(x, y);
  for (int i = 19; i >= 0; i--)
    if ((l[y] - l[x]) & (1 << i)) res = max(res, mx[y][i]), y = dp[y][i];
  if (y == x) return res;
  for (int i = 19; i >= 0; i--)
    if (dp[x][i] != dp[y][i])
      res = max(res, max(mx[x][i], mx[y][i])), x = dp[x][i], y = dp[y][i];
  return max(res, max(mx[x][0], mx[y][0]));
}
void dfs(int x, int val = 0, int p = 0) {
  if (vis[x]) return;
  vis[x] = 1;
  l[x] = l[p] + 1;
  dp[x][0] = p;
  mx[x][0] = val;
  for (int i = 1; i < 20; i++)
    dp[x][i] = dp[dp[x][i - 1]][i - 1],
    mx[x][i] = max(mx[x][i - 1], mx[dp[x][i - 1]][i - 1]);
  for (auto it : v[x]) {
    int y = it.first, z = it.second;
    if (!taken[z] && vis[y] && y != p) {
      int lc = lca(x, y);
      assert(lc <= w[z]);
      if (lc == w[z]) ans++;
    }
  }
  for (auto it : g[x]) {
    if (!vis[it.first]) dfs(it.first, w[it.second], x);
  }
}
int main() {
  int n, m, x, y, z;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    scanf("%d %d %d", &x, &y, &z);
    v[x].push_back({y, i});
    v[y].push_back({x, i});
    w[i] = z;
    e[i] = {x, y, i};
  }
  sort(e + 1, e + m + 1, cmp);
  for (int i = 1; i <= n; i++) a[i] = i;
  for (int i = 1; i <= m; i++) {
    if (rnk(e[i].x) != rnk(e[i].y)) {
      a[rnk(e[i].x)] = rnk(e[i].y);
      g[e[i].x].push_back({e[i].y, e[i].id});
      g[e[i].y].push_back({e[i].x, e[i].id});
      taken[e[i].id] = 1;
    }
  }
  dfs(1, 0);
  cout << ans;
  return 0;
}
