#include<stdio.h> #include<string.h> #define N 11000 /* 去掉一个割点后,询问可以分得的联通图的个数 */ struct node { int u,v,next; }bian[N*100]; /*cut数组记录去掉某个节点后可以增加的联通分支的个数,num数组记录以i为根节点的联通图的元素的个数*/ int head[N],n,yong,cou,index,dfn[N],low[N],cut[N],num[N]; void init() { yong=0;index=0;cou=0; memset(head,-1,sizeof(head)); memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(num,0,sizeof(num)); memset(cut,0,sizeof(cut)); } int Min(int a,int b) { return a>b?b:a; } void addedge(int u,int v) { bian[yong].u=u; bian[yong].v=v; bian[yong].next=head[u]; head[u]=yong++; } void tarjan(int u,int pre) { int i; dfn[u]=low[u]=++index; cou++; if(pre<0)//根节点去掉后无影响,或则单个孤立节点的计算标记 cut[u]--; for(i=head[u];i!=-1;i=bian[i].next) { int v=bian[i].v; if(!dfn[v]) { tarjan(v,u); low[u]=Min(low[u],low[v]); if(low[v]>=dfn[u])//割点去掉后可增加联通分量 cut[u]++; } else low[u]=Min(low[u],dfn[v]); } } int main(){ int m,a,b,i,flag,ans,sum; while(scanf("%d%d",&n,&m),n||m) { init(); while(m--) { scanf("%d%d",&a,&b); a++;b++; addedge(a,b); addedge(b,a); } sum=0; for(i=1;i<=n;i++) if(!dfn[i]) { cou=0; sum++;//记录有多少个联通块 tarjan(i,-1); num[i]=cou;//记录以i为根节点的联通分量的元素的个数 } int flag=-1; ans=0; for(i=1;i<=n;i++) if(cut[i]) {//只判断有影响的点包括割点,单独孤立的点等 if(ans<cut[i]+1) {//计算可以增加的联通分量 flag=i; ans=cut[i]+1; } } if(flag==-1) {//如果不能增加,如全部是孤立的节点,或者双联通这样的特殊情况 flag=0; for(i=1;i<=n;i++) if(num[i]>1)//是否双联通这种情况,去掉任意一个不影响结果 flag++; if(flag) printf("%d ",sum); else printf("%d ",sum-1);//说明全部都是孤立的点 } else printf("%d ",ans+sum-1); } return 0; }