#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
inline int rd() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) f = ch == '-' ? 0 : 1, ch = getchar();
  while (isdigit(ch)) x = (x << 1) + (x << 3) + ch - '0', ch = getchar();
  return f ? x : -x;
}
int n, m, F[N], ans;
bool vis[N];
struct Edge {
  int u, v, w;
  friend bool operator<(const Edge A, const Edge B) { return A.w < B.w; }
} edge[N];
int get(int x) {
  if (x == F[x]) return x;
  return F[x] = get(F[x]);
}
int main() {
  n = rd(), m = rd();
  for (int i = 1; i <= n; i++) F[i] = i;
  for (int i = 1; i <= m; i++)
    edge[i].u = rd(), edge[i].v = rd(), edge[i].w = rd();
  sort(edge + 1, edge + m + 1);
  int x, y, z, u, v, tmp = edge[1].w, lst = 0;
  bool flag = false;
  for (int i = 2; i <= m; i++) {
    z = edge[i].w;
    if (z == tmp) continue;
    for (int j = lst + 1; j < i; j++) {
      x = edge[j].u, y = edge[j].v;
      u = get(x), v = get(y);
      if (u == v) {
        vis[j] = 1;
        continue;
      }
    }
    for (int j = lst + 1; j < i; j++) {
      if (vis[j]) continue;
      x = edge[j].u, y = edge[j].v;
      u = get(x), v = get(y);
      if (u == v)
        ans++;
      else
        F[u] = v;
    }
    lst = i - 1;
    tmp = z;
  }
  for (int i = lst + 1; i <= m; i++) {
    x = edge[i].u, y = edge[i].v;
    u = get(x), v = get(y);
    if (u == v) {
      vis[i] = 1;
      continue;
    }
  }
  for (int i = lst + 1; i <= m; i++) {
    if (vis[i]) continue;
    x = edge[i].u, y = edge[i].v;
    u = get(x), v = get(y);
    if (u == v)
      ans++;
    else
      F[u] = v;
  }
  printf("%d\n", ans);
  return 0;
}
