#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
#define ll long long int
//#define d double
#define F first
#define S second
#define FastIO ios_base::sync_with_stdio(false),cin.tie(0)
#define fix std::fixed<<setprecision(10)
const int M=1e9+7;
#define f(n) for(int i=0;i<n;i++)
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define vi vector<int>
#define pb push_back
#define si set<int>
#define cl(n,m) (ceil(double(n)/double(m)))
#define T() int t; cin>>t; while(t--)
#define pi pair<ll,ll>
const int MOD=998244353;
//const int MOD=1e9+7;
#define endl "\n"
const double PI = 3.141592653589793238460;
#define READ(f) freopen(f, "r", stdin)
#define WRITE(f) freopen(f, "w", stdout)
//bitset<N>bs;
//bitset<512>bb[512];
//vector<vector<int>>arr;

ll power(ll a,ll b)
{
    ll res=1;
    if(a==0)return 0;
    if(a==1)return 1;
    for(;b>0;b>>=1)
    {
        if(b&1)res=(res*a);
        if(res>MOD)res%=MOD;
        a=(a*a);
        if(a>MOD)a=a%MOD;
    }
    return res;
}

bool isPrime[1000001];
vector<ll>prime;

void seive(int limit)
{
    isPrime[0]=isPrime[1]=1;

    for(int i=2;i*i<=limit;i++)
    {
        if(!isPrime[i])
        for(int j=i*i;j<=limit;j+=i)
        {
            isPrime[j]=1;
        }
    }
    for(int i=2;i<=limit;i++)if(!isPrime[i])prime.pb(i);
}

int n,m;
set<ll>adj[100100];
int visited[100100];
bool flag=0;

int parent[100010];
int sz[100010];

int finds(int x)
{
    while(parent[x]!=x)
    {
        parent[x]=parent[parent[x]];
        x=parent[x];
    }
    return x;
}

void uniona(int x,int y)
{
    int a=finds(x);
    int b=finds(y);

    if(sz[a]>sz[b])swap(a,b);

    sz[b]+=sz[a];
    parent[a]=b;
}

void dfs(int s,int p)
{
    if(visited[s])
    {
        flag=1;return;
    }
    visited[s]=1;

    for(int x:adj[s])
    {
        if(x!=p)
        {
            dfs(x,s);
        }
    }
}

int main()
{
  cin>>n>>m;

  f(m)
  {
      int x,y;
      cin>>x>>y;
      adj[x].insert(y);
      adj[y].insert(x);
  }
  int ans=0;
  for(int i=1;i<=n;i++)
  {
      if(!visited[i])
      {
          flag=0;
          dfs(i,0);
          if(!flag)ans++;
      }
  }
cout<<ans;
}


#include <bits/stdc++.h>

#define ll          long long
#define pb          push_back
#define pii         pair<ll int,ll int>
#define vi          vector<ll int>
#define vii         vector<pii>
#define mi          map<ll int,ll int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (int)x.size()

#define hell        1000000007
#define rep(i,a,b)  for(ll int i=a;i<b;i++)
#define take        rep(i,0,n) cin>>v[i];
#define MAXN        1000005
using namespace std;

vi adj[MAXN];
ll vis[MAXN];
vi   a[MAXN];
vi   v[MAXN];
ll   q[MAXN];
ll n,k,m;
ll c;
ll t;
ll fk;
ll nd;
void dfs(ll i,ll p)
{
	if(vis[i]) return;
	vis[i]=1;
	nd++;

	for(auto x:adj[i])
	{
		if(vis[x]==1&&x!=p)
		{
			t++;
		}
		dfs(x,i);
	}

}
void solve()
{

	cin>>n>>k;
	for(ll i=1;i<=k;i++)
	{
		ll x,y;
		cin>>x>>y;
		adj[x].pb(y);
		adj[y].pb(x);
	}

		ll z=0;
	for(ll i=1;i<=n;i++)
	{

	t=0;
	if(vis[i]==0){

		dfs(i,-1);
	//	cout<<t<<" t "<<nd<<endl;
		if(t==0)
		{
			z++;
		}
	}

	}
	cout<<z<<endl;

}
int main()
    {
       ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        int t;
        t=1;
    //  cin>>t;
        while(t--)
        solve();
    }


#include <bits/stdc++.h>

#define ll          long long
#define pb          push_back
#define pii         pair<ll int,ll int>
#define vi          vector<ll int>
#define vii         vector<pii>
#define mi          map<ll int,ll int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (int)x.size()

#define hell        1000000007
#define rep(i,a,b)  for(ll int i=a;i<b;i++)
#define take        rep(i,0,n) cin>>v[i];
#define MAXN        1000005
using namespace std;

vi adj[MAXN];
ll vis[MAXN];
vi   a[MAXN];
vi   v[MAXN];
ll   q[MAXN];
ll n,k,m;
ll c;
ll t;
ll fk;
void dfs(ll i)
{
	if(vis[i]) return;
	vis[i]=1;
	if(adj[i].size()>=3)
	{
		fk++;
	}
	for(auto x:adj[i])
	{
		if((adj[i].size()==1&&adj[x].size()==2))
		{
			t++;
		}
		dfs(x);
	}

}
void solve()
{

	cin>>n>>k;
	for(ll i=1;i<=k;i++)
	{
		ll x,y;
		cin>>x>>y;
		adj[x].pb(y);
		adj[y].pb(x);
	}

		ll z=0;
	for(ll i=1;i<=n;i++)
	{
		t=0;
		fk=0;
		dfs(i);
		if(t-fk>1)
		{
			z=z+t-1;
		}

	}
	cout<<z<<endl;

}
int main()
    {
       ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        int t;
        t=1;
    //  cin>>t;
        while(t--)
        solve();
    }


#include <bits/stdc++.h>

#define ll          long long
#define pb          push_back
#define pii         pair<ll int,ll int>
#define vi          vector<ll int>
#define vii         vector<pii>
#define mi          map<ll int,ll int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (int)x.size()

#define hell        1000000007
#define rep(i,a,b)  for(ll int i=a;i<b;i++)
#define take        rep(i,0,n) cin>>v[i];
#define MAXN        1000005
using namespace std;

vi adj[MAXN];
ll vis[MAXN];
vi   a[MAXN];
vi   v[MAXN];
ll   q[MAXN];
ll n,k,m;
ll c;
ll t;
void dfs(ll i)
{
	if(vis[i]) return;
	vis[i]=1;
	for(auto x:adj[i])
	{
		if((adj[i].size()==1&&adj[x].size()==2))
		{
			t++;
		}
		dfs(x);
	}
}
void solve()
{

	cin>>n>>k;
	for(ll i=1;i<=k;i++)
	{
		ll x,y;
		cin>>x>>y;
		adj[x].pb(y);
		adj[y].pb(x);
	}

		ll z=0;
	for(ll i=1;i<=n;i++)
	{
		t=0;
		dfs(i);
		if(t>1)
		{
			z=z+t-1;
		}

	}
	cout<<z<<endl;

}
int main()
    {
       ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        int t;
        t=1;
    //  cin>>t;
        while(t--)
        solve();
    }


#include <bits/stdc++.h>

#define ll          long long
#define pb          push_back
#define pii         pair<ll int,ll int>
#define vi          vector<ll int>
#define vii         vector<pii>
#define mi          map<ll int,ll int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (int)x.size()

#define hell        1000000007
#define rep(i,a,b)  for(ll int i=a;i<b;i++)
#define take        rep(i,0,n) cin>>v[i];
#define MAXN        1000005
using namespace std;

vi adj[MAXN];
ll vis[MAXN];
vi   a[MAXN];
vi   v[MAXN];
ll   q[MAXN];
ll n,k,m;
ll c;
ll t;
ll fk;
ll nd;
void dfs(ll i,ll p)
{
	if(vis[i]) return;
	vis[i]=1;
	nd++;

	for(auto x:adj[i])
	{
		if(vis[x]==1&&x!=p)
		{
			t++;
		}
		dfs(x,i);
	}

}
void solve()
{

	cin>>n>>k;
	for(ll i=1;i<=k;i++)
	{
		ll x,y;
		cin>>x>>y;
		adj[x].pb(y);
		adj[y].pb(x);
	}

		ll z=0;
	for(ll i=1;i<=n;i++)
	{
	nd=0;
	t=0;
		dfs(i,-1);
	//	cout<<t<<" t "<<nd<<endl;
		if(t==0&&nd>1)
		{
			z++;
		}

	}
	cout<<z<<endl;

}
int main()
    {
       ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        int t;
        t=1;
    //  cin>>t;
        while(t--)
        solve();
    }


#include <bits/stdc++.h>
using namespace std;
#define inf (pow(10,18))
#define ll long long int
#define mod 1000000007
#define ntq(z)  long long int z; cin>>z; for(long long int i=0;i<z;i++)
#define fi(x9,y9) for(long long int i=x9;i<y9;i++)
#define fj(x9,y9) for(long long int j=x9;j<y9;j++)
#define fk(x9,y9) for(long long int k=x9;k<y9;k++)
#define f(z9) for(long long int i=0;i<z9;i++)
#define frev(z9) for(long long int i=z9-1;i>=0;i--)
#define endl "\n"
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,i) for(typeof((c).begin() i = (c).begin(); i != (c).end(); i++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define stoi(s,n) stringstream str(s); str >> n;
#define get_vi(v, n) vi v(n); f(n){cin >> v[i];}

typedef vector< ll > vi;
typedef vector< pair<ll,ll> > vp;
typedef vector< vi > vvi;
typedef pair< ll,ll > ii;
typedef priority_queue <ll, vi, greater <ll> > min_heap;
typedef priority_queue <ll> max_heap;

void printprecise(double l,ll precision) {
	std::cout << std::fixed;
	std::cout << std::setprecision(precision);
	std::cout << l;
}

ll ncr(ll n, ll k)
{
	ll C[n + 1][k + 1];
	ll i, j;
	for (i = 0; i <= n; i++)
	{
		for (j = 0; j <= min(i, k); j++)
		{
			if (j == 0 || j == i)
				C[i][j] = 1;

			else
				C[i][j] = C[i - 1][j - 1] +
						  C[i - 1][j];
		}
	}

	return C[n][k];
}

ll power_wm(ll x, ll y, ll p) {
	ll res = 1;      // Initialize result

	x = x % p;  // Update x if it is more than or
				// equal to p

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x) % p;

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x) % p;
	}
	return res;
}

ll power(ll x, ll y) {
	ll res = 1;      // Initialize result

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x);

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x);
	}
	return res;
}

ll root(ll x,vi &roots){
  if(roots[x]!=x)
	roots[x]=root(roots[x],roots);
  return roots[x];
}

void unoin(ll p, ll q,vi &roots,vi &rank){
  ll rp=root(p,roots);
  ll rq=root(q,roots);
  if(rank[rq]<rank[rp]){
	roots[rq]=rp;
  }
  else if(rank[rp]>rank[rq]){
	roots[rp]=rq;
  }
  else{
	roots[rp]=rq;
	rank[rq]++;
  }

}

ll dig_sum(ll n) {
  ll s = 0;
  while(n) {
	s += n%10;
	n /=10;
  }
  return s;
}

ll gcd(ll a, ll b) {
	if(a < b) {
	  a = a + b;
	  b = a - b;
	  a = a - b;
	}
	if (b == 0)
	  return a;
	return gcd(b, a % b);
}

ll toD(ll x, ll y, ll m) {
  return x*m + y%m;
}

pair <ll, ll> twoD(ll p, ll m) {
  return (make_pair(p/m, p%m));
}

vi dist;
vvi g;

void dfs(ll p) {
  if(dist[p] != -1) {
	return;
  }

  dist[p] = 0;
  ll maxd = -1;

  f(g[p].size()) {
	  dfs(g[p][i]);
	  maxd = max(maxd, dist[g[p][i]]);
  }

  dist[p] = maxd + 1;
}

vi fact;

void calfact() {
  fact[0] = 1;
  fi(1, 1000001) {
	fact[i] = (fact[i-1] * i) % 998244353;
  }
}

int main() {

  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  #ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  ll n, m;
  cin >> n >> m;

  vi roots(n), rank(n), deg(n);

  f(n) {
  	roots[i] = i;
  }

  ll x, y;

  f(m) {
  	cin >> x >> y;
  	unoin(--x, --y, roots, rank);
  	deg[x]++;
  	deg[y]++;
  }

  vi bad(n);

  f(n) {
  	ll r = root(i, roots);
  	if(r == i) {
  		bad[r] = 1;
  	} else {
  		bad[r] += deg[i] - 2;
  	}
  }

  ll ans = 0;

  f(n) {
  	if(bad[i]) {
  		ans++;
  	}
  }

  cout << ans;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define inf (pow(10,18))
#define ll long long int
#define mod 1000000007
#define ntq(z)  long long int z; cin>>z; for(long long int i=0;i<z;i++)
#define fi(x9,y9) for(long long int i=x9;i<y9;i++)
#define fj(x9,y9) for(long long int j=x9;j<y9;j++)
#define fk(x9,y9) for(long long int k=x9;k<y9;k++)
#define f(z9) for(long long int i=0;i<z9;i++)
#define frev(z9) for(long long int i=z9-1;i>=0;i--)
#define endl "\n"
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,i) for(typeof((c).begin() i = (c).begin(); i != (c).end(); i++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define stoi(s,n) stringstream str(s); str >> n;
#define get_vi(v, n) vi v(n); f(n){cin >> v[i];}

typedef vector< ll > vi;
typedef vector< pair<ll,ll> > vp;
typedef vector< vi > vvi;
typedef pair< ll,ll > ii;
typedef priority_queue <ll, vi, greater <ll> > min_heap;
typedef priority_queue <ll> max_heap;

void printprecise(double l,ll precision) {
	std::cout << std::fixed;
	std::cout << std::setprecision(precision);
	std::cout << l;
}

ll ncr(ll n, ll k)
{
	ll C[n + 1][k + 1];
	ll i, j;
	for (i = 0; i <= n; i++)
	{
		for (j = 0; j <= min(i, k); j++)
		{
			if (j == 0 || j == i)
				C[i][j] = 1;

			else
				C[i][j] = C[i - 1][j - 1] +
						  C[i - 1][j];
		}
	}

	return C[n][k];
}

ll power_wm(ll x, ll y, ll p) {
	ll res = 1;      // Initialize result

	x = x % p;  // Update x if it is more than or
				// equal to p

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x) % p;

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x) % p;
	}
	return res;
}

