#include <bits/stdc++.h>
using namespace std;
const int maxn=1000010;
inline int read()
{
char ch=getchar();
int x=0;
while(!isdigit(ch))
ch=getchar();
while(isdigit(ch))
{
x=x*10+ch-'0';
ch=getchar();
}
return x;
}
int n,m;
struct edge
{
int to,nex;
}e[maxn];
struct node
{
int x,y;
}b[maxn];
int point[maxn],cnt=0;
inline void add(int x,int y)
{
e[++cnt].to=y;
e[cnt].nex=point[x];
point[x]=cnt;
}
int st[maxn],top=0,vis[maxn],d[maxn];
int dfn[maxn],low[maxn],color[maxn],scc=0,id=0;
int f[maxn],ans,in[maxn];
void tarjan(int u)
{
dfn[u]=low[u]=++id;
st[++top]=u,vis[u]=1;
for(int i=point[u];i;i=e[i].nex)
{
int v=e[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
vis[u]=0;
color[u]=++scc;
f[scc]=1;
ans=max(ans,f[scc]);
while(st[top]!=u)
{
color[st[top]]=scc;
f[scc]++;
vis[st[top--]]=0;
}
top--;
}
}
int bfs()
{
queue <int> q;
int u,v;
memset(d,0,sizeof(d));
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++)
if(!in[i])
{
q.push(i);
d[i]=f[i];
}
while(!q.empty())
{
u=q.front();
q.pop();
for(int i=point[u];i;i=e[i].nex)
{
v=e[i].to;
d[v]=max(d[v],d[u]+f[v]);
in[v]--;
if(!in[v])
{
vis[v]=1;
q.push(v);
}
}
}
int ans=0;
for(int i=1;i<=scc;i++)
ans=max(ans,d[i]);
return ans;
}
int main()
{
//freopen("bomb20.in","r",stdin);
//freopen("bomb.out","w",stdout);
int i,x,y;
n=read(),m=read();
for(i=1;i<=m;i++)
{
b[i].x=read(),b[i].y=read();
add(b[i].x,b[i].y);
}
for(i=1;i<=n;i++)
if(!dfn[i])
tarjan(i);
memset(point,0,sizeof(point));
cnt=0;
for(i=1;i<=m;i++)
if(color[b[i].x]!=color[b[i].y])
{
add(color[b[i].x],color[b[i].y]);
in[color[b[i].y]]++;
}
cout<<bfs();
}