/*
TASK:zala
LANG:C++
*/
#include <algorithm>
#include <stdio.h>
using namespace std;
struct rib{long a,b;};
inline int cmp (rib x, rib y)
 {if (x.a==y.a) return x.b<y.b;
           else return x.a<y.a;
 }
 
rib ribs[200000];
long used[51000],q[51000],r,w;
long i,v,e,a,b,br=0;
inline long ffind (long a, long b)
{long l=0,r=e-1,m,pos=0;
 while (l<=r)
 {m=(r+l)/2; 
  if (ribs[m].a==a&&ribs[m].b==b) return m;
  if (ribs[r].a==a&&ribs[r].b==b) return r;
  if (ribs[l].a==a&&ribs[l].b==b) return l;
  if (ribs[m].a!=a){
                   if (ribs[m].a>a) r=m;
                               else l=m;
                   }
     else {       
          if (ribs[m].b>b) r=m;
                      else l=m;
           
          }      
   r--;l++;       
 }       
 return -1;
}

int main()
{
scanf("%ld %ld",&v,&e)    ;
for (i=0;i<e;i++)
   {
   scanf("%ld %ld",&a,&b);
   ribs[i*2].a=a;
   ribs[i*2].b=b;
   ribs[i*2+1].a=b;
   ribs[i*2+1].b=a;
   }
e=e*2;
for (i=0;i<v;i++)
 {ribs[e+i].a=i;
  ribs[e+i].b=-1;                 
  }
e+=v;    
sort(ribs,ribs+e,cmp);
long j,t;
for (i=0;i<v;i++)
{for (j=0;j<v;j++)if (i!=j)used[j]=0;
                      else used[j]=1;                 
 if (i!=0) q[0]=0;
      else q[0]=1;
 used[q[0]]=1;
 r=0;
 w=1;
 while (r<=w)                     
 {t=ffind(q[r],-1)-1;
  if (t!=-2)
  while (ribs[++t].a==q[r])
   if (used[ribs[t].b]==0) 
     {q[w++]=ribs[t].b;
      used[ribs[t].b]=1;
      } 
  r++        ;
 }
 if (r!=v)br++;
}
printf("%ld\n",br);

/*for (i=0;i<e;i++) printf("%ld %ld\n",ribs[i].a,ribs[i].b);
while (a!=-1)
{
scanf("%ld %ld",&a,&b);
printf("%ld\n",ffind(a,b));
}*/

return 0;
}