ll power(ll x, ll y) {
	ll res = 1;      // Initialize result

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x);

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x);
	}
	return res;
}

ll root(ll x,vi &roots){
  if(roots[x]!=x)
	roots[x]=root(roots[x],roots);
  return roots[x];
}

void unoin(ll p, ll q,vi &roots,vi &rank){
  ll rp=root(p,roots);
  ll rq=root(q,roots);
  if(rank[rq]<rank[rp]){
	roots[rq]=rp;
  }
  else if(rank[rp]>rank[rq]){
	roots[rp]=rq;
  }
  else{
	roots[rp]=rq;
	rank[rq]++;
  }

}

ll dig_sum(ll n) {
  ll s = 0;
  while(n) {
	s += n%10;
	n /=10;
  }
  return s;
}

ll gcd(ll a, ll b) {
	if(a < b) {
	  a = a + b;
	  b = a - b;
	  a = a - b;
	}
	if (b == 0)
	  return a;
	return gcd(b, a % b);
}

ll toD(ll x, ll y, ll m) {
  return x*m + y%m;
}

pair <ll, ll> twoD(ll p, ll m) {
  return (make_pair(p/m, p%m));
}

vi dist;
vvi g;

void dfs(ll p) {
  if(dist[p] != -1) {
	return;
  }

  dist[p] = 0;
  ll maxd = -1;

  f(g[p].size()) {
	  dfs(g[p][i]);
	  maxd = max(maxd, dist[g[p][i]]);
  }

  dist[p] = maxd + 1;
}

vi fact;

void calfact() {
  fact[0] = 1;
  fi(1, 1000001) {
	fact[i] = (fact[i-1] * i) % 998244353;
  }
}

int main() {

  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  #ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  ll n, m;
  cin >> n >> m;

  vi roots(n), rank(n), deg(n);

  f(n) {
  	roots[i] = i;
  }

  ll x, y;

  f(m) {
  	cin >> x >> y;
  	unoin(--x, --y, roots, rank);
  	deg[x]++;
  	deg[y]++;
  }

  vi bad(n);

  f(n) {
		ll r = root(i, roots);
		bad[r] += deg[i] - 2;
  }

  ll ans = 0;

  f(n) {
  	if(bad[i] == -2) {
  		ans++;
  	}
  }

  cout << ans;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define inf (pow(10,18))
#define ll long long int
#define mod 1000000007
#define ntq(z)  long long int z; cin>>z; for(long long int i=0;i<z;i++)
#define fi(x9,y9) for(long long int i=x9;i<y9;i++)
#define fj(x9,y9) for(long long int j=x9;j<y9;j++)
#define fk(x9,y9) for(long long int k=x9;k<y9;k++)
#define f(z9) for(long long int i=0;i<z9;i++)
#define frev(z9) for(long long int i=z9-1;i>=0;i--)
#define endl "\n"
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,i) for(typeof((c).begin() i = (c).begin(); i != (c).end(); i++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define stoi(s,n) stringstream str(s); str >> n;
#define get_vi(v, n) vi v(n); f(n){cin >> v[i];}

typedef vector< ll > vi;
typedef vector< pair<ll,ll> > vp;
typedef vector< vi > vvi;
typedef pair< ll,ll > ii;
typedef priority_queue <ll, vi, greater <ll> > min_heap;
typedef priority_queue <ll> max_heap;

void printprecise(double l,ll precision) {
	std::cout << std::fixed;
	std::cout << std::setprecision(precision);
	std::cout << l;
}

ll ncr(ll n, ll k)
{
	ll C[n + 1][k + 1];
	ll i, j;
	for (i = 0; i <= n; i++)
	{
		for (j = 0; j <= min(i, k); j++)
		{
			if (j == 0 || j == i)
				C[i][j] = 1;

			else
				C[i][j] = C[i - 1][j - 1] +
						  C[i - 1][j];
		}
	}

	return C[n][k];
}

ll power_wm(ll x, ll y, ll p) {
	ll res = 1;      // Initialize result

	x = x % p;  // Update x if it is more than or
				// equal to p

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x) % p;

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x) % p;
	}
	return res;
}

ll power(ll x, ll y) {
	ll res = 1;      // Initialize result

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x);

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x);
	}
	return res;
}

ll root(ll x,vi &roots){
  if(roots[x]!=x)
	roots[x]=root(roots[x],roots);
  return roots[x];
}

void unoin(ll p, ll q,vi &roots,vi &rank){
  ll rp=root(p,roots);
  ll rq=root(q,roots);
  if(rank[rq]<rank[rp]){
	roots[rq]=rp;
  }
  else if(rank[rp]>rank[rq]){
	roots[rp]=rq;
  }
  else{
	roots[rp]=rq;
	rank[rq]++;
  }

}

ll dig_sum(ll n) {
  ll s = 0;
  while(n) {
	s += n%10;
	n /=10;
  }
  return s;
}

ll gcd(ll a, ll b) {
	if(a < b) {
	  a = a + b;
	  b = a - b;
	  a = a - b;
	}
	if (b == 0)
	  return a;
	return gcd(b, a % b);
}

ll toD(ll x, ll y, ll m) {
  return x*m + y%m;
}

pair <ll, ll> twoD(ll p, ll m) {
  return (make_pair(p/m, p%m));
}

vi dist;
vvi g;

void dfs(ll p) {
  if(dist[p] != -1) {
	return;
  }

  dist[p] = 0;
  ll maxd = -1;

  f(g[p].size()) {
	  dfs(g[p][i]);
	  maxd = max(maxd, dist[g[p][i]]);
  }

  dist[p] = maxd + 1;
}

vi fact;

void calfact() {
  fact[0] = 1;
  fi(1, 1000001) {
	fact[i] = (fact[i-1] * i) % 998244353;
  }
}

int main() {

  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  #ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  ll n, m;
  cin >> n >> m;

  vi roots(n), rank(n), deg(n);

  f(n) {
  	roots[i] = i;
  }

  ll x, y;

  f(m) {
  	cin >> x >> y;
  	unoin(--x, --y, roots, rank);
  	deg[x]++;
  	deg[y]++;
  }

  vi bad(n);

  f(n) {
  	ll r = root(i, roots);
  	bad[r] += deg[i] - 2;
  }

  ll ans = 0;

  f(n) {
  	if(bad[i]) {
  		ans++;
  	}
  }

  cout << ans;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define inf (pow(10,18))
#define ll long long int
#define mod 1000000007
#define ntq(z)  long long int z; cin>>z; for(long long int i=0;i<z;i++)
#define fi(x9,y9) for(long long int i=x9;i<y9;i++)
#define fj(x9,y9) for(long long int j=x9;j<y9;j++)
#define fk(x9,y9) for(long long int k=x9;k<y9;k++)
#define f(z9) for(long long int i=0;i<z9;i++)
#define frev(z9) for(long long int i=z9-1;i>=0;i--)
#define endl "\n"
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,i) for(typeof((c).begin() i = (c).begin(); i != (c).end(); i++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define stoi(s,n) stringstream str(s); str >> n;
#define get_vi(v, n) vi v(n); f(n){cin >> v[i];}

typedef vector< ll > vi;
typedef vector< pair<ll,ll> > vp;
typedef vector< vi > vvi;
typedef pair< ll,ll > ii;
typedef priority_queue <ll, vi, greater <ll> > min_heap;
typedef priority_queue <ll> max_heap;

void printprecise(double l,ll precision) {
	std::cout << std::fixed;
	std::cout << std::setprecision(precision);
	std::cout << l;
}

ll ncr(ll n, ll k)
{
	ll C[n + 1][k + 1];
	ll i, j;
	for (i = 0; i <= n; i++)
	{
		for (j = 0; j <= min(i, k); j++)
		{
			if (j == 0 || j == i)
				C[i][j] = 1;

			else
				C[i][j] = C[i - 1][j - 1] +
						  C[i - 1][j];
		}
	}

	return C[n][k];
}

ll power_wm(ll x, ll y, ll p) {
	ll res = 1;      // Initialize result

	x = x % p;  // Update x if it is more than or
				// equal to p

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x) % p;

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x) % p;
	}
	return res;
}

ll power(ll x, ll y) {
	ll res = 1;      // Initialize result

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x);

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x);
	}
	return res;
}

ll root(ll x,vi &roots){
  if(roots[x]!=x)
	roots[x]=root(roots[x],roots);
  return roots[x];
}

void unoin(ll p, ll q,vi &roots,vi &rank){
  ll rp=root(p,roots);
  ll rq=root(q,roots);
  if(rank[rq]<rank[rp]){
	roots[rq]=rp;
  }
  else if(rank[rp]>rank[rq]){
	roots[rp]=rq;
  }
  else{
	roots[rp]=rq;
	rank[rq]++;
  }

}

ll dig_sum(ll n) {
  ll s = 0;
  while(n) {
	s += n%10;
	n /=10;
  }
  return s;
}

ll gcd(ll a, ll b) {
	if(a < b) {
	  a = a + b;
	  b = a - b;
	  a = a - b;
	}
	if (b == 0)
	  return a;
	return gcd(b, a % b);
}

ll toD(ll x, ll y, ll m) {
  return x*m + y%m;
}

pair <ll, ll> twoD(ll p, ll m) {
  return (make_pair(p/m, p%m));
}

vi dist;
vvi g;

void dfs(ll p) {
  if(dist[p] != -1) {
	return;
  }

  dist[p] = 0;
  ll maxd = -1;

  f(g[p].size()) {
	  dfs(g[p][i]);
	  maxd = max(maxd, dist[g[p][i]]);
  }

  dist[p] = maxd + 1;
}

vi fact;

void calfact() {
  fact[0] = 1;
  fi(1, 1000001) {
	fact[i] = (fact[i-1] * i) % 998244353;
  }
}

int main() {

  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  #ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  ll n, m;
  cin >> n >> m;

  vi roots(n), rank(n), deg(n);

  f(n) {
  	roots[i] = i;
  }

  ll x, y;

  f(m) {
  	cin >> x >> y;
  	unoin(--x, --y, roots, rank);
  	deg[x]++;
  	deg[y]++;
  }

  vi bad(n);

  f(n) {
  	if(deg[i] == 0) {
  		bad[i] = 1;
  	} else {
  		ll r = root(i, roots);
  		bad[r] += deg[i] - 2;
  	}
  }

  ll ans = 0;

  f(n) {
  	if(bad[i]) {
  		ans++;
  	}
  }

  cout << ans;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define inf (pow(10,18))
#define ll long long int
#define mod 1000000007
#define ntq(z)  long long int z; cin>>z; for(long long int i=0;i<z;i++)
#define fi(x9,y9) for(long long int i=x9;i<y9;i++)
#define fj(x9,y9) for(long long int j=x9;j<y9;j++)
#define fk(x9,y9) for(long long int k=x9;k<y9;k++)
#define f(z9) for(long long int i=0;i<z9;i++)
#define frev(z9) for(long long int i=z9-1;i>=0;i--)
#define endl "\n"
#define sz(a) int((a).size())
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define tr(c,i) for(typeof((c).begin() i = (c).begin(); i != (c).end(); i++)
#define present(c,x) ((c).find(x) != (c).end())
#define cpresent(c,x) (find(all(c),x) != (c).end())
#define stoi(s,n) stringstream str(s); str >> n;
#define get_vi(v, n) vi v(n); f(n){cin >> v[i];}

typedef vector< ll > vi;
typedef vector< pair<ll,ll> > vp;
typedef vector< vi > vvi;
typedef pair< ll,ll > ii;
typedef priority_queue <ll, vi, greater <ll> > min_heap;
typedef priority_queue <ll> max_heap;

void printprecise(double l,ll precision) {
	std::cout << std::fixed;
	std::cout << std::setprecision(precision);
	std::cout << l;
}

ll ncr(ll n, ll k)
{
	ll C[n + 1][k + 1];
	ll i, j;
	for (i = 0; i <= n; i++)
	{
		for (j = 0; j <= min(i, k); j++)
		{
			if (j == 0 || j == i)
				C[i][j] = 1;

			else
				C[i][j] = C[i - 1][j - 1] +
						  C[i - 1][j];
		}
	}

	return C[n][k];
}

ll power_wm(ll x, ll y, ll p) {
	ll res = 1;      // Initialize result

	x = x % p;  // Update x if it is more than or
				// equal to p

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x) % p;

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x) % p;
	}
	return res;
}

ll power(ll x, ll y) {
	ll res = 1;      // Initialize result

	while (y > 0)
	{
		// If y is odd, multiply x with result
		if (y & 1)
			res = (res * x);

		// y must be even now
		y = y >> 1; // y = y/2
		x = (x * x);
	}
	return res;
}

