#include <bits/stdc++.h>
using namespace std;
struct UnionFind {
  vector<int> par;
  UnionFind(int n) : par(n, -1) {}
  int root(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = root(par[x]);
  }
  bool issame(int x, int y) { return root(x) == root(y); }
  bool merge(int x, int y) {
    x = root(x), y = root(y);
    if (x == y) return false;
    if (par[x] > par[y]) swap(x, y);
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  int size(int x) { return -par[root(x)]; }
};
struct Edge {
  int a, b, cost;
  bool operator<(const Edge& o) const { return cost < o.cost; }
};
struct Graph {
  int n;
  vector<Edge> es;
  int kruskal() {
    sort(es.begin(), es.end());
    UnionFind uf(n);
    int res = 0;
    for (int i = 0; i < es.size(); i++) {
      Edge& e = es[i];
      if (uf.issame(e.a, e.b))
        res++;
      else
        uf.merge(e.a, e.b);
    }
    return res;
  }
};
Graph input_graph() {
  Graph g;
  int m;
  cin >> g.n >> m;
  for (int i = 0; i < m; i++) {
    Edge e;
    cin >> e.a >> e.b >> e.cost;
    e.a--;
    e.b--;
    g.es.push_back(e);
  }
  return g;
}
int main() {
  Graph g = input_graph();
  cout << g.kruskal() << endl;
  return 0;
}
