#include <bits/stdc++.h>
using namespace std;
using i64 = int64_t;
using i32 = int32_t;
template <class T, class U>
void init_n(vector<T>& v, size_t n, U x) {
  v = vector<T>(n, x);
}
template <class T>
void init_n(vector<T>& v, size_t n) {
  init_n(v, n, T());
}
template <class T>
void read_n(vector<T>& v, size_t n, size_t o = 0) {
  v = vector<T>(n + o);
  for (size_t i = o; i < n + o; ++i) cin >> v[i];
}
template <class T>
void read_n(T a[], size_t n, size_t o = 0) {
  for (size_t i = o; i < n + o; ++i) cin >> a[i];
}
template <class T>
T gabs(const T& x) {
  return max(x, -x);
}
struct UnionFind {
  vector<int> c, s;
  UnionFind(size_t n) : c(n), s(n, 1) { iota(begin(c), end(c), 0); }
  int root(int i) { return c[i] == i ? i : (c[i] = root(c[i])); }
  bool same(int i, int j) { return root(i) == root(j); }
  void unite(int i, int j) {
    i = root(i);
    j = root(j);
    if (i != j) {
      if (s[i] > s[j]) {
        c[j] = i;
        s[i] += s[j];
      } else {
        c[i] = j;
        s[j] += s[i];
      }
    }
  }
  int size(int i) { return s[root(i)]; }
};
i64 n, k;
int main() {
  cin >> n >> k;
  UnionFind uf(n + 1);
  for (i64 i = 0; i < k; ++i) {
    i64 a, b;
    cin >> a >> b;
    uf.unite(a, b);
  }
  i64 ans = 0;
  set<i64> used;
  for (i64 x = 1; x <= n; ++x) {
    i64 r = uf.root(x);
    if (used.count(r) == 0) {
      ans += uf.size(r) - 1;
      used.insert(r);
    }
  }
  cout << (k - ans) << endl;
  return 0;
}