ll root(ll x,vi &roots){
  if(roots[x]!=x)
	roots[x]=root(roots[x],roots);
  return roots[x];
}

void unoin(ll p, ll q,vi &roots,vi &rank){
  ll rp=root(p,roots);
  ll rq=root(q,roots);
  if(rank[rq]<rank[rp]){
	roots[rq]=rp;
  }
  else if(rank[rp]>rank[rq]){
	roots[rp]=rq;
  }
  else{
	roots[rp]=rq;
	rank[rq]++;
  }

}

ll dig_sum(ll n) {
  ll s = 0;
  while(n) {
	s += n%10;
	n /=10;
  }
  return s;
}

ll gcd(ll a, ll b) {
	if(a < b) {
	  a = a + b;
	  b = a - b;
	  a = a - b;
	}
	if (b == 0)
	  return a;
	return gcd(b, a % b);
}

ll toD(ll x, ll y, ll m) {
  return x*m + y%m;
}

pair <ll, ll> twoD(ll p, ll m) {
  return (make_pair(p/m, p%m));
}

vi dist;
vvi g;

void dfs(ll p) {
  if(dist[p] != -1) {
	return;
  }

  dist[p] = 0;
  ll maxd = -1;

  f(g[p].size()) {
	  dfs(g[p][i]);
	  maxd = max(maxd, dist[g[p][i]]);
  }

  dist[p] = maxd + 1;
}

vi fact;

void calfact() {
  fact[0] = 1;
  fi(1, 1000001) {
	fact[i] = (fact[i-1] * i) % 998244353;
  }
}

int main() {

  ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
  #ifndef ONLINE_JUDGE
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
  #endif

  ll n, m;
  cin >> n >> m;

  vi roots(n), rank(n), deg(n);

  f(n) {
  	roots[i] = i;
  }

  ll x, y;

  f(m) {
  	cin >> x >> y;
  	unoin(--x, --y, roots, rank);
  	deg[x]++;
  	deg[y]++;
  }

  vi bad(n);

  f(n) {
  	if(deg[i] == 0) {
  		bad[i] = 1;
  	} else {
  		ll r = root(i, roots);
  		bad[r] += deg[i] - 2;
  	}
  }

  ll ans = 0;

  f(n) {
  	if(bad[i] <= -2) {
  		ans++;
  	}
  }

  cout << ans;

  return 0;
}


#include<bits/stdc++.h>

using namespace std;

#define ios               ios_base::sync_with_stdio(false);
#define ll                long long
#define ld                long double
#define db(w)             cout << "[" << #w << ": " << (w) << "]\n"
#define db2(w,x)          cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]\n"
#define db3(w,x,y)        cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]  [" << #y << ": " << (y) << "]\n"
#define db4(w,x,y,z)      cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]  [" << #y << ": " << (y) << "]  [" << #z << ": " << (z) << "]\n"
#define cn                13
#define sn                103
#define bn                1000007
#define M                 1000000007
#define inf               LLONG_MAX
#define c1                p*2+1
#define c2                p*2+2

bool cf[bn],rf[bn];
vector<pair<ll,ll>> g[bn];
ll c;

void dfs(ll x,ll px,ll r)
{
        if(cf[x]) return;
        if(rf[r]) return;
        rf[r] = 1;
        if(px != -1) c++;
        for(auto [to,rd] : g[x])
        {
                dfs(to,x,rd);
        }
        cf[x] = 1;
}

int main()
{
        ios;
        ll n,m; cin >> n >> m;
        for(ll i = 1; i <= m; i++)
        {
                ll x,y; cin >> x >> y;
                g[x].push_back({y,i}); g[y].push_back({x,i});
        }
        for(ll i = 1; i <= n; i++)
        {
                rf[-1] = 0;
                dfs(i,-1,-1);
        }
        cout << max(0ll,n-c);
}

/*

*/


#include<bits/stdc++.h>

using namespace std;

#define ios               ios_base::sync_with_stdio(false);
#define ll                long long
#define ld                long double
#define db(w)             cout << "[" << #w << ": " << (w) << "]\n"
#define db2(w,x)          cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]\n"
#define db3(w,x,y)        cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]  [" << #y << ": " << (y) << "]\n"
#define db4(w,x,y,z)      cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]  [" << #y << ": " << (y) << "]  [" << #z << ": " << (z) << "]\n"
#define cn                13
#define sn                103
#define bn                1000007
#define M                 1000000007
#define inf               LLONG_MAX
#define c1                p*2+1
#define c2                p*2+2

bool cf[bn],rf[bn];
ll pr[bn];
vector<pair<ll,ll>> g[bn];

void dfs(ll x,ll px,ll r)
{
        if(cf[x]) return;
        if(rf[r]) return;
        rf[r] = 1;
        pr[x] = px;
        for(auto [to,rd] : g[x])
        {
                dfs(to,x,rd);
        }
        cf[x] = 1;
}

int main()
{
        ios;
        ll n,m; cin >> n >> m;
        for(ll i = 1; i <= m; i++)
        {
                ll x,y; cin >> x >> y;
                g[x].push_back({y,i}); g[y].push_back({x,i});
        }
        for(ll i = 1; i <= n; i++)
        {
                rf[-1] = 0;
                dfs(i,-1,-1);
        }
        ll c = 0;
        for(ll i = 1; i <= n; i++)
        {
                if(pr[i] != -1) continue;
                c++;
        }
        cout << c;
}

/*

*/


#include<bits/stdc++.h>

using namespace std;

#define ios               ios_base::sync_with_stdio(false);
#define ll                long long
#define ld                long double
#define db(w)             cout << "[" << #w << ": " << (w) << "]\n"
#define db2(w,x)          cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]\n"
#define db3(w,x,y)        cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]  [" << #y << ": " << (y) << "]\n"
#define db4(w,x,y,z)      cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]  [" << #y << ": " << (y) << "]  [" << #z << ": " << (z) << "]\n"
#define cn                13
#define sn                103
#define bn                1000007
#define M                 1000000007
#define inf               LLONG_MAX
#define c1                p*2+1
#define c2                p*2+2

vector<ll> g[bn];
ll pa[bn],ok[bn];
set<ll> s;
bool cf[bn];

void dfs(ll x,ll px,ll pr)
{
        if(cf[x]) return;
        if(pa[x] == pr) { ok[pr] = 1; return;}
        pa[x] = pr;
        for(auto i : g[x])
        {
                if(i == px) continue;
                dfs(i,x,pr);
        }
        cf[x] = 1;
}

int main()
{
        ios;
        ll n,m; cin >> n >> m;
        for(ll i = 1; i <= m; i++)
        {
                ll x,y; cin >> x >> y;
                g[x].push_back(y); g[y].push_back(x);
        }
        for(ll i = 1; i <= n; i++)
        {
                dfs(i,-1,i);
        }
        for(ll i = 1; i <= n; i++) s.insert(pa[i]);
        ll sum = 0;
        for(auto i : s) sum += ok[i] == 0;
        cout << sum;

}

/*

*/


#include<bits/stdc++.h>

using namespace std;

#define ios               ios_base::sync_with_stdio(false);
#define ll                long long
#define ld                long double
#define db(w)             cout << "[" << #w << ": " << (w) << "]\n"
#define db2(w,x)          cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]\n"
#define db3(w,x,y)        cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]  [" << #y << ": " << (y) << "]\n"
#define db4(w,x,y,z)      cout << "[" << #w << ": " << (w) << "]  [" << #x << ": " << (x) << "]  [" << #y << ": " << (y) << "]  [" << #z << ": " << (z) << "]\n"
#define cn                13
#define sn                103
#define bn                1000007
#define M                 1000000007
#define inf               LLONG_MAX
#define c1                p*2+1
#define c2                p*2+2

bool cf[bn],rf[bn];
vector<pair<ll,ll>> g[bn];
ll c;

void dfs(ll x,ll px,ll r)
{
        if(cf[x]) return;
        if(rf[r]) return;
        rf[r] = 1;
        if(px != -1) c++;
        for(auto [to,rd] : g[x])
        {
                dfs(to,x,rd);
        }
        cf[x] = 1;
}

int main()
{
        ios;
        ll n,m; cin >> n >> m;
        for(ll i = 1; i <= m; i++)
        {
                ll x,y; cin >> x >> y;
                g[x].push_back({y,i}); g[y].push_back({x,i});
        }
        for(ll i = 1; i <= n; i++)
        {
                rf[-1] = 0;
                dfs(i,-1,-1);
        }
        cout << n-c;
}

/*

*/


#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <cmath>
#include <math.h>
#include <ctime>
#include <cstring>
#include <climits>
#include <sstream>
#include <array>
#include <tuple>
#include <set>
#include <iterator>
#include <cstdio>
#include <string>
#include <stack>
#include <valarray>
#include <utility>
#include <iomanip>
#include <list>
#include <numeric>
#include <regex>
#include <map>
#include <queue>
#include <deque>
#include <unordered_map>

using namespace std;

#define IOS         ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ll          long long
#define PI          3.1415926535
#define pb          push_back
#define ins         insert
#define INF         LLONG_MAX
#define mk          make_pair
#define lb(v,x)     lower_bound(all(v),x)
#define ub(v,x)     upper_bound(all(v),x)
#define Ln          length
#define ff          first
#define ss          second
#define rev         reverse
#define umap        unordered_map
#define endl        "\n"
#define max3(x,y,z)  max(x,max(y,z))
#define min3(x,y,z)  min(x,min(y,z))
#define sz(a)       (ll)a.size()
#define double      long double
#define minpq       priority_queue <ll,vector<ll>,greater<ll> >
#define fill(x,y)   memset(x,y,sizeof(x))
#define all(x)      (x).begin(), (x).end()
#define rall(x)     (x).rbegin(), (x).rend()
#define MOD         1000000007
#define bp(n)       __builtin_popcount(n)
#define mxt(a)      *(max_element(a.begin(),a.end()))
#define mnt(a)      *(min_element(a.begin(),a.end())
#define unique_sort(c) (sort(all(c)), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define rep(i, a, b) for(ll i = (a); i<= (b); ++i)
#define re(i,n)      for(ll i = 0; i < n; ++i)
const ll N = 2e5 + 7;
typedef pair<ll,ll>   pii;
typedef vector<pii>   vpii;
typedef vector<ll>    vll;
const string alpha = "abcdefghijklmnopqrstuvwxyz";
ll power(ll x,ll y){ll res=1;x=x;while(y>0){if(y&1)res=(res*x);y=y>>1;x=(x*x);}return res;}
template<typename T> T gcd(T a,T b){ if(a==0) return b; return gcd(b%a,a); }
template<typename T> T powm(T a,T b, ll m){T cnt=1; while(b>0){ if(b%2==1) cnt=(cnt*a)%m; b/=2; a=(a*a)%m; }return cnt%m;}
ll ncr(ll n,ll r){ll res=1;if(r>n)return 0;if(r>n-r)r=n-r;for(ll i=0;i<r;i++){res*=(n-i);res/=(i+1);}return res;}
ll sqr(ll x) { return x * x;}
// always use 1ll*ans to avoid signed integer overflow;
ll n,m;
vector<ll> g[100010];
vector<bool> vis(1e5+10,false);
ll edges,nodes;

void dfs(int i){
    if(vis[i]){
        return;
    }
    vis[i] = true;
    nodes++;
    edges+= sz(g[i]);
    for(auto j:g[i]){
        dfs(j);
    }

}

int solve(){
    re(i,m){
        ll a,b;
        cin >> a>>b;
        g[a].pb(b);
        g[b].pb(a);
    }
    ll ans=0;
    rep(i,1,n){
        if(!vis[i]){
            edges = 0;
            nodes = 0;
            dfs(i);
            edges/=2;
            if(edges<nodes) ans++;
        }
    }
    cout << ans;
    return 0;
}

