#include <bits/stdc++.h>
using namespace std;
const long long dx[] = {-1, -1, -1, 0, 1, 1, 1, 0};
const long long dy[] = {-1, 0, 1, 1, 1, 0, -1, -1};
class DSU {
 public:
  vector<long long> parent;
  DSU(long long n) {
    parent.resize(n);
    for (long long i = 0; i < n; i++) {
      parent[i] = i;
    }
  }
  bool unite(long long x, long long y) {
    long long px = find(x);
    long long py = find(y);
    if (px == py) {
      return true;
    }
    parent[px] = py;
    return false;
  }
  long long find(long long x) {
    if (x == parent[x]) {
      return x;
    } else {
      return parent[x] = find(parent[x]);
    }
  }
};
vector<long long> edge[100005];
bool vis[100005];
set<pair<long long, long long>> nodes;
void dfs(long long node) {
  if (vis[node]) {
    return;
  }
  vis[node] = 1;
  for (auto x : edge[node]) {
    long long aa, bb;
    aa = x;
    bb = node;
    if (aa > bb) {
      swap(aa, bb);
    }
    nodes.insert({aa, bb});
    if (!vis[x]) {
      dfs(x);
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  ;
  long long test = 1;
  while (test--) {
    long long n;
    cin >> n;
    long long m;
    cin >> m;
    long long ans = 0;
    for (long long i = 0; i < m; i++) {
      long long x, y;
      cin >> x >> y;
      x--;
      y--;
      edge[x].push_back(y);
      edge[y].push_back(x);
    }
    DSU dsu(2 * n + 100);
    for (long long i = 0; i < n; i++) {
      if (!vis[i]) {
        nodes.clear();
        dfs(i);
        long long cnt = 1;
        for (auto x : nodes) {
          if (dsu.unite(x.first, x.second)) {
            cnt = 0;
            break;
          }
        }
        ans += cnt;
      }
    }
    cout << ans << '\n';
  }
  return 0;
}
