#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
inline int Read() {
  int x = 0, f = 1;
  char c = getchar();
  while (c > '9' || c < '0') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  return x * f;
}
struct EDGE {
  int from, to, w, next;
} E[400005];
int n, m;
int HEAD[200005];
int dep[200005], CENT;
int pa[200005][50], maxx[200005][50];
void ADD(int from, int to, int w) {
  E[CENT].from = from;
  E[CENT].to = to;
  E[CENT].w = w;
  E[CENT].next = HEAD[from];
  HEAD[from] = CENT++;
}
void DFS(int u, int f) {
  pa[u][0] = f;
  for (int i = HEAD[u]; i != -1; i = E[i].next) {
    int to = E[i].to;
    if (to != f) {
      dep[to] = dep[u] + 1;
      maxx[to][0] = E[i].w;
      DFS(to, u);
    }
  }
}
int maxh;
void deal() {
  int j;
  for (j = 1; (1 << j) < n; j++)
    for (int i = 1; i <= n; i++) {
      int t = pa[i][j - 1];
      pa[i][j] = pa[pa[i][j - 1]][j - 1];
      maxx[i][j] = max(maxx[i][j - 1], maxx[t][j - 1]);
    }
  maxh = j - 1;
}
int swim(int x, int k, int &ma) {
  ma = 0;
  for (int i = 0; i <= maxh; i++) {
    if (k >> i & 1) {
      ma = max(ma, maxx[x][i]);
      x = pa[x][i];
    }
  }
  return x;
}
int LCA(int x, int y) {
  if (dep[x] > dep[y]) swap(x, y);
  int ans = 0;
  y = swim(y, dep[y] - dep[x], ans);
  if (x == y) return ans;
  for (int i = maxh; i >= 0; i--) {
    if (pa[x][i] != pa[y][i]) {
      ans = max(ans, max(maxx[x][i], maxx[y][i]));
      x = pa[x][i], y = pa[y][i];
    }
  }
  return max(ans, max(maxx[x][0], maxx[y][0]));
}
const int N = 200005;
struct edge {
  int from, to, w, next;
  int ty;
  bool operator<(const edge a) const { return w < a.w; }
};
int pre[N], head[N];
int cnt;
edge e[200005 + 5];
void add(int from, int to, int w) {
  e[cnt].from = from;
  e[cnt].to = to;
  e[cnt].w = w;
  e[cnt].next = head[from];
  e[cnt].ty = 0;
  head[from] = cnt++;
}
int find(int x) {
  if (x == pre[x]) return x;
  return pre[x] = find(pre[x]);
}
void Kruskal() {
  for (int i = 1; i <= n; ++i) pre[i] = i;
  sort(e, e + cnt);
  for (int i = 0; i < cnt; ++i) {
    int u = find(e[i].from);
    int v = find(e[i].to);
    if (u != v) {
      pre[u] = v;
      ADD(e[i].from, e[i].to, e[i].w);
      ADD(e[i].to, e[i].from, e[i].w);
      e[i].ty = 1;
    }
  }
}
int main() {
  while (scanf("%d %d", &n, &m) != EOF) {
    CENT = cnt = 0;
    for (int i = 1; i <= n; i++) head[i] = HEAD[i] = -1;
    for (int i = 1; i <= m; i++) {
      int u = Read(), v = Read(), w = Read();
      add(u, v, w);
    }
    Kruskal();
    DFS(1, -1);
    deal();
    int ans = 0;
    for (int i = 0; i < cnt; i++) {
      if (!e[i].ty) {
        int u = e[i].from, v = e[i].to;
        int minn = LCA(u, v);
        if (minn == e[i].w) ans++;
      }
    }
    printf("%d\n", ans);
  }
  return 0;
}
