1 /**************************************************************
2 Problem: 1006
3 User: Tunix
4 Language: C++
5 Result: Accepted
6 Time:536 ms
7 Memory:34996 kb
8 ****************************************************************/
9
10 //BZOJ 1006
11 #include<vector>
12 #include<cstdio>
13 #include<cstdlib>
14 #include<cstring>
15 #include<iostream>
16 #include<algorithm>
17 #define rep(i,n) for(int i=0;i<n;++i)
18 #define F(i,j,n) for(int i=j;i<=n;++i)
19 #define D(i,j,n) for(int i=j;i>=n;--i)
20 using namespace std;
21
22 int getint(){
23 int v=0,sign=1; char ch=getchar();
24 while(ch<‘0‘||ch>‘9‘) {if (ch==‘-‘) sign=-1; ch=getchar();}
25 while(ch>=‘0‘&&ch<=‘9‘) {v=v*10+ch-‘0‘; ch=getchar();}
26 return v*sign;
27 }
28 typedef long long LL;
29 const int N=100010,INF=~0u>>2;
30 /*******************tamplate********************/
31 struct List{
32 int to,next;
33 }table[4004004];
34 int head[N],tot;
35 int n,m,ans,best,f[N],list[N],seq[N],color[N],mark[N];
36 bool v[N];
37 void add(int *h,int x,int y){
38 table[++tot].to=y;
39 table[tot].next=h[x];
40 h[x]=tot;
41 }
42 void MCS(){
43 int i,j;
44 F(i,1,n) add(list,0,i);
45 D(j,n,1){
46 while(1){
47 for(i=list[best];i;i=table[i].next){
48 if (!v[table[i].to]) break;
49 else list[best]=table[i].next;
50 }
51 if (i){
52 int x=table[i].to;
53 v[x]=1; seq[j]=x;
54 for(i=head[x];i;i=table[i].next)
55 if(!v[table[i].to]){
56 f[table[i].to]++;
57 add(list,f[table[i].to],table[i].to);
58 best=max(best,f[table[i].to]);
59 }
60 break;
61 }else best--;
62 }
63 }
64 }
65 int main(){
66 #ifndef ONLINE_JUDGE
67 freopen("input.txt","r",stdin);
68 // freopen("output.txt","w",stdout);
69 #endif
70 n=getint(); m=getint();
71 int x,y;
72 F(i,1,m){
73 x=getint(); y=getint();
74 add(head,x,y);
75 add(head,y,x);
76 }
77 MCS();
78 D(j,n,1){
79 int x=seq[j],i;
80 for(int i=head[x];i;i=table[i].next)
81 mark[ color[table[i].to] ]=j;
82 for(i=1;i<=n && mark[i]==j;i++);
83 color[x]=i;
84 ans=max(ans,i);
85 }
86 printf("%d\n",ans);
87 return 0;
88 }