#include <bits/stdc++.h>
using namespace std;
int pre[1010];
bool t[1010];//t 用于标记独立块的根结点
int find(int x)//查找根节点
{
int r=x;
while(pre[r]!=r)
r=pre[r];//返回根节点 r
int i=x,j;
while(pre[i]!=r)//路径压缩
{
j=pre[i]; // 在改变上级之前用临时变量 j 记录下他的值
pre[i]=r;//把上级改为根节点
i=j;
}
return r;
}
void join(int x,int y)//判断x y是否连通,
{
int fx=find(x),fy=find(y);
if(fx!=fy)
pre[fy]=fx;//如果已经连通,就不用管了 //如果不连通,就把它们所在的连通分支合并起来
}
int main()
{
int N,M,a,b,i,j,ans;
while(scanf("%d%d",&N,&M)&&N)
{
for(i=1;i<=N;i++)
pre[i]=i;//初始化
for(i=1;i<=M;i++)
{
scanf("%d%d",&a,&b);
join(a,b);//判断x y是否连通
}
memset(t,0,sizeof(t));
for(i=1;i<=N;i++)
t[find(i)]=1;//标记根结点
for(ans=0,i=1;i<=N;i++)
if(t[i])
ans++;
printf("%d\n",ans-1);
}
return 0;
}