#include<bits/stdc++.h>
using namespace std;

int f[1005];//存储每个结点的根 

//初始化 
void init(){
	for(int i = 1;i <= 1005;i++){
		f[i] = i;
	} 
}

//查找,找出x的根
int find(int x){
	//路径压缩x的父元素,直接指向x的根 
	return x==f[x]?x:f[x]=find(f[x]);
} 

//合并 
void merge(int x,int y){
	//先找出根 
	int p = find(x);
	int q = find(y);
	//如果不在一个集合 
	if(p!=q){
		f[p] = q;//将q的父元素指向p 
	}
} 

int main(){
	int n,m,p;
	while(true){
		cin>>n;
		if(n == 0) return 0;
		cin>>m;
		
		init();//初始化
		
		int x,y;
		for(int i = 1;i <= m;i++){
			cin>>x>>y;
			merge(x,y);//合并xy 
		} 
		
		int cnt = 0;//存储最少要修多少路(联通分量数量-1)
		//找出联通分量的个数
		for(int i = 1;i <= n;i++){
			//数一数有几个根 
			if(i == f[i]){
				cnt++; 
			}
		} 
		
		cout<<cnt-1<<endl;
	}
	
	return 0;
} 
/**************************************************************
	Problem: 1922
	User: admin
	Language: C++
	Result: Accepted
	Time:70 ms
	Memory:2076 kb
****************************************************************/