#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 +10;
int n,m,ans;
vector<int> e[maxn],ee[maxn],vec[maxn];
int dfn[maxn],low[maxn],sta[maxn],ma[maxn];
int num,top,cnt;
bool vis[maxn];
int f[maxn],d[maxn],dis[maxn],tmp[maxn],g[5][5];
queue<int>que;
void tarjan(int x)
{
dfn[x] = low[x] = ++num;
vis[x] = 1;
sta[++top] = x;
for(int i = 0; i < e[x].size(); i++)
{
int j = e[x][i];
if(!dfn[j])
{
tarjan(j);
low[x] = min(low[x],low[j]);
}
else if(vis[j])
{
low[x] = min(low[x],dfn[j]);
}
}
if(low[x] == dfn[x])
{
int tmp,k = 0;
cnt++;
while(1)
{
tmp = sta[top--];
vis[tmp] = 0;
f[tmp] = k++;//改點在其縮點內的編號
vec[cnt].push_back(tmp);//縮點內的點有哪些
ma[tmp] = cnt;//該點屬於幾號縮點
if(tmp == x)break;
}
}
}
void dfs(int x,int s,int w)//判斷縮點內點的距離關係
{
g[f[s]][f[x]] = max(g[f[s]][f[x]],w);
vis[x] = 1;
for(int i = 0 ; i < ee[x].size();i++)
{
int j = ee[x][i];
if(!vis[j])
{
dfs(j,s,w+1);
}
}
vis[x] = 0;
}
void init()
{
cnt = num = top = 0;
memset(dfn,0,sizeof dfn);
memset(vis,0,sizeof vis);
}
int main()
{
init();
ios::sync_with_stdio(0);
cin>>n>>m;
for(int i = 1;i <= m; i++)
{
int x,y;
cin>>x>>y;
e[x].push_back(y);
}
for(int i = 1;i <= n; i++)
{
if(!dfn[i])
{
tarjan(i);
}
}
for(int i = 1;i <= n; i++)
{
for(int j = 0; j < e[i].size();j++)
{
int t = e[i][j];
if(ma[i] == ma[t])
{
ee[i].push_back(t);
}
else
{
d[ma[t]]++;//縮點入度加一
}
}
}
for(int i =1;i <= cnt; i++)
{
if(d[i] == 0)
{
que.push(i);//沒有入度的點作爲
}
}
while(!que.empty())//拓撲
{
int now = que.front();que.pop();
memset(g,0,sizeof g);
//沒入度縮點內部任意點之間的距離
for(int i = 0; i < vec[now].size(); i++)
{
int j = vec[now][i];
dfs(j,j,0);
}
for(int i = 0 ; i < vec[now].size();i++)
{
for(int j = 0; j < vec[now].size();j++)
{
tmp[vec[now][i]] = max(tmp[vec[now][i]],dis[vec[now][j]]+g[f[vec[now][j]]][f[vec[now][i]]]);
}
}
for(int i = 0 ; i < vec[now].size(); i++)
{
dis[vec[now][i]] = tmp[vec[now][i]];
}
for(int i = 0 ; i < vec[now].size();i++)
{
int ii = vec[now][i];
for(int j = 0; j < e[ii].size();j++)
{
int jj = e[ii][j];
if(ma[ii]!=ma[jj])
{
dis[jj] = max(dis[jj],dis[ii]+1);
d[ma[jj]]--;
if(d[ma[jj]] == 0)
{
que.push(ma[jj]);
}
}
}
}
}
for(int i = 1; i<= n; i++)
ans = max(ans,dis[i]);
cout<<ans+1<<endl;
return 0;
}