int main()
{
    IOS;
    int tc;
    tc=1;
    //cin >> tc;
    while(tc--)
        solve();
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <cmath>
#include <math.h>
#include <ctime>
#include <cstring>
#include <climits>
#include <sstream>
#include <array>
#include <tuple>
#include <set>
#include <iterator>
#include <cstdio>
#include <string>
#include <stack>
#include <valarray>
#include <utility>
#include <iomanip>
#include <list>
#include <numeric>
#include <regex>
#include <map>
#include <queue>
#include <deque>
#include <unordered_map>

using namespace std;

#define IOS         ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ll          long long
#define PI          3.1415926535
#define pb          push_back
#define ins         insert
#define INF         LLONG_MAX
#define mk          make_pair
#define lb(v,x)     lower_bound(all(v),x)
#define ub(v,x)     upper_bound(all(v),x)
#define Ln          length
#define ff          first
#define ss          second
#define rev         reverse
#define umap        unordered_map
#define endl        "\n"
#define max3(x,y,z)  max(x,max(y,z))
#define min3(x,y,z)  min(x,min(y,z))
#define sz(a)       (ll)a.size()
#define double      long double
#define minpq       priority_queue <ll,vector<ll>,greater<ll> >
#define fill(x,y)   memset(x,y,sizeof(x))
#define all(x)      (x).begin(), (x).end()
#define rall(x)     (x).rbegin(), (x).rend()
#define MOD         1000000007
#define bp(n)       __builtin_popcount(n)
#define mxt(a)      *(max_element(a.begin(),a.end()))
#define mnt(a)      *(min_element(a.begin(),a.end())
#define unique_sort(c) (sort(all(c)), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define rep(i, a, b) for(ll i = (a); i<= (b); ++i)
#define re(i,n)      for(ll i = 0; i < n; ++i)
const ll N = 2e5 + 7;
typedef pair<ll,ll>   pii;
typedef vector<pii>   vpii;
typedef vector<ll>    vll;
const string alpha = "abcdefghijklmnopqrstuvwxyz";
ll power(ll x,ll y){ll res=1;x=x;while(y>0){if(y&1)res=(res*x);y=y>>1;x=(x*x);}return res;}
template<typename T> T gcd(T a,T b){ if(a==0) return b; return gcd(b%a,a); }
template<typename T> T powm(T a,T b, ll m){T cnt=1; while(b>0){ if(b%2==1) cnt=(cnt*a)%m; b/=2; a=(a*a)%m; }return cnt%m;}
ll ncr(ll n,ll r){ll res=1;if(r>n)return 0;if(r>n-r)r=n-r;for(ll i=0;i<r;i++){res*=(n-i);res/=(i+1);}return res;}
ll sqr(ll x) { return x * x;}
// always use 1ll*ans to avoid signed integer overflow;
ll n,m;
vector<ll> g[100010];
vector<bool> vis(1e5+10,false);
ll edges,nodes;

void dfs(int i){
    if(vis[i]){
        return;
    }
    vis[i] = true;
    nodes++;
    edges+= sz(g[i]);
    for(auto j:g[i]){
        dfs(j);
    }

}
int solve(){
    cin>>n>>m;
    re(i,m){
        ll a,b;
        cin >> a>>b;
        g[a].pb(b);
        g[b].pb(a);
    }
    ll ans =0;
    rep(i,1,n){
        if(!vis[i]){
            edges = 0;
            nodes = 0;
            dfs(i);
            edges/=2;
            if(edges<nodes) ans++;
        }
    }
    cout << ans;
    return 0;
}

int main()
{
    IOS;
    int tc;
    tc=1;
    //cin >> tc;
    while(tc--)
        solve();
    return 0;
}


#include <iostream>
#include <algorithm>
#include <vector>
#include <string.h>
#include <cmath>
#include <math.h>
#include <ctime>
#include <cstring>
#include <climits>
#include <sstream>
#include <array>
#include <tuple>
#include <set>
#include <iterator>
#include <cstdio>
#include <string>
#include <stack>
#include <valarray>
#include <utility>
#include <iomanip>
#include <list>
#include <numeric>
#include <regex>
#include <map>
#include <queue>
#include <deque>
#include <unordered_map>

using namespace std;

#define IOS         ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define ll          long long
#define PI          3.1415926535
#define pb          push_back
#define ins         insert
#define INF         LLONG_MAX
#define mk          make_pair
#define lb(v,x)     lower_bound(all(v),x)
#define ub(v,x)     upper_bound(all(v),x)
#define Ln          length
#define ff          first
#define ss          second
#define rev         reverse
#define umap        unordered_map
#define endl        "\n"
#define max3(x,y,z)  max(x,max(y,z))
#define min3(x,y,z)  min(x,min(y,z))
#define sz(a)       (ll)a.size()
#define double      long double
#define minpq       priority_queue <ll,vector<ll>,greater<ll> >
#define fill(x,y)   memset(x,y,sizeof(x))
#define all(x)      (x).begin(), (x).end()
#define rall(x)     (x).rbegin(), (x).rend()
#define MOD         1000000007
#define bp(n)       __builtin_popcount(n)
#define mxt(a)      *(max_element(a.begin(),a.end()))
#define mnt(a)      *(min_element(a.begin(),a.end())
#define unique_sort(c) (sort(all(c)), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#define rep(i, a, b) for(ll i = (a); i<= (b); ++i)
#define re(i,n)      for(ll i = 0; i < n; ++i)
const ll N = 2e5 + 7;
typedef pair<ll,ll>   pii;
typedef vector<pii>   vpii;
typedef vector<ll>    vll;
const string alpha = "abcdefghijklmnopqrstuvwxyz";
ll power(ll x,ll y){ll res=1;x=x;while(y>0){if(y&1)res=(res*x);y=y>>1;x=(x*x);}return res;}
template<typename T> T gcd(T a,T b){ if(a==0) return b; return gcd(b%a,a); }
template<typename T> T powm(T a,T b, ll m){T cnt=1; while(b>0){ if(b%2==1) cnt=(cnt*a)%m; b/=2; a=(a*a)%m; }return cnt%m;}
ll ncr(ll n,ll r){ll res=1;if(r>n)return 0;if(r>n-r)r=n-r;for(ll i=0;i<r;i++){res*=(n-i);res/=(i+1);}return res;}
ll sqr(ll x) { return x * x;}
// always use 1ll*ans to avoid signed integer overflow;
ll n,m,u,v,cnt=0;
set <ll> ad[N];
umap <ll,bool> mp;
int solve(){
    cin>>n>>m;
    while(m--){
        cin>>u>>v;
        ad[u].ins(v);
        ad[v].ins(u);
    }
    rep(i,1,n){
        if(!sz(ad[i])) continue;
        for(auto j: ad[i]){
            if(mp[i])
            {
                mp[j]=true;
                ad[j].erase(i);
            }
            else {
                mp[i]=true;
                ad[j].erase(i);
            }
        }
    }
    rep(i,1,n) if(!mp[i]) cnt++;
    cout<<cnt<<endl;
    return 0;
}

int main()
{
    IOS;
    int tc;
    tc=1;
    //cin >> tc;
    while(tc--)
        solve();
    return 0;
}


#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
#define pb push_back
unordered_map<int,vector<int> > g;
unordered_map<int,int> indeg;
unordered_map<int,int> parent;
unordered_map<int,bool> visited;
int ans=0;

void dfs(int i,int p)
{
    visited[i]=true;

    for(auto j:g[i])
    {
        if((indeg[j]==0 || indeg[i]==0) )
        {
            dfs(j,i);
        }
    }
 //   cout<<"i : "<<i<<"  indeg[i] : "<<indeg[i]<<"  p : "<<p<<"  indeg[p] : "<<indeg[p]<<"\n";
    if(indeg[p]==0)
    {
        if(indeg[i]>=2)
        {
            indeg[p]++;
            indeg[i]--;
            parent[p]=i;
        }
    }
    if(indeg[i]==0)
    {
        if(indeg[p]<=1)
        {
            return;
        }
        else
        {
            indeg[p]--;
            indeg[i]++;
            parent[p]=i;
        }
    }
}

int main()
{
    g.clear();
    indeg.clear();
    parent.clear();
    parent[1]=0;

    int n,m;
    cin>>n>>m;
    int i,j,x,y;
    for(i=1;i<=m;++i)
    {
        cin>>x>>y;
        g[x].pb(y);
        indeg[y]++;
        parent[y]=x;
    }
    for(i=1;i<=n;++i)
    {
        if(!visited[i] || indeg[i]==0)
        {
            dfs(i,parent[i]);
        }
    }
    for(i=1;i<=n;++i)
    {
        if(indeg[i]==0)
            ++ans;
    }
    cout<<ans;

    return 0;
}


#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
#define pb push_back
unordered_map<int,vector<int> > g;
unordered_map<int,int> indeg;
unordered_map<int,int> parent;
unordered_map<int,bool> visited;
int ans=0;

void dfs(int i,int p)
{
    visited[i]=true;

    for(auto j:g[i])
    {
        if((!visited[j] || indeg[j]==0 || indeg[i]==0) )
        {
            dfs(j,i);
        }
    }
 //   cout<<"i : "<<i<<"  indeg[i] : "<<indeg[i]<<"  p : "<<p<<"  indeg[p] : "<<indeg[p]<<"\n";
    if(indeg[p]==0)
    {
        if(indeg[i]>=2)
        {
            indeg[p]++;
            indeg[i]--;
            parent[p]=i;
        }
    }
    if(indeg[i]==0)
    {
        if(indeg[p]<=1)
        {
            return;
        }
        else
        {
            indeg[p]--;
            indeg[i]++;
            parent[p]=i;
        }
    }
}

int main()
{
    g.clear();
    indeg.clear();
    parent.clear();
    parent[1]=0;

    int n,m;
    cin>>n>>m;
    int i,j,x,y;
    for(i=1;i<=m;++i)
    {
        cin>>x>>y;
        g[x].pb(y);
        indeg[y]++;
        parent[y]=x;
    }
    for(i=1;i<=n;++i)
    {
        if(!visited[i] || indeg[i]==0)
        {
            dfs(i,parent[i]);
        }
    }
    for(i=1;i<=n;++i)
    {
        if(indeg[i]==0)
            ++ans;
    }
    cout<<ans;

    return 0;
}


#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
#define pb push_back
unordered_map<int,vector<int> > g;
unordered_map<int,bool> visited;
int edges=0,nodes=0;

void dfs(int i)
{
    visited[i]=true;
    ++nodes;
    edges+=g[i].size();

    for(auto j:g[i])
    {
        if(!visited[j])
            dfs(j);
    }
}

int main()
{
    int n,m;
    cin>>n>>m;
    int i,j,x,y;
    for(i=1;i<=m;++i)
    {
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
    }

    int ans=0;
    //if tree ans is 1 else 0 (count for each component) (reason : n-1 edges with n nodes in a tree , so at best 1 node will be left with no indegree)
    for(i=1;i<=n;++i)
    {
        if(!visited[i])
        {
            edges=0;nodes=0;
            dfs(i);
            edges/=2;
            if(nodes==edges+1)
                ++ans;
        }
    }
    cout<<ans;

    return 0;
}


#include<iostream>
#include<unordered_map>
#include<map>
#include<vector>
using namespace std;
#define pb push_back
unordered_map<int,vector<int> > g;
unordered_map<int,int> indeg;
map<int,int> parent;
unordered_map<int,bool> visited;
int ans=0;

void dfs(int i,int p)
{
    visited[i]=true;

    for(auto j:g[i])
    {
        if((indeg[j]==0 || indeg[i]==0) && !visited[j] )
        {
            parent[j]=i;
            dfs(j,i);
        }
    }
//    cout<<"i : "<<i<<"  indeg["<<i<<"] : "<<indeg[i]<<"  p : "<<p<<"  indeg["<<p<<"] : "<<indeg[p]<<"\n";
    if(indeg[p]==0 && p!=0)
    {
        if(indeg[i]>=2)
        {
            indeg[p]++;
            indeg[i]--;
 //           cout<<"after change - indeg["<<p<<"] : "<<indeg[p]<<"  indeg["<<i<<"] : "<<indeg[i]<<"\n";
        }
        else
        {
 //           cout<<"can't change \n";
        }
    }
    if(indeg[i]==0)
    {
        if(indeg[p]<=1)
        {
            if(p!=0)
 //               cout<<"can't change \n";
            return;
        }
        else
        {
            indeg[p]--;
            indeg[i]++;
//            cout<<"after change - indeg["<<p<<"] : "<<indeg[p]<<"  indeg["<<i<<"] : "<<indeg[i]<<"\n";
        }
    }
}

int main()
{
    g.clear();
    indeg.clear();
    parent.clear();
    visited.clear();

    int n,m;
    cin>>n>>m;
    int i,j,x,y;
    for(i=1;i<=m;++i)
    {
        cin>>x>>y;
        g[x].pb(y);
        g[y].pb(x);
        indeg[y]++;
    }
    for(i=1;i<=n;++i)
    {
        if(!visited[i] || indeg[i]==0 || indeg[i]>=2)
        {
            dfs(i,parent[i]);
        }
    }
    for(i=1;i<=n;++i)
    {
        if(indeg[i]==0)
            ++ans;
    }
    cout<<ans;

    return 0;
}
/*
4 3
2 1
1 3
4 3
*/


#include<iostream>
#include<unordered_map>
#include<vector>
using namespace std;
#define pb push_back
unordered_map<int,vector<int> > g;
unordered_map<int,int> indeg;
unordered_map<int,int> parent;
unordered_map<int,bool> visited;
int ans=0;

void dfs(int i,int p)
{
    visited[i]=true;

    for(auto j:g[i])
    {
        if((!visited[j] || indeg[j]==0 || indeg[i]==0) )
        {
            dfs(j,i);
        }
    }
 //   cout<<"i : "<<i<<"  indeg[i] : "<<indeg[i]<<"  p : "<<p<<"  indeg[p] : "<<indeg[p]<<"\n";
    if(indeg[p]==0)
    {
        if(indeg[i]>=2)
        {
            indeg[p]++;
            indeg[i]--;
            parent[p]=i;
        }
    }
    if(indeg[i]==0)
    {
        if(indeg[p]<=1)
        {
            ++ans;
            return;
        }
        else
        {
            indeg[p]--;
            indeg[i]++;
            parent[p]=i;
        }
    }
}

int main()
{
    g.clear();
    indeg.clear();
    parent.clear();
    parent[1]=0;

    int n,m;
    cin>>n>>m;
    int i,j,x,y;
    for(i=1;i<=m;++i)
    {
        cin>>x>>y;
        g[x].pb(y);
        indeg[y]++;
        parent[y]=x;
    }
    for(i=1;i<=n;++i)
    {
        if(!visited[i] || indeg[i]==0)
        {
            dfs(i,parent[i]);
        }
    }
    cout<<ans;

    return 0;
}


// In the name of GOD
#include<bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<"\n";
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\n";
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<"\n";

#define     IOS         ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define 	setprecn(x) cout<<fixed<<setprecision(x);
#define 	ll          long long int
#define 	pb          push_back
#define 	pll         pair<ll,ll>
#define 	vll         vector<ll>
#define 	ff          first
#define 	ss          second
#define 	all(a)      (a).begin(),(a).end()
#define 	sz(x)       (ll)x.size()
#define 	mod         1000000007
#define 	inf         10000000000000007
#define 	rep(i,n)    for(ll i=0;i<n;i++)
#define 	repe(i,a,b) for(ll i=a;i<b;i++)
#define 	lbnd        lower_bound
#define 	ubnd        upper_bound
#define 	bs          binary_search

ll power(ll a,ll b,ll m=mod)
{
	if(b==0)
		return 1;
	if(b==1)
		return a;
	ll c=power(a,b/2,m);
	if(b%2==0)
		return((c%m)*(c%m))%m;
	return ((((c%m)*(c%m))%m)*(a%m))%m;
}

/********************************************************/
//	d.erase(unique(all(d)), d.end());

ll p=0,vis[100005]={0};
vector<ll> g[100005];

void dfs(ll x,ll b,ll par)
{
	vis[x]=1;
	// debug3(x,b,x);
	rep(i,g[x].size())
	{
		if(vis[g[x][i]] && b==0 && g[x][i]!=par) b=1;
	}
	rep(i,g[x].size())
	{
		if(vis[g[x][i]]==0)
		{
			if(b!=1)
			{
				b=1;
				dfs(g[x][i],0,x);
			}
			else
				dfs(g[x][i],1,x);
		}
	}
	// debug3(x,b,x);
	p+= (!b);
}

int main()
{
	IOS;
	ll n,k,m,i,j,c=0,cs=0,t;
	t=1;

	// cin>>t;
	string s;
	while(t--)
	{
		cin>>n>>m;
		// n=s.length();

		rep(i,m)
		{
			cin>>j>>k;
			g[j].pb(k);
			g[k].pb(j);
		}
		p=0;
		repe(i,1,n+1)
		{
			if(vis[i]==0)
			{
				dfs(i,0,0);
			}
		}
		cout<<p;

		cout<<"\n";
	}
	return 0;
}


// In the name of GOD
#include<bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<"\n";
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\n";
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<"\n";

#define     IOS         ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define 	setprecn(x) cout<<fixed<<setprecision(x);
#define 	ll          long long int
#define 	pb          push_back
#define 	pll         pair<ll,ll>
#define 	vll         vector<ll>
#define 	ff          first
#define 	ss          second
#define 	all(a)      (a).begin(),(a).end()
#define 	sz(x)       (ll)x.size()
#define 	mod         1000000007
#define 	inf         10000000000000007
#define 	rep(i,n)    for(ll i=0;i<n;i++)
#define 	repe(i,a,b) for(ll i=a;i<b;i++)
#define 	lbnd        lower_bound
#define 	ubnd        upper_bound
#define 	bs          binary_search

ll power(ll a,ll b,ll m=mod)
{
	if(b==0)
		return 1;
	if(b==1)
		return a;
	ll c=power(a,b/2,m);
	if(b%2==0)
		return((c%m)*(c%m))%m;
	return ((((c%m)*(c%m))%m)*(a%m))%m;
}

/********************************************************/
//	d.erase(unique(all(d)), d.end());

ll p=0,vis[100005]={0},e=0;;
vector<ll> g[100005];

void dfs(ll x,ll pr)
{
	vis[x]=1;
	p++;
	// debug3(x,b,x);
	rep(i,g[x].size())
	{
		if(vis[g[x][i]]==0)
		{

			dfs(g[x][i],pr);
		}
		if(g[x][i]!=pr) e++;
	}
}

int main()
{
	IOS;
	ll n,k,m,i,j,c=0,cs=0,t;
	t=1;

	// cin>>t;
	string s;
	while(t--)
	{
		cin>>n>>m;
		// n=s.length();

		rep(i,m)
		{
			cin>>j>>k;
			g[j].pb(k);
			g[k].pb(j);
		}
		p=0;
		repe(i,1,n+1)
		{
			if(vis[i]==0)
			{
				p=e=0;
				dfs(i,0);
				e/=2;
				if(e<=p-1) c++;
				// debug3(i,p,e);
			}
		}
		cout<<c;

		cout<<"\n";
	}
	return 0;
}


// In the name of GOD
#include<bits/stdc++.h>
using namespace std;

#define debug(x) cout<<#x<<" :: "<<x<<"\n";
#define debug2(x,y) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\n";
#define debug3(x,y,z) cout<<#x<<" :: "<<x<<"\t"<<#y<<" :: "<<y<<"\t"<<#z<<" :: "<<z<<"\n";

#define     IOS         ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define 	setprecn(x) cout<<fixed<<setprecision(x);
#define 	ll          long long int
#define 	pb          push_back
#define 	pll         pair<ll,ll>
#define 	vll         vector<ll>
#define 	ff          first
#define 	ss          second
#define 	all(a)      (a).begin(),(a).end()
#define 	sz(x)       (ll)x.size()
#define 	mod         1000000007
#define 	inf         10000000000000007
#define 	rep(i,n)    for(ll i=0;i<n;i++)
#define 	repe(i,a,b) for(ll i=a;i<b;i++)
#define 	lbnd        lower_bound
#define 	ubnd        upper_bound
#define 	bs          binary_search

ll power(ll a,ll b,ll m=mod)
{
	if(b==0)
		return 1;
	if(b==1)
		return a;
	ll c=power(a,b/2,m);
	if(b%2==0)
		return((c%m)*(c%m))%m;
	return ((((c%m)*(c%m))%m)*(a%m))%m;
}

/********************************************************/
//	d.erase(unique(all(d)), d.end());

ll p=0,vis[100005]={0};
vector<ll> g[100005];

void dfs(ll x,ll b,ll par)
{
	vis[x]=1;
	// debug3(x,b,x);
	rep(i,g[x].size())
	{
		if(vis[g[x][i]]==0)
		{
			if(b!=1)
			{
				b=1;
				dfs(g[x][i],0,x);
			}
			else
				dfs(g[x][i],1,x);
		}
		else if(b==0 && g[x][i]!=par) b=1;
	}
	// debug3(x,b,x);
	p+= (!b);
}

int main()
{
	IOS;
	ll n,k,m,i,j,c=0,cs=0,t;
	t=1;

	// cin>>t;
	string s;
	while(t--)
	{
		cin>>n>>m;
		// n=s.length();

		rep(i,m)
		{
			cin>>j>>k;
			g[j].pb(k);
			g[k].pb(j);
		}
		p=0;
		repe(i,1,n+1)
		{
			if(vis[i]==0)
			{
				dfs(i,0,0);
			}
		}
		cout<<p;

		cout<<"\n";
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,canh,cnt,ans=0;
vector<int> g[100001];
void DFS(int u){
    used[u]=1;
    cnt++;
    dem+=g[u].size();
    for(int i=0;i<g[u].size();i++){
        if(used[g[u][i]]==0){
            DFS(g[u][i]);
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for(int i=1;i<=n;i++){
        if(used[i]==0){
            cnt=0,canh=0;
            DFS(i);
            if((canh/2)<cnt){
                ans++;
            }
        }
    }
    cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,canh,cnt,ans=0,used[100001];
vector<int> g[100001];
void DFS(int u){
    used[u]=1;
    cnt++;
    canh+=g[u].size();
    for(int i=0;i<g[u].size();i++){
        if(used[g[u][i]]==0){
            DFS(g[u][i]);
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for(int i=1;i<=n;i++){
        if(used[i]==0){
            cnt=0,canh=0;
            DFS(i);
            if((canh/2)<cnt){
                ans++;
            }
        }
    }
    cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,canh,cnt,ans=0,used[100001];
vector<int> g[100001];
void DFS(int u){
    used[u]=1;
    cnt++;
    dem+=g[u].size();
    for(int i=0;i<g[u].size();i++){
        if(used[g[u][i]]==0){
            DFS(g[u][i]);
        }
    }
}
int main(){
    cin>>n>>m;
    for(int i=1;i<=m;i++){
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for(int i=1;i<=n;i++){
        if(used[i]==0){
            cnt=0,canh=0;
            DFS(i);
            if((canh/2)<cnt){
                ans++;
            }
        }
    }
    cout<<ans;
}


#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
#include<queue>
#include<unordered_map>
#include<map>
#include<stack>
//#include<bits/stdc++.h>
#include<string.h>
#define FASTIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define fr first
#define sc second
#define respr(fir,sec) for(int i=0;i<=fir;i++){for(int j=0;j<=sec;j++){cout << res[i][j] << " ";}cout << "\n";}
#define pb push_back
//#define INF (1LL<<31)
using namespace std;
const int mod = 1000000007;
const ll MAX = 1000000000000000000;
typedef pair<int,ll> pii;
typedef pair<int,int> pi;
typedef tuple<long long,int> tp;
typedef tuple<int,int,long long> tu;
typedef multimap<pii , int> mpp;
typedef priority_queue< pi , vector<pi>, greater<pi>>  minheap;
typedef priority_queue<pii , vector<pii>> maxheap;
const int nax = 50+5;
#define sz(x) (int)x.size()
char arr[nax][nax];
vector<vector<bool>> visited(nax,vector<bool>(nax));
vector<pi> temp;
int d1[] = {-1,0,1,0};
int d2[] = {0,1,0,-1};
int n,m,k;

void dfs(int u, int v, bool &flag){
	visited[u][v]=true;
	if(u==0 || u == n-1 || v==0 || v==m-1)
		flag = true;
	temp.push_back({u,v});
	for(int i=0;i<4;i++)
	{
		int x = u+d1[i];
		int y = v+d2[i];
		if(x >= 0 && x<n && y >= 0 && y<m){
			if(!visited[x][y] && arr[x][y]=='.'){
				dfs(x,y,flag);
			}
		}
	}
}

bool compareInterval(const vector<pi> &a, const vector<pi> &b){
	return a.size()< b.size();
}

int main()
{
	FASTIO;
	cin >> n >> m >> k;

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			cin >> arr[i][j];
		}
	}

	vector<vector<pi>> comp;

	for(int i=0;i<n;i++){
		for(int j=0;j<m;j++){
			if(!visited[i][j] && arr[i][j]=='.'){
				bool flag = false;
				dfs(i, j,flag);
				//cout << flag << " " << i << " " <<  j <<  " here \n";
				if(!flag)
					comp.push_back(temp);
				temp.clear();
			}
		}
	}

	sort(comp.begin(), comp.end(), compareInterval);

	int cap = comp.size();

	//cout << cap << "\n";

	int ans=0, start=0;

	while(cap>k){
		ans += comp[start].size();
		for(auto po : comp[start])
		{
			arr[po.fr][po.sc] = '*';
		}
		cap--;
		start++;
	}
	cout << ans << "\n";
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
			cout << arr[i][j];
		cout << "\n";
	}
	return 0;
}


#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
#include<queue>
#include<unordered_map>
#include<map>
#include<stack>
//#include<bits/stdc++.h>
#include<string.h>
#define FASTIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define fr first
#define sc second
#define respr(fir,sec) for(int i=0;i<=fir;i++){for(int j=0;j<=sec;j++){cout << res[i][j] << " ";}cout << "\n";}
#define pb push_back
//#define INF (1LL<<31)
using namespace std;
const int mod = 1000000007;
const ll MAX = 1000000000000000000;
typedef pair<int,ll> pii;
typedef pair<int,int> pi;
typedef tuple<long long,int> tp;
typedef tuple<int,int,long long> tu;
typedef multimap<pii , int> mpp;
typedef priority_queue< pi , vector<pi>, greater<pi>>  minheap;
typedef priority_queue<pii , vector<pii>> maxheap;
const int nax = 1e5+5;
#define sz(x) (int)x.size()
vector<int> graph[nax];
vector<bool> visited1(nax), visited2(nax);

void dfs(int s, int &cv , int &ce){
	visited1[s]=1;
	cv++;
	ce += graph[s].size();
	for(auto v : graph[s])
	{
		if(!visited1[v])
		{
			dfs(v, cv,ce);
		}
	}
}

int main()
{
	FASTIO;
	int n,m;
	cin >> n  >> m;
	vector<pi> edges(m);
	vector<int> arr(n+1);
	int x,y;
	for(int i=0;i<m;i++){
		cin >> x >> y;
		graph[x].push_back(y);
		graph[y].push_back(x);
	}

	int cnt=0;
	for(int i=1;i<=n;i++){
		if(!visited1[i]){
			int cv=0,ce=0;
			dfs(i,cv,ce);
			ce /= 2;
			//cout << cv << " " << ce << "\n";
			if(ce == cv-1)
				cnt +=1;
		}
	}

	cout << cnt << "\n";

	return 0;
}


#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
#include<queue>
#include<unordered_map>
#include<map>
#include<stack>
//#include<bits/stdc++.h>
#include<string.h>
#define FASTIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define fr first
#define sc second
#define respr(fir,sec) for(int i=0;i<=fir;i++){for(int j=0;j<=sec;j++){cout << res[i][j] << " ";}cout << "\n";}
#define pb push_back
//#define INF (1LL<<31)
using namespace std;
const int mod = 1000000007;
const ll MAX = 1000000000000000000;
typedef pair<int,ll> pii;
typedef pair<int,int> pi;
typedef tuple<long long,int> tp;
typedef tuple<int,int,long long> tu;
typedef multimap<pii , int> mpp;
typedef priority_queue< pi , vector<pi>, greater<pi>>  minheap;
typedef priority_queue<pii , vector<pii>> maxheap;
const int nax = 1e5+5;
#define sz(x) (int)x.size()
int main()
{
	FASTIO;
	int n,m;
	cin >> n  >> m;
	vector<pi> edges(m);
	vector<int> arr(n+1);
	int x,y;
	for(int i=0;i<m;i++){
		cin >> x >> y;
		arr[x]++;
		arr[y]++;
		edges[i] = {x,y};
	}
	vector<bool> visited(n+1);

	for(int i=0;i<m;i++){

		tie(x,y) = edges[i];
		if(arr[x]>arr[y] || visited[x])
			visited[y]=1;
		else
			visited[x]=1;

		arr[x]--;
		arr[y]--;
	}

	int cnt=0;
	for(int i=1;i<=n;i++)
	{
		if(!visited[i])
			cnt++;
	}

	cout << cnt << "\n";

	return 0;
}


#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<set>
#include<cmath>
#include<queue>
#include<unordered_map>
#include<map>
#include<stack>
//#include<bits/stdc++.h>
#include<string.h>
#define FASTIO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define ll long long
#define fr first
#define sc second
#define respr(fir,sec) for(int i=0;i<=fir;i++){for(int j=0;j<=sec;j++){cout << res[i][j] << " ";}cout << "\n";}
#define pb push_back
//#define INF (1LL<<31)
using namespace std;
const int mod = 1000000007;
const ll MAX = 1000000000000000000;
typedef pair<int,ll> pii;
typedef pair<int,int> pi;
typedef tuple<long long,int> tp;
typedef tuple<int,int,long long> tu;
typedef multimap<pii , int> mpp;
typedef priority_queue< pi , vector<pi>, greater<pi>>  minheap;
typedef priority_queue<pii , vector<pii>> maxheap;
const int nax = 1e5+5;
#define sz(x) (int)x.size()
vector<int> graph[nax];
vector<bool> visited1(nax), visited2(nax);

void dfs(int s, int p){
	visited1[s]=1;

	for(auto v : graph[s])
	{
		if(v==p)
			continue;
		if(!visited1[v]){
			visited2[v] = 1;
			dfs(v, s);
		}
		else
			visited2[s] = 1;
	}
}

int main()
{
	FASTIO;
	int n,m;
	cin >> n  >> m;
	vector<pi> edges(m);
	vector<int> arr(n+1);
	int x,y;
	for(int i=0;i<m;i++){
		cin >> x >> y;
		graph[x].push_back(y);
		graph[y].push_back(x);
	}

	for(int i=1;i<=n;i++){
		if(!visited1[i]){
			dfs(i, -1);
		}
	}

	int cnt=0;
	for(int i=1;i<=n;i++)
	{
		if(!visited2[i])
			cnt++;
	}

	cout << cnt << "\n";

	return 0;
}


#include <bits/stdc++.h>
#define pb          push_back
#define pii         pair<int,int>
#define vi          vector<int>
#define vii         vector<pii>
#define mi          map<int,int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define x           first
#define y           second
#define sz(x)       (int)x.size()
#define endl        '\n'
#define hell        1000000007
#define rep(i,a,b)  for(int i=a;i<b;i++)
#define mod			1000000007
using namespace std;
long long cnt , cnt_e;
vector< int > g[100001];
int vis[100001];
int flag=0;
void dfs( int x , int p)
{
  vis[x] = 1;
  for( int u : g[x] )
  {
    if(!vis[u])
    dfs(u,x);
     else if(vis[u] && u!=p )
        flag = 1;
     }
  }

int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
		  // cout<<i;
			flag=0;
			dfs(2,-1);
		//	cout<<flag;
			if(!flag)
			ans++;
		}
	}
	cout<<ans;
}


#include <bits/stdc++.h>
#define pb          push_back
#define pii         pair<int,int>
#define vi          vector<int>
#define vii         vector<pii>
#define mi          map<int,int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define x           first
#define y           second
#define sz(x)       (int)x.size()
#define endl        '\n'
#define hell        1000000007
#define rep(i,a,b)  for(int i=a;i<b;i++)
#define mod			1000000007
using namespace std;
long long cnt , cnt_e;
vector< int > g[100001];
int vis[100001];
int flag=0;
void dfs( int x , int p)
{
  vis[x] = 1;
  for( int u : g[x] )
  {
    if(!vis[u])
    dfs(u,x);
     else if(vis[u] && u!=p )
        flag = 1;
     }
  }

int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
		  // cout<<i;
			flag=0;
			dfs(i,-1);
		//	cout<<flag;
			if(!flag)
			ans++;
		}
	}
	cout<<ans;
}


#include <bits/stdc++.h>
#define pb          push_back
#define pii         pair<int,int>
#define vi          vector<int>
#define vii         vector<pii>
#define mi          map<int,int>
#define mii         map<pii,int>
#define all(a)      (a).begin(),(a).end()
#define x           first
#define y           second
#define sz(x)       (int)x.size()
#define endl        '\n'
#define hell        1000000007
#define rep(i,a,b)  for(int i=a;i<b;i++)
#define mod			1000000007
using namespace std;
long long cnt , cnt_e;
vector< int > g[100001];
int vis[100001];
bool flag=0;
void dfs(int node, int par)
{
    //cout<<g[4][0];
   // cout<<node;
	vis[node]=1;
	for(auto i:g[node])
	{
	    //cout<<i<<endl;
		if(vis[i]==0)
		dfs(i,node);
	    else if(i!=par && vis[i]==1)
	   // cout<<i<<par;
	    flag=1;
	}
}
int main()
{
	int n,m;
	cin>>n>>m;
	for(int i=0;i<m;i++)
	{
		int a,b;
		cin>>a>>b;
		g[a].pb(b);
		g[b].pb(a);
	}
	int ans=0;
	for(int i=1;i<=n;i++)
	{
		if(!vis[i])
		{
		  // cout<<i;
			flag=0;
			dfs(2,-1);
		//	cout<<flag;
			if(!flag)
			ans++;
		}
	}
	cout<<ans;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int ans,cur;
vector<vector<int>>g(2 * 10e5);
vector<bool>used(100005);
void dfs(int x,int f)
{
    if(used[x])
    {
        cur = 0;
        return;
    }
    used[x] = 1;
    for(int i = 0;i < g[x].size(); i++)
    {
        int v = g[x][i];
        if(v != f)
        {

            dfs(v,x);
        }
    }
}
int32_t main()
{
    int n, x;
	cin >> n >> x;
	vector<int>rb(2 * 10e5),ra(2 * 10e5);
	for(int i = 1;i < n; i++)
	{
		int a, b;
		cin >> a >> b;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	for(int i = 1;i <= n;i++)
	{
	  if(used[i])
      {
          continue;
      }
	  cur = 1;
	  dfs(i,0);
	  ans += cur;
	}
	cout << ans;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int ans,cur;
vector<vector<int>>g(2 * 10e5);
vector<bool>used(100005);
void dfs(int x,int f)
{
    if(used[x])
    {
        cur = 0;
        return;
    }
    used[x] = 1;
    for(int i = 0;i < g[x].size(); i++)
    {
        int v = g[x][i];
        if(v != f)
        {

            dfs(v,x);
        }
    }
}
int32_t main()
{
    int n, x;
	cin >> n >> x;
	for(int i = 1;i <= x; i++)
	{
		int a, b;
		cin >> a >> b;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	for(int i = 1;i <= n;i++)
	{
	  if(used[i])
      {
          continue;
      }
	  cur = 1;
	  dfs(i,0);
	  ans += cur;
	}
	cout << ans;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int ans,cur;
vector<vector<int>>g(2 * 10e5);
vector<bool>used(100005);
void dfs(int x,int f)
{
    if(used[x])
    {
        cur = 0;
        return;
    }
    used[x] = 1;
    for(int i = 0;i < g[x].size(); i++)
    {
        int v = g[x][i];
        if(v != f && !used[v])
        {

            dfs(v,x);
        }
    }
}
int32_t main()
{
    int n, x;
	cin >> n >> x;
	vector<int>rb(2 * 10e5),ra(2 * 10e5);
	for(int i = 1;i < n; i++)
	{
		int a, b;
		cin >> a >> b;
		g[a].push_back(b);
		g[b].push_back(a);
	}
	for(int i = 1;i <= n;i++)
	{
	  if(used[i])
      {
          continue;
      }
	  cur = 1;
	  dfs(i,0);
	  ans += cur;
	}
	cout << ans;
    return 0;
}


#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define int                 long long
#define FF(i,a,b)           for(int i=a;i<b;i++)
#define BF(i,a,b)           for(int i=a;i>=b;i--)
#define vi                  vector<int>
#define MAP                 map<int,int>
#define pb                  push_back
#define MP                  make_pair
#define F                   first
#define S                   second
#define pi                  pair<int,int>
#define all(v)              v.begin(),v.end()
#define PIE                 3.1415926535897932384626433832795
#define FastIO              ios::sync_with_stdio(0); cin.tie(0);cout.tie(0)
//#define ordered_set         tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>
/*

    order_of_key (k) : Number of items strictly smaller than k .
    find_by_order(k) : K-th element in a set (counting from zero).

*/
/**************************************************************************************/
                       /*Global Variables*/
const int mod = 1e9+7;
const int N = 2e5+10;
const int inf = 3e18;
vi g[N];
vector<bool> vis(N);
/**************************************************************************************/
template <typename A>istream& operator>>(istream& input,vector<A>& x) {for(auto& i:x)input>>i;return input;}
template<typename A>ostream& operator<<(ostream& output,vector<A>& x) {for(auto& i:x)output<<i<<' ';return output;}
int add(int a, int b){return (a%mod + b%mod + mod)%mod;}
int sub(int a, int b){return (a%mod - b%mod + mod)%mod;}
int mul(int a, int b){return ((a%mod)*(b%mod) + mod)%mod;}
int Power(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1)res*=a;
        a*=a;
        b>>=1;
    }
    return res;
}
int x=0,y=0;
int dfs(int u)
{
    x+=g[u].size();
    y++;
    vis[u]=true;
    for(auto v:g[u])
    {
        if(!vis[v])
        {
            dfs(v);
        }
    }

}
signed main()
{
    FastIO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        FF(i,0,N)vis[i]=false;
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            g[x].pb(y);
            g[y].pb(x);
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                dfs(i);
                //cout<<y<<" "<<x<<"\n";
                if((x/2)<=y-1)
                ans++;
                x=0;
                y=0;

            }
        }
        cout<<ans<<"\n";

    }

}
/*
|| Do what you can with all you have,wherever you are. ||

|| Knowing is not enough, we must apply. Wishing is not enough, we must do. ||

|| A goal is a dream with deadline. ||

|| Whether you think you can or you think you can't, you're right. ||

|| A year from now you may wish you had started today ||
*/


#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define int                 long long
#define FF(i,a,b)           for(int i=a;i<b;i++)
#define BF(i,a,b)           for(int i=a;i>=b;i--)
#define vi                  vector<int>
#define MAP                 map<int,int>
#define pb                  push_back
#define MP                  make_pair
#define F                   first
#define S                   second
#define pi                  pair<int,int>
#define all(v)              v.begin(),v.end()
#define PIE                 3.1415926535897932384626433832795
#define FastIO              ios::sync_with_stdio(0); cin.tie(0);cout.tie(0)
//#define ordered_set         tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>
/*

    order_of_key (k) : Number of items strictly smaller than k .
    find_by_order(k) : K-th element in a set (counting from zero).

*/
/**************************************************************************************/
                       /*Global Variables*/
const int mod = 1e9+7;
const int N = 2e5+10;
const int inf = 3e18;
vi g[N];
vector<bool> vis(N);
/**************************************************************************************/
template <typename A>istream& operator>>(istream& input,vector<A>& x) {for(auto& i:x)input>>i;return input;}
template<typename A>ostream& operator<<(ostream& output,vector<A>& x) {for(auto& i:x)output<<i<<' ';return output;}
int add(int a, int b){return (a%mod + b%mod + mod)%mod;}
int sub(int a, int b){return (a%mod - b%mod + mod)%mod;}
int mul(int a, int b){return ((a%mod)*(b%mod) + mod)%mod;}
int Power(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1)res*=a;
        a*=a;
        b>>=1;
    }
    return res;
}
int x=0,y=0;
int dfs(int u)
{
    x+=g[u].size();
    y++;
    vis[u]=true;
    for(auto v:g[u])
    {
        if(!vis[v])
        {
            dfs(v);
        }
    }

}
signed main()
{
    FastIO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        FF(i,0,N)vis[i]=false;
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            g[x].pb(y);
            g[y].pb(x);
        }
        int ans =0;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                dfs(i);
                //cout<<y<<" "<<x<<"\n";
                if((x/2)<=y-1)
                ans++;
                x=0;
                y=0;

            }
        }
        cout<<ans<<"\n";

    }

}
/*
|| Do what you can with all you have,wherever you are. ||

|| Knowing is not enough, we must apply. Wishing is not enough, we must do. ||

|| A goal is a dream with deadline. ||

|| Whether you think you can or you think you can't, you're right. ||

|| A year from now you may wish you had started today ||
*/


