#include <bits/stdc++.h>
using namespace std;
struct UNIONFIND {
  int size;
  vector<int> vec;
  UNIONFIND(int n) : size(n) {
    vec = vector<int>(n + 1);
    for (int i = 0; i < n + 1; i++) {
      vec[i] = -1;
    }
  }
  void set(int a, int b) {
    if (vec[parent(a)] < vec[parent(b)]) {
      vec[parent(a)] += vec[parent(b)];
      vec[parent(b)] = parent(a);
    } else {
      vec[parent(b)] += vec[parent(a)];
      vec[parent(a)] = parent(b);
    }
  }
  int parent(int a) {
    if (vec[a] < 0) {
      return a;
    }
    return vec[a] = parent(vec[a]);
  }
  bool same(int a, int b) { return (parent(a) == parent(b)); }
};
struct EDGE {
  int node1;
  int node2;
  int cost;
  EDGE(int a, int b, int c) : node1(a), node2(b), cost(c) {}
  bool operator<(const EDGE& right) const { return cost < right.cost; }
};
struct GRAPH {
  vector<EDGE> vec;
  int n;
  int nonuse;
  GRAPH(int i) : n(i) {}
  void push(int a, int b, int c) { vec.push_back(EDGE(a, b, c)); }
  int make() {
    nonuse = 0;
    sort(vec.begin(), vec.end());
    UNIONFIND uf = UNIONFIND(n);
    for (int i = 0; i < vec.size(); i++) {
      if (!uf.same(vec[i].node1, vec[i].node2)) {
        uf.set(vec[i].node1, vec[i].node2);
      } else {
        nonuse++;
      }
    }
    return nonuse;
  }
};
int main() {
  int n, m;
  cin >> n >> m;
  GRAPH gr = GRAPH(n);
  for (int i = 0; i < m; i++) {
    int a, b, c;
    cin >> a >> b >> c;
    gr.push(a, b, c);
  }
  cout << gr.make() << endl;
  return 0;
}
