#include <iostream>
using namespace std;
int pre[1050];
int find(int x){
return pre[x]==x?x:pre[x]=find(pre[x]);
}
bool join(int a,int b){
int fa=find(a);
int fb=find(b);
if(fa!=fb){
pre[fb]=fa;
return 1;
}
return 0;
}
int main(){
int m,n;
int a,b;
int f1,f2;
while(scanf("%d",&n)&&n){
int ans=0;
for(int i=1;i<=n;i++){
pre[i]=i;
}
scanf("%d",&m);
for(int i=1;i<=m;i++){
scanf("%d %d",&a,&b);
join(a,b);
}
for(int i=1;i<=n;i++){
if(find(i)==i) ans++;
}
ans--;
printf("%d\n",ans);
}
}
/*
4 2
1 3
4 3
3 3
1 2
1 3
2 3
5 2
1 2
3 5
999 0
0
*/
并查集的基础题~
1.寻找根结点的思想就是:如果根结点为自己就返回自己,如果根结点不为自己就向上查找,直到找到根结点是自己本身的点;
2.找到有几个不同的根结点,则把这些根结点连起来需要n-1条边,即为答案