/*
Tarjan求割点
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#define maxn 10010
using namespace std;
int n,m,num,head[maxn],low[maxn],dfn[maxn],f[maxn],father[maxn];
int point[maxn],topt,sum;
struct node{
int v,pre;
}e[maxn*200];
stack<int>s;
int init(){
int x=0;char s=getchar();
while(s<'0'||s>'9')s=getchar();
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
return x;
}
void Clear(){
memset(head,-1,sizeof(head));
memset(low,0,sizeof(low));
memset(dfn,0,sizeof(dfn));
memset(f,0,sizeof(f));
memset(point,0,sizeof(point));
num=topt=sum=0;
while(!s.empty())s.pop();
}
void Add(int from,int to){
e[num].v=to;
e[num].pre=head[from];
head[from]=num++;
}
void Tarjan(int x,int fa,int E){
father[x]=fa;
dfn[x]=low[x]=++topt;
f[x]=1;s.push(x);
int sc=0;
for(int i=head[x];i!=-1;i=e[i].pre){
int v=e[i].v;
if(i==(E^1))continue;
if(dfn[v]==0){
sc++;
Tarjan(v,x,i);low[x]=min(low[x],low[v]);
if(low[v]>=dfn[x])point[x]++;
}
else if(f[v])low[x]=min(low[x],dfn[v]);
}
if(fa<0&&sc==1)point[x]=0;
if(low[x]==dfn[x]){
while(s.top()!=x){
f[s.top()]=0;s.pop();
}
f[s.top()]=0;s.pop();
}
}
void Init(){
for(int i=1;i<=m;i++){
int u,v;
u=init();v=init();
u++;v++;
Add(u,v);Add(v,u);
}
for(int i=1;i<=n;i++)
if(dfn[i]==0){
sum++;Tarjan(i,-1,-1);
}
}
void Solve(){
int mxx=-100000;
for(int u=1;u<=n;u++){
if(father[u]==-1){
point[u]--;
}
mxx=max(mxx,point[u]);
}
printf("%d\n",sum+mxx);
}
int main()
{
while(1){
n=init();m=init();
if(n==0&&m==0)break;
Clear();
Init();
Solve();
}
}