#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define int                 long long
#define FF(i,a,b)           for(int i=a;i<b;i++)
#define BF(i,a,b)           for(int i=a;i>=b;i--)
#define vi                  vector<int>
#define MAP                 map<int,int>
#define pb                  push_back
#define MP                  make_pair
#define F                   first
#define S                   second
#define pi                  pair<int,int>
#define all(v)              v.begin(),v.end()
#define PIE                 3.1415926535897932384626433832795
#define FastIO              ios::sync_with_stdio(0); cin.tie(0);cout.tie(0)
//#define ordered_set         tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>
/*

    order_of_key (k) : Number of items strictly smaller than k .
    find_by_order(k) : K-th element in a set (counting from zero).

*/
/**************************************************************************************/
                       /*Global Variables*/
const int mod = 1e9+7;
const int N = 2e5+10;
const int inf = 3e18;
vi g[N];
vector<bool> vis(N);
/**************************************************************************************/
template <typename A>istream& operator>>(istream& input,vector<A>& x) {for(auto& i:x)input>>i;return input;}
template<typename A>ostream& operator<<(ostream& output,vector<A>& x) {for(auto& i:x)output<<i<<' ';return output;}
int add(int a, int b){return (a%mod + b%mod + mod)%mod;}
int sub(int a, int b){return (a%mod - b%mod + mod)%mod;}
int mul(int a, int b){return ((a%mod)*(b%mod) + mod)%mod;}
int Power(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1)res*=a;
        a*=a;
        b>>=1;
    }
    return res;
}
int x=0,y=0;
int dfs(int u)
{
    x+=g[u].size();
    y++;
    vis[u]=true;
    for(auto v:g[u])
    {
        if(!vis[v])
        {
            dfs(v);
        }
    }

}
signed main()
{
    FastIO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        //vis.assign(n+1,false);
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            g[x].pb(y);
            g[y].pb(x);
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                dfs(i);
                //cout<<y<<" "<<x<<"\n";
                if((x/2)<=y-1)
                ans++;
                x=0;
                y=0;

            }
        }
        cout<<ans<<"\n";

    }

}
/*
|| Do what you can with all you have,wherever you are. ||

|| Knowing is not enough, we must apply. Wishing is not enough, we must do. ||

|| A goal is a dream with deadline. ||

|| Whether you think you can or you think you can't, you're right. ||

|| A year from now you may wish you had started today ||
*/


