#include <iostream>
using namespace std;
const int N=1002;
int n,m,a,b;
int cont;
int G[N][N];
bool visited[N]={false};
void Initial(){
    cont=0;
    for(int i=1;i<=1000;i++){
        for(int j=1;j<=1000;j++)
           G[i][j]=G[j][i]=0;
    }
    for(int i=1;i<=1000;i++) visited[i]=false;
}
void DFS(int v){
    visited[v]=true; //置已访问标记
    for(int u=1;u<=n;u++){
        //即如果u顶点是v顶点的邻接顶点,且u顶点尚未访问过
        if(G[v][u]==1 && visited[u]==false) DFS(u);
    }
}
void DFSTraverse(){
   for(int i=1;i<=n;i++){
      //计算连通分量数
      if(visited[i]==false){
         cont++;
         DFS(i);
      } 
   }
}
int main() {
   while(cin>>n>>m){
      Initial();
      for(int i=0;i<m;i++){
         cin>>a>>b;
         G[a][b]=G[b][a]=1;
      }
      DFSTraverse();
      cout<<cont-1<<endl;
   }
   return 0;
}