#include<iostream>
using namespace std;
const int maxn=1010;
int city[maxn];
int height[maxn];
void Initial(int n){
for(int i=1;i<=n;i++){
city[i]=i;
height[i]=1;
}
return ;
}
int Find(int x){//路径压缩查找
if(x!=city[x]){
city[x]=Find(city[x]);
}
return city[x];
}
void Union(int x,int y){//低树合并到高树
x=Find(x);
y=Find(y);
if(height[x]>height[y]){
city[y]=x;
height[y]=height[x];
}
else if(height[x]<height[y]){
city[x]=y;
height[x]=height[y];
}
else {
city[x]=y;
height[y]++;
height[x]=height[y];
}
return;
}
int main(){
int n,m;
while(scanf("%d",&n)!=EOF){
if(n==0)break;
scanf("%d",&m);
Initial(n);
int x,y;
for(int i=0;i<m;i++){
scanf("%d%d",&x,&y);
Union(x,y);
}
int ans=-1;
for(int i=1;i<=n;i++){
if(Find(i)==i)ans++;//查找连通分量
}
printf("%d\n",ans);
}
return 0;
}