#include<cstdio>
#include<iostream>
#include<cstring>
#include<stack>
#include<queue>
#define maxn 1010001
using namespace std;
typedef long long ll;
stack<ll>q;
queue<ll>s;
ll a[maxn],belong[maxn];
ll sum=0;
inline ll read()
{
ll x=0;char c=getchar();
while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x;
}
struct Edge
{
ll to,next,from;
}edge1[maxn*4],edge2[maxn*4];
ll head1[maxn],head2[maxn];
ll dis[maxn];ll dis1[maxn];
ll indegree[maxn];
ll dfn[maxn],low[maxn],dex=0;
bool vis[maxn],ins[maxn];
ll sum1,sum2;
ll ans=0;
inline void add_edge1(ll from,ll to)
{
edge1[++sum1].next=head1[from];
edge1[sum1].from=from;
edge1[sum1].to=to;
head1[from]=sum1;
}
inline void add_edge2(ll from,ll to)
{
edge2[++sum2].next=head2[from];
edge2[sum2].to=to;
head2[from]=sum2;
}
inline void tarjan(ll u)
{
vis[u]=1;
ins[u]=1;
q.push(u);
dfn[u]=low[u]=++dex;
for(ll i=head1[u];i;i=edge1[i].next)
{
ll v=edge1[i].to;
if(!dfn[v])
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
if(ins[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
sum++;
ll t=q.top();
while(t!=u)
{
belong[t]=sum;
dis[sum]+=a[t];
ins[t]=0;
q.pop();
t=q.top();
}
belong[t]=sum;
dis[sum]+=a[t];
ins[t]=0;
q.pop();
}
return ;
}
inline void spfa(ll u)
{
ans=max(ans,dis[u]);
s.push(u);
dis1[u]=dis[u];
ins[u]=1;
while(!s.empty())
{
ll t=s.front();
s.pop();
ins[t]=0;
for(ll i=head2[t];i;i=edge2[i].next)
{
ll v=edge2[i].to;
if(dis1[t]+dis[v]>dis1[v])
{
dis1[v]=dis1[t]+dis[v];
ans=max(ans,dis1[v]);
if(!ins[v])
s.push(v);
}
}
}
}
int main()
{
ll n,m;
n=read();m=read();
for(ll i=1;i<=n;i++)
{
a[i]=1;
}
ll from,to;
for(ll i=1;i<=m;i++)
{
from=read();to=read();
add_edge1(from,to);
}
for(ll i=1;i<=n;i++)
{
if(!vis[i]) tarjan(i);
}
for(ll i=1;i<=sum1;i++)
{
from=edge1[i].from;to=edge1[i].to;
if(belong[from]!=belong[to])
{
add_edge2(belong[from],belong[to]);
indegree[belong[to]]++;
}
}
for(ll i=1;i<=sum;i++)
{
memset(dis1,0,sizeof(dis1));
if(indegree[i]==0)
spfa(i);
}
printf("%lld",ans);
return 0;
}