#include <bits/stdc++.h>
using namespace std;
const int MOD = 1e9 + 7;
const int maxn = 2e5 + 10;
const int DEG = 20;
struct Edge {
  int to, nxt, val;
  Edge() {}
  Edge(int to, int nxt, int val) : to(to), nxt(nxt), val(val) {}
} edge[maxn << 1];
struct node {
  int u, v, val, vis;
  node() {}
  node(int _u, int _v, int _val) { u = _u, v = _v, val = _val, vis = 0; }
  bool operator<(const node &other) const { return val < other.val; }
} edge_MST[maxn << 1];
int n, m;
int head[maxn];
int deg[maxn];
int tot;
int father[maxn];
int fa[maxn][DEG];
int dis[maxn][DEG];
void Init() {
  tot = 0;
  for (int i = 1; i <= n; ++i) father[i] = i;
  memset(head, -1, sizeof head);
}
void addedge(int u, int v, int w) {
  edge[tot] = Edge(v, head[u], w);
  head[u] = tot++;
  edge[tot] = Edge(u, head[v], w);
  head[v] = tot++;
}
int find(int x) {
  return father[x] == x ? father[x] : father[x] = find(father[x]);
}
bool same(int x, int y) { return find(x) == find(y); }
void Mix(int x, int y) {
  x = find(x), y = find(y);
  if (x != y) {
    father[x] = y;
  }
}
void MST() {
  sort(edge_MST + 1, edge_MST + 1 + m);
  for (int i = 1; i <= m; ++i) {
    int u = edge_MST[i].u, v = edge_MST[i].v, w = edge_MST[i].val;
    if (same(u, v)) continue;
    Mix(u, v);
    edge_MST[i].vis = 1;
    addedge(u, v, w);
  }
}
void BFS(int root) {
  deg[root] = 0;
  fa[root][0] = root;
  queue<int> q;
  q.push(root);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 1; i < DEG; ++i) {
      fa[u][i] = fa[fa[u][i - 1]][i - 1];
      dis[u][i] = max(dis[u][i - 1], dis[fa[u][i - 1]][i - 1]);
    }
    for (int i = head[u]; ~i; i = edge[i].nxt) {
      int v = edge[i].to, w = edge[i].val;
      if (v == fa[u][0]) continue;
      fa[v][0] = u;
      deg[v] = deg[u] + 1;
      dis[v][0] = w;
      q.push(v);
    }
  }
}
int LCA(int u, int v) {
  if (deg[u] > deg[v]) swap(u, v);
  int hu = deg[u], hv = deg[v];
  int tu = u, tv = v;
  int ans = 0;
  for (int det = hv - hu, i = 0; det; det >>= 1, ++i) {
    if (det & 1) {
      ans = max(ans, dis[tv][i]);
      tv = fa[tv][i];
    }
  }
  if (tu == tv) return ans;
  for (int i = DEG - 1; i >= 0; --i) {
    if (fa[tu][i] == fa[tv][i]) continue;
    ans = max(ans, max(dis[tu][i], dis[tv][i]));
    tu = fa[tu][i];
    tv = fa[tv][i];
  }
  return max(ans, max(dis[tu][0], dis[tv][0]));
}
void RUN() {
  while (~scanf("%d %d", &n, &m)) {
    Init();
    for (int i = 1, u, v, w; i <= m; ++i) {
      scanf("%d %d %d", &u, &v, &w);
      edge_MST[i] = node(u, v, w);
    }
    MST();
    BFS(1);
    int ans = 0;
    for (int i = 1, u, v, w; i <= m; ++i) {
      if (edge_MST[i].vis) continue;
      u = edge_MST[i].u, v = edge_MST[i].v, w = edge_MST[i].val;
      ans += (LCA(u, v) == w);
    }
    printf("%d\n", ans);
  }
}
int main() {
  RUN();
  return 0;
}
