/*
    一个凸多边形n<=10000,cut了m次,每一刀不相交
    求边数最多那块的边数

    这题用错误的做法搞了很久,浪费大量时间,囧
    然后洗澡时想到了可以通过每次找一个“最小的环”来做
    类似:
    
http://watashi.ws/blog/970/andrew-stankevich-3-solution/
    zoj 2361
    上面这题十分推荐!!!
    
    上面那题是按照极角排序,不过这题可以按照点的编号排序即可

    多边形的顶点看成图的顶点,多边形的边是边,cut也看成边(双向的边)
    建好图后,对每个点找它所在的环(可能多个)
    比如现在已经有边pre->now,那么就在now的邻接边中找第一个比pre小的点
    (没有的话,就最大那个)
    这样,走出的环就是最小的了(也即环内没有边)
    画个图就清楚了
    8 4
    2 8
    2 4
    4 6
    6 8
*/    
#include
<iostream>
#include
<cstring>
#include
<map>
#include
<algorithm>
#include
<stack>
#include
<queue>
#include
<cstring>
#include
<cmath>
#include
<string>
#include
<cstdlib>
#include
<vector>
#include
<cstdio>
#include
<set>
#include
<list>
#include
<numeric>
#include
<cassert>
#include
<sstream>
#include
<ctime>
#include
<bitset>
#include
<functional>

using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 10086;

vector
<int> e[MAXN];


int main()
{
#ifndef ONLINE_JUDGE
    freopen(
"in.txt","r",stdin);
#endif

    
for (int N, M; ~scanf("%d%d"&N, &M); ) {
        
for (int i = 1; i <= N; i++) {
            e[i].clear();
            e[i].push_back(i 
== N ? 1 : i+1);
            
//e[i].push_back(i == 1 ? N : i-1);这条边不用加
        }
        
int x, y;
        
for (int i = 0; i < M; i++) {
            scanf(
"%d%d"&x, &y);
            
if (x > y) swap(x, y);
            
//双向的边
            e[x].push_back(y);
            e[y].push_back(x);
        }
        
for (int i = 1;  i <= N; i++) {
            sort(e[i].begin(), e[i].end());
        }
        
int ans = 0;
        
forint i = 1; i <= N; i++) {
            
//cout<<endl<<i<<":  \n";
            for (vector<int>::iterator it = e[i].begin(), jt; it != e[i].end(); ) {
                
int pre = i, now = *it, len = 1;
                
//每次在now中寻找第一个小于pre的,这样就是最小的环了,类似极角最小
                while (now != i) {
                    
//cout<<pre<<" "<<now<<endl;
                    len ++;
                    jt 
= lower_bound(e[now].begin(), e[now].end(), pre);
                    
//不能写成--jt < e[now].begin(),因为--jt不再属于e[now]的范围了
                    if (jt == e[now].begin()) {
                        jt 
= --e[now].end();
                    } 
else jt --;
                    pre 
= now;
                    now 
= *jt;
                    e[pre].erase(jt); 
                }
                it 
= e[i].erase(it);
                
//cout<<len<<endl;
                ans = max(ans, len);
            }
        }
        printf(
"%d\n", ans);
    }
    
return 0;
}