/*
    一個凸多邊形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;
}