#include<bits/stdc++.h>
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
using namespace std;
#define int                 long long
#define FF(i,a,b)           for(int i=a;i<b;i++)
#define BF(i,a,b)           for(int i=a;i>=b;i--)
#define vi                  vector<int>
#define MAP                 map<int,int>
#define pb                  push_back
#define MP                  make_pair
#define F                   first
#define S                   second
#define pi                  pair<int,int>
#define all(v)              v.begin(),v.end()
#define PIE                 3.1415926535897932384626433832795
#define FastIO              ios::sync_with_stdio(0); cin.tie(0);cout.tie(0)
//#define ordered_set         tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>
/*

    order_of_key (k) : Number of items strictly smaller than k .
    find_by_order(k) : K-th element in a set (counting from zero).

*/
/**************************************************************************************/
                       /*Global Variables*/
const int mod = 1e9+7;
const int N = 2e5+10;
const int inf = 3e18;
vi g[N];
vector<bool> vis;
/**************************************************************************************/
template <typename A>istream& operator>>(istream& input,vector<A>& x) {for(auto& i:x)input>>i;return input;}
template<typename A>ostream& operator<<(ostream& output,vector<A>& x) {for(auto& i:x)output<<i<<' ';return output;}
int add(int a, int b){return (a%mod + b%mod + mod)%mod;}
int sub(int a, int b){return (a%mod - b%mod + mod)%mod;}
int mul(int a, int b){return ((a%mod)*(b%mod) + mod)%mod;}
int Power(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1)res*=a;
        a*=a;
        b>>=1;
    }
    return res;
}
int x=0,y=0;
int dfs(int u)
{
    x+=g[u].size();
    y++;
    vis[u]=true;
    for(auto v:g[u])
    {
        if(!vis[v])
        {
            dfs(v);
        }
    }

}
signed main()
{
    FastIO;
    int T=1;
    //cin>>T;
    while(T--)
    {
        int n,m;
        cin>>n>>m;
        vis.assign(n+1,false);
        for(int i=0;i<m;i++)
        {
            int x,y;
            cin>>x>>y;
            g[x].pb(y);
            g[y].pb(x);
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i])
            {
                dfs(i);
                //cout<<y<<" "<<x<<"\n";
                if((x/2)<=y-1)
                ans++;
                x=0;
                y=0;

            }
        }
        cout<<ans<<"\n";

    }

}
/*
|| Do what you can with all you have,wherever you are. ||

|| Knowing is not enough, we must apply. Wishing is not enough, we must do. ||

|| A goal is a dream with deadline. ||

|| Whether you think you can or you think you can't, you're right. ||

|| A year from now you may wish you had started today ||
*/


