/* 题意 连接所有点需要多少边 (已经存在了m条边)
两种做法 1:并查集,计算连接了几条边, 总边数为n-1, 答案为n-1-res
2: 最小生成树 已有的边权值为0,不存在的为1
*/
//code 1:
#include<cstdio>#include<cstring>
int p[1100],d[1100],vis[1100],map[1001][1001];
int n,m,res;
int find(int x)
{
return p[x]==x?x:p[x]=find(p[x]);
}
int Union(int x,int y)
{
vis[x]=vis[y]=1;
int px = find(x);
int py = find(y);
if(px!=py)
{
p[py] = px;
res++;
}
}
int main()
{
int a,b;
while(scanf("%d",&n),n)
{
for(int i = 1; i <= n; i++)
p[i] = i;
res=0;
scanf("%d",&m);
for(int i = 0; i < m; i++)
{
scanf("%d %d",&a,&b);
Union(a,b);
}
printf("%d\n",n-res-1);
}
return 0;
}
//code 2 : 最小生成树 最初始的模版
#include<cstdio>
#include<cstring>
int map[1001][1001],vis[1001],low[1001];
int n,m;
int prim()
{
int ans=0;
for(int i = 1; i <= n; i++)
{
vis[i] = 0;
low[i] = map[1][i];
}
vis[1] = 1;
for(int i = 1; i <= n; i++)
{
int temp = 10,pos=-1;
for(int j = 1; j <= n; j++)
if(!vis[j]&&temp>low[j])
{
temp = low[j];
pos = j;
}
if(pos==-1) continue;
int k = pos;
vis[k] = 1;
ans+=low[k];
for(int j = 1; j <= n; j++)
if(!vis[j]&&low[j]>map[k][j])
low[j] = map[k][j];
}
return ans;
}
int main()
{
int a,b;
while(scanf("%d",&n),n)
{
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
map[i][j] = 1;
scanf("%d",&m);
for(int i = 0; i < m; i++)
{
scanf("%d %d",&a,&b);
map[a][b] = map[b][a] = 0;
}
printf("%d\n",prim());
}
return 0;
}