#include <iostream>
#include <fstream>
#include <deque>
#define pb push_back
#define pf push_front
#define l 10
// determinarea componentelor conexe ale unui graf;
using namespace std;
void DFS(int n, int nod,int viz[],deque <int> vecini[]){
deque <int> stiva;
int i,gasit,x;
viz[nod] = 1;
stiva.pf (nod);
while(!stiva.empty()){
i = 1 ;gasit = 0; x =stiva.front();
for( i = 0 ; i < vecini[x].size(); i++){
if(viz[vecini[x][i]]!=1) // cautam un element ce nu a fost vizita
{ // daca am gasit intrerupe si adaugam in stiva
viz[vecini[x][i]] = 1;
gasit = 1;
break;
}
}
if(gasit){
stiva.pf (vecini[x][i]);
}
else{
stiva.pop_front();
}
}
}
int main()
{
int n,m,x,y,sol = 0;
ifstream f("dfs.in",ios::in);
ofstream g("dfs.out",ios::out);
f>>n>>m;
int viz[n+1];
deque <int> vecini[n+1] ;
for(int i = 1; i <= m; i++){
f>>x>>y;
vecini[x].pf(y);
vecini[y].pf(x);
}
for( int i = 1 ;i <= n; i++)
viz[i] = 0;
for( int i = 1 ;i <= n; i++)
if(viz[i]==0){
DFS(n,i,viz,vecini);
sol++;
}
g<<sol;
return 0;
}