#include<bits/stdc++.h>
using namespace std;
bool dfs(int x,vector<int> arr[],bool visit[],int parent){
	visit[x] =true;
	for(int i:arr[x]){
			if(!visit[i]){
				if(dfs(i,arr,visit,x))
					return true;

			}
			else if(i!=parent){
				return true;
			}
	}
	return false;
}
void add(vector<int> arr[],int x,int y){
		arr[x].push_back(y);
		arr[y].push_back(x);
}
int main(){
	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);
	int n,m;
	cin>>n>>m;
	vector<int> arr[n+1];
	bool visit[n+1];
	for(int i=1;i<=n;i++){
		visit[i]= false;
	}
	for(int i=0;i<m;i++){
		int x,y;
		cin>>x>>y;
		add(arr,x,y);
	 }
	int t=0;
	for(int i=1;i<=n;i++){
		if(visit[i]==false){

		if(!dfs(i,arr,visit,-1)) t++;
		}
	}
	cout<<t;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
bool dfs(int x,vector<int> arr[],bool visit[],int parent){
	visit[x] =true;
	for(int i:arr[x]){
			if(!visit[i]){
				dfs(i,arr,visit,x);

			}
			else if(i!=parent){
				return true;
			}
	}
	return false;
}
void add(vector<int> arr[],int x,int y){
		arr[x].push_back(y);
		arr[y].push_back(x);
}
int main(){
	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);
	int n,m;
	cin>>n>>m;
	vector<int> arr[n+1];
	bool visit[n+1];
	for(int i=1;i<=n;i++){
		visit[i]= false;
	}
	for(int i=0;i<m;i++){
		int x,y;
		cin>>x>>y;
		add(arr,x,y);
	 }
	int t=0;
	for(int i=1;i<=n;i++){
		if(visit[i]==false){

		if(!dfs(i,arr,visit,-1)) t++;
		}
	}
	cout<<t;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
bool dfs(int x,vector<int> arr[],bool visit[],int parent){
	visit[x] =true;
	for(int i:arr[x]){
			if(!visit[i]){
				dfs(i,arr,visit,x);
			}
			else if(i!=parent){
				return true;
			}
	}
	return false;
}
void add(vector<int> arr[],int x,int y){
		arr[x].push_back(y);
		arr[y].push_back(x);
}
int main(){
	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);
	int n,m;
	cin>>n>>m;
	vector<int> arr[n+1];
	bool visit[n+1];
	for(int i=0;i<m;i++){
		int x,y;
		cin>>x>>y;
		add(arr,x,y);
	 }
	int t=0;
	for(int i=1;i<=n;i++){
		if(visit[i]==false){

		if(!dfs(1,arr,visit,-1)) t++;
		}
	}
	cout<<t;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
bool dfs(int x,vector<int> arr[],bool visit[],int parent){
	visit[x] =true;
	for(int i:arr[x]){
			if(!visit[i]){
				dfs(i,arr,visit,x);
			}
			else if(i!=parent){
				return true;
			}
	}
	return false;
}
void add(vector<int> arr[],int x,int y){
		arr[x].push_back(y);
		arr[y].push_back(x);
}
int main(){
	cin.tie(NULL);
	cout.tie(NULL);
	ios_base::sync_with_stdio(false);
	int n,m;
	cin>>n>>m;
	vector<int> arr[n+1];
	bool visit[n+1];
	for(int i=1;i<=n;i++){
		visit[i]= false;
	}
	for(int i=0;i<m;i++){
		int x,y;
		cin>>x>>y;
		add(arr,x,y);
	 }
	int t=0;
	for(int i=1;i<=n;i++){
		if(visit[i]==false){

		if(!dfs(1,arr,visit,-1)) t++;
		}
	}
	cout<<t;
	return 0;
}


//@sakshjha
#include<bits/stdc++.h>
using namespace std;
#define ll  long long int
#define ld long double
#define IOS ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define pi 3.14159265358979
const ll MOD = 1000000007;
const ll N=100005;
vector<ll>gr[N];
int main()
{
    IOS
    ll n,m,i;
    cin>>n>>m;
    for(i=1; i<=m; i++)
    {
        ll u,v;
        cin>>u>>v;
        gr[u].push_back(v);
        gr[v].push_back(u);
    }
    for(i=1; i<=n; i++)
        sort(gr[i].begin(),gr[i].end());
    ll vis[n+5]={0};
    for(i=1; i<=n; i++)
    {
        ll te=0;
        for(ll v: gr[i])
        {
            if(v<i)
                continue;
            else if(vis[i]==1)
                vis[v]=1;
            else if(vis[i]==0)
            {
                vis[i]=1;
            }

        }
    }
    ll ans=n;
    for(i=1; i<=n; i++)
        ans-=vis[i];
    cout<<ans;

    return 0;
}


//@sakshjha
#include<bits/stdc++.h>
using namespace std;
#define ll  long long int
#define ld long double
#define IOS ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define pi 3.14159265358979
const ll MOD = 1000000007;
const ll N=100005;
vector<ll>gr[N];
int main()
{
    IOS
    ll n,m,i;
    cin>>n>>m;
    for(i=1; i<=m; i++)
    {
        ll u,v;
        cin>>u>>v;
        gr[u].push_back(v);
        gr[v].push_back(u);
    }
    for(i=1; i<=n; i++)
        sort(gr[i].begin(),gr[i].end());
    ll vis[n+5]={0};
    for(i=1; i<=n; i++)
    {
        ll te=0;
        for(ll v: gr[i])
        {
            if(v<i)
                continue;
            else if(vis[i]==1)
                vis[v]=1;
            else if(te==0)
            {
                vis[i]=1;
                te=1;
            }
            else if(te==1)
                vis[v]=1;

        }
    }
    ll ans=n;
    for(i=1; i<=n; i++)
        ans-=vis[i];
    cout<<ans;

    return 0;
}


//@sakshjha
#include<bits/stdc++.h>
using namespace std;
#define ll  long long int
#define ld long double
#define IOS ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define pi 3.14159265358979
const ll MOD = 1000000007;
const ll N=100005;
vector<ll>gr[N];
ll ed=0,no=0,vis[N];
void dfs( ll u)
{
    if(vis[u])
        return;
    vis[u]=1;
    no++;
    ed+=gr[u].size();
    for(ll v: gr[u])
        dfs(v);
}
int main()
{
    IOS
    ll n,m,i;
    cin>>n>>m;
    for(i=1; i<=m; i++)
    {
        ll u,v;
        cin>>u>>v;
        gr[u].push_back(v);
        gr[v].push_back(u);
    }
    for(i=1; i<=n; i++)
        sort(gr[i].begin(),gr[i].end());
    //ll vis[n+5]={0};
    ll ans=0;
    for(i=1; i<=n; i++)
    {
        if(vis[i]==0)
        {
            ed=0;
            no=0;
            dfs(i);
            ed/=2;
            if(ed<no)
                ans++;
        }

    }
    cout<<ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

//------defines
#define CLR(U) memset(U, 0, sizeof U)
#define CPY(FROM, TO) memcpy(TO, FROM, sizeof TO)
//------defines

//------globals
int n, flag[100010][10];
//------globals

//------dsu
int p[40], h[40], go[40], Free;
bool was[40];

void reset()
{
    CLR(h);
    CLR(was);
    Free = 0;
    for (int i(0); i < (n << 2); ++i)
        go[i] = p[i] = i;
}

int find_set(int v)
{
    return p[v] == v ? v : p[v] = find_set(p[v]);
}

int union_set(int u, int v)
{
    u = find_set(u);
    v = find_set(v);
    if (u == v)
        return 0;
    if (h[u] > h[v])
        swap(u, v);
    p[v] = u;
    if (h[u] == h[v])
        ++h[u];
    return 1;
}
//------dsu

//------segments
struct range
{
    int l, r, L[10], R[10], k;
    range()
    {
        k = 0;
    }
    range(int x)
    {
        l = r = x;
        k = n;
        L[0] = 0;
        for (int i(1); i < n; ++i)
            if (flag[x][i] == flag[x][i - 1])
            {
                --k;
                L[i] = L[i - 1];
            }
            else
                L[i] = L[i - 1] + 1;
        CPY(L, R);
    }
    range(const range &seg)
    {
        *this = seg;
    }
};

range merge(const range &L, const range &R)
{
    if (!L.k || !R.k)
        return L.k ? range(L) : range(R);
    range res;
    res.k = L.k + R.k;
    int *l = flag[L.r], *r = flag[R.l];
    res.l = L.l;
    res.r = R.r;
    reset();
    for (int i(0); i < n; ++i)
        if (l[i] == r[i])
            res.k -= union_set(L.R[i], R.L[i] + (n << 1));
    for (int i(0); i < n; ++i)
    {
        res.L[i] = find_set(L.L[i]);
        res.R[i] = find_set(R.R[i] + (n << 1));
        was[res.L[i]] = was[res.R[i]] = 1;
    }
    for (int i(n << 1); i < (n << 2); ++i)
        if (was[i])
        {
            while (was[Free])
                ++Free;
            was[i] = 0;
            was[Free] = 1;
            go[i] = Free;
        }
    for (int i(0); i < n; ++i)
    {
        res.L[i] = go[res.L[i]];
        res.R[i] = go[res.R[i]];
    }
    return res;
}
//------range

//------segment_tree
struct node
{
    node *L, *R;
    int l, r, m;
    range s;
    node(int ll, int rr)
    {
        l = ll;
        r = rr;
        m = (l + r) >> 1;
        L = R = 0;
    }
};

node *build(int l, int r)
{
    node *v = new node(l, r);
    if (l == r)
    {
        v->s = range(l);
        return v;
    }
    v->L = build(l, v->m);
    v->R = build(v->m + 1, r);
    v->s = merge(v->L->s, v->R->s);
    return v;
}

range query(node *v, int l, int r)
{
    if (l > r)
        return range();
    if (l == v->l && r == v->r)
        return v->s;
    return merge(query(v->L, l, min(r, v->m)), query(v->R, max(l, v->m + 1), r));
}

void destruct(node *v)
{
    if (!v)
        return;
    destruct(v->L);
    destruct(v->R);
    delete v;
}

//------segment_tree

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int m, q;
    cin >> n >> m >> q;
    for (int i(0); i < n; ++i)
        for (int j(1); j <= m; ++j)
            cin >> flag[j][i];
    node *root = build(1, m);
    for (int l, r; q; --q)
    {
        cin >> l >> r;
        cout << query(root, l, r).k << '\n';
    }
    destruct(root);
}


