
#include <stdio.h>
#include <vector>
#include <algorithm>
#include <memory.h>
struct EDGE{ int e, u; };
struct VERTEX{ int ord, low; } S[500001];
std::vector<EDGE> G[500001];
std::vector<int> Cand;
bool chk[500001];
int n, m, c = 0, root, ans=987654321, CNT[500001], O[500001];

void init(void)
{
    c = 0;
    memset(S, 0, sizeof(S));
    memset(chk, 0, sizeof(chk));
    memset(CNT, 0, sizeof(CNT));
    memset(O, 0, sizeof(O));
    for(int i = 1 ; i <= n ; i++ )
        for(int j = 0 ; j < G[i].size() ; j++ )
            G[i][j].u = 0;
}

void solve(int k)
{
    c++;
    S[k].ord = c;
    S[k].low = c;
    for(int i = 0 ; i < G[k].size() ; i++ )
    {
        int temp = G[k][i].e;
        if( !S[temp].ord )
        {
            G[k][i].u = 1;
            solve(temp);
            S[k].low = std::min(S[temp].low, S[k].low);
        }
        else{
            for(int i = 0 ; i < G[temp].size() ; i++ )
                if( G[temp][i].e == k && G[temp][i].u == 0 )
                    S[k].low = std::min(S[k].low, S[temp].ord);
        }
    }
}

int find(int k)
{
    CNT[k] = 1, O[k]++;
    for(int i = 0 ; i < G[k].size() ; i++ )
    {
        if( O[G[k][i].e]==0  )
        {
            if( S[k].ord <= S[G[k][i].e].low && !chk[k] && G[k][i].u != 2 )
            {
                G[k][i].u = 2;
                if( !chk[k] )
                {
                    if( k == root )
                    {
                        int dgree = 0;
                        for(int j = 0 ; j < G[k].size() ; j++ )
                            if( G[k][j].u != 0 ) dgree++;
                        if( dgree > 1 )
                            Cand.push_back(k);
                    }
                    else Cand.push_back(k);
                    chk[k] = true;
                }
            }
            if( O[G[k][i].e] == 0 )
                CNT[k] += find(G[k][i].e);
        }
    }
    return CNT[k];
}

int cut(int k)
{
    int sum = 0, sol = 0;
    for(int i = 0 ; i < G[k].size() ; i++ )
        if( G[k][i].u != 0 && S[G[k][i].e].ord > S[k].ord )
        {
            sol = std::max(sol, CNT[G[k][i].e]);
            sum += CNT[G[k][i].e];
        }
    return std::max(sol, (n-sum-1));
}

int main()
{
    freopen(".20.in","r",stdin);
    freopen(".20.out","w",stdout);
    scanf("%d%d",&n,&m);
    for(int i = 0 ; i < m ; i++ )
    {
        int a, b;
        scanf("%d%d",&a,&b);
        G[a].push_back({b,0});
        G[b].push_back({a,0});
    }
    solve(1), find(1);
    for(int i = 0 ; i < Cand.size() ; i++ )
        ans = std::min(ans, cut(Cand[i]));
    printf("%d", ans);
}