#include <bits/stdc++.h>

using namespace std;

#define MX 100010
#define CPY(FROM, TO) memcpy(TO, FROM, sizeof TO)

int field[MX][10], m;

struct range
{
    int L[10], R[10], uL[10], uR[10], k;
    range() { k = 0; }
};

int find_set(int v, unordered_map <int, int> &p)
{
    return p[v] == v ? v : p[v] = find_set(p[v], p);
}

int union_set(int u, int v, unordered_map <int, int> &p)
{
    u = find_set(u, p);
    v = find_set(v, p);
    if (u == v) return 0;
    p[u] = v;
    return 1;
}

range merge(range a, range b)
{
    if (!a.k || !b.k)
        return !a.k ? b : a;
    range res;
    CPY(a.L, res.L);
    CPY(b.R, res.R);
    res.k = a.k + b.k;
    unordered_map <int, int> p;
    for (int i(0); i < m; ++i)
    {
        p[a.uL[i]] = a.uL[i];
        p[a.uR[i]] = a.uR[i];
        p[b.uL[i]] = b.uL[i];
        p[b.uR[i]] = b.uR[i];
    }
    for (int i(0); i < m; ++i)
        if (a.R[i] == b.L[i])
            res.k -= union_set(a.uR[i], b.uL[i], p);
    for (int i(0); i < m; ++i)
    {
        res.uL[i] = find_set(a.uL[i], p);
        res.uR[i] = find_set(b.uR[i], p);
    }
    return res;
}

struct Node
{
    int l, r, m;
    range s;
    Node *L, *R;
    Node(int _l, int _r)
    {
        L = R = 0;
        l = _l;
        r = _r;
        m = (l + r) >> 1;
    }
};

Node *Build(int l, int r)
{
    Node *v = new Node(l, r);
    if (l == r)
    {
        CPY(field[l], v->s.L);
        CPY(field[r], v->s.R);
        v->s.uL[0] = v->s.uR[0] = l * m;
        v->s.k = m;
        for (int i(1); i < m; ++i)
            if (field[l][i] == field[l][i - 1])
            {
                --v->s.k;
                v->s.uL[i] = v->s.uR[i] = v->s.uL[i - 1];
            }
            else
                v->s.uL[i] = v->s.uR[i] = l * m + i;
        return v;
    }
    v->L = Build(l, v->m);
    v->R = Build(v->m + 1, v->r);
    v->s = merge(v->L->s, v->R->s);
    return v;
}

range Query(int l, int r, Node *v)
{
    if (l > r) return range();
    if (l == v->l && r == v->r)
        return v->s;
    return merge(Query(l, min(v->m, r), v->L), Query(max(v->m + 1, l), r, v->R));
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, q;
    cin >> m >> n >> q;;
    for (int i(0); i < m; ++i)
        for (int j(1); j <= n; ++j)
            cin >> field[j][i];
    Node *root = Build(1, n);
    map <pair <int, int>, int> cash;
    for (int l, r; q; --q)
    {
        cin >> l >> r;
        if (!cash[pair <int, int> { l, r }])
            cash[pair <int, int> { l, r }] = Query(l, r, root).k;
        cout << cash[pair <int, int> { l, r }] << '\n';
    }
}


#include <bits/stdc++.h>

using namespace std;

#define MX 100010
#define CPY(FROM, TO) memcpy(TO, FROM, sizeof TO)

int field[MX][10], m;

struct range
{
    int L[10], R[10], uL[10], uR[10], k;
    range() { k = 0; }
    range(const range &r)
    {
        k = r.k;
        CPY(r.L, L);
        CPY(r.R, R);
        CPY(r.uL, uL);
        CPY(r.uR, uR);
    }
};

int find_set(int v, unordered_map <int, int> &p)
{
    return p[v] == v ? v : p[v] = find_set(p[v], p);
}

int union_set(int u, int v, unordered_map <int, int> &p)
{
    u = find_set(u, p);
    v = find_set(v, p);
    if (u == v) return 0;
    p[u] = v;
    return 1;
}

range merge(const range &a, const range &b)
{
    if (!a.k || !b.k)
        return !a.k ? range(b) : range(a);
    range res;
    CPY(a.L, res.L);
    CPY(b.R, res.R);
    res.k = a.k + b.k;
    unordered_map <int, int> p;
    for (int i(0); i < m; ++i)
    {
        p[a.uL[i]] = a.uL[i];
        p[a.uR[i]] = a.uR[i];
        p[b.uL[i]] = b.uL[i];
        p[b.uR[i]] = b.uR[i];
    }
    for (int i(0); i < m; ++i)
        if (a.R[i] == b.L[i])
            res.k -= union_set(a.uR[i], b.uL[i], p);
    for (int i(0); i < m; ++i)
    {
        res.uL[i] = find_set(a.uL[i], p);
        res.uR[i] = find_set(b.uR[i], p);
    }
    return res;
}

struct Node
{
    int l, r, m;
    range s;
    Node *L, *R;
    Node(int _l, int _r)
    {
        L = R = 0;
        l = _l;
        r = _r;
        m = (l + r) >> 1;
    }
};

Node *Build(int l, int r)
{
    Node *v = new Node(l, r);
    if (l == r)
    {
        CPY(field[l], v->s.L);
        CPY(field[r], v->s.R);
        v->s.uL[0] = v->s.uR[0] = l * m;
        v->s.k = m;
        for (int i(1); i < m; ++i)
            if (field[l][i] == field[l][i - 1])
            {
                --v->s.k;
                v->s.uL[i] = v->s.uR[i] = v->s.uL[i - 1];
            }
            else
                v->s.uL[i] = v->s.uR[i] = l * m + i;
        return v;
    }
    v->L = Build(l, v->m);
    v->R = Build(v->m + 1, v->r);
    v->s = merge(v->L->s, v->R->s);
    return v;
}

range Query(int l, int r, Node *v)
{
    if (l > r) return range();
    if (l == v->l && r == v->r)
        return v->s;
    return merge(Query(l, min(v->m, r), v->L), Query(max(v->m + 1, l), r, v->R));
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n, q;
    cin >> m >> n >> q;;
    for (int i(0); i < m; ++i)
        for (int j(1); j <= n; ++j)
            cin >> field[j][i];
    Node *root = Build(1, n);
    map <pair <int, int>, int> cash;
    for (int l, r; q; --q)
    {
        cin >> l >> r;
        if (!cash[pair <int, int> { l, r }])
            cash[pair <int, int> { l, r }] = Query(l, r, root).k;
        cout << cash[pair <int, int> { l, r }] << '\n';
    }
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <vector>

using namespace std;

const int NMAX = 10 + 1;
const int MMAX = 100000 + 5;

int N, M;
int mat[NMAX][MMAX];

struct Node {
    int st, dr;
    int internal;
    int comps[NMAX][2];
} tree[4 * MMAX];

vector <int> graph[3 * NMAX];

void addEdge(int a, int b) {
    graph[a].push_back(b);
    graph[b].push_back(a);
}

int comps[3 * NMAX];
int currentComp;
void dfs(int node)  {
    comps[node] = currentComp;
    for (auto it: graph[node])
        if (!comps[it])
            dfs(it);
}

void unite(Node &res, const Node a, const Node &b) {
    if (a.st == -1) {
        res = b;
        return ;
    }

    for (int i = 1; i <= 3 * N; ++ i)
        graph[i].clear(), comps[i] = 0;

    //Node a
    int last[2 * NMAX] = {0};
    for (int i = 1; i <= N; ++ i) {
        if (last[a.comps[i][0]])
            addEdge(i, last[a.comps[i][0]]);
        last[a.comps[i][0]] = i;
    }
    for (int i = 1; i <= N; ++ i) {
        if (last[a.comps[i][1]])
            addEdge(N + i, last[a.comps[i][1]]);
        last[a.comps[i][1]] = N + i;
    }
    //Node b
    for (int i = 1; i <= 2 * N; ++ i)
        last[i] = 0;
    for (int i = 1; i <= N; ++ i) {
        if (last[b.comps[i][0]])
            addEdge(N + i, last[b.comps[i][0]]);
        last[b.comps[i][0]] = N + i;
    }
    for (int i = 1; i <= N; ++ i) {
        if (last[b.comps[i][1]])
            addEdge(2 * N + i, last[b.comps[i][1]]);
        last[b.comps[i][1]] = 2 * N + i;
    }

    //Final dfs left
    currentComp = 0;
    for (int i = 1; i <= N; ++ i) {
        if (!comps[i]) {
            ++ currentComp;
            dfs(i);
        }
        res.comps[i][0] = comps[i];
    }

    //Final dfs right
    for (int i = 2 * N + 1; i <= 3 * N; ++ i) {
        if (!comps[i]) {
            ++ currentComp;
            dfs(i);
        }
        res.comps[i - 2 * N][1] = comps[i];
    }

    //Final dfs middle
    res.internal = a.internal + b.internal;
    for (int i = N + 1; i <= 2 * N; ++ i)
        if (!comps[i]) {
            ++ currentComp;
            dfs(i);
            ++ res.internal;
        }
    res.st = a.st;
    res.dr = b.dr;
}

const int dx[2] = {0, 1};
const int dy[2] = {1, 0};

int where[MMAX];
void build(int node, int st, int dr) {
    tree[node].st = st, tree[node].dr = dr;

    if (dr - st <= 1) {
        for (int i = 1; i <= 2 * N; ++ i)
            graph[i].clear(), comps[i] = 0;

        int nd = 1;
        for (int j = st; j <= dr; ++ j)
            for (int i = 1; i <= N; ++ i, ++ nd)
                for (int k = 0; k < 2; ++ k) {
                    int lin = i + dx[k];
                    int col = j + dy[k];

                    if (lin >= 1 && lin <= N && col >= st && col <= dr && mat[i][j] == mat[lin][col])
                        addEdge(nd, (col - st) * N + lin);
                }

        currentComp = 0;
        for (int i = 1; i <= N; ++ i) {
            if (!comps[i]) {
                ++ currentComp;
                dfs(i);
            }
            tree[node].comps[i][0] = comps[i];
            if (st == dr)
                tree[node].comps[i][1] = comps[i];
        }

        if (st < dr) {
            for (int i = N + 1; i <= 2 * N; ++ i) {
                if (!comps[i]) {
                    ++ currentComp;
                    dfs(i);
                }
                tree[node].comps[i - N][1] = comps[i];
            }
        }

        if (st < dr) {
            build(node << 1, st, st);
            build((node << 1) + 1, dr, dr);
        }

        if (st == dr)
            where[st] = node;
        return ;
    }

    int mid = (st + dr) >> 1;

    build(node << 1, st, mid);
    build((node << 1) + 1, mid, dr);

    unite(tree[node], tree[node << 1], tree[(node << 1) + 1]);
}

Node ans;
void query(int node, int st, int dr) {
    if (tree[node].st == st && tree[node].dr == dr) {
        unite(ans, ans, tree[node]);
        return ;
    }

    int mid = (tree[node].st + tree[node].dr) >> 1;

    if (dr <= mid)
        query(node << 1, st, dr);
    else if (st >= mid)
        query((node << 1) + 1, st, dr);
    else {
        query(node << 1, st, mid);
        query((node << 1) + 1, mid, dr);
    }
}

int main()
{
    //freopen("data.in", "r", stdin);
    ios_base :: sync_with_stdio(false);
    cin.tie(0);

    int Q;
    cin >> N >> M >> Q;
    for (int i = 1; i <= N; ++ i)
        for (int j = 1; j <= M; ++ j)
            cin >> mat[i][j];
    build(1, 1, M);

    while (Q --) {
        int st, dr;
        cin >> st >> dr;

        if (st < dr) {
            ans.st = -1;
            query(1, st, dr);
        }
        else
            ans = tree[where[st]];
        int res = ans.internal;

        vector <int> v;
        for (int i = 1; i <= N; ++ i) {
            v.push_back(ans.comps[i][0]);
            v.push_back(ans.comps[i][1]);
        }

        sort(v.begin(), v.end());
        v.resize(unique(v.begin(), v.end()) - v.begin());

        cout << res + v.size() << '\n';
    }

    return 0;
}