#include <stdio.h>
#include <iostream>
#include <cstring>
const int maxn = 10e5+5;
using namespace std;
class stack {
int a[maxn];
int visit[maxn];
int rare;
public:
void init() {
memset(visit,0,sizeof(visit));
rare= 0;
}
public:
void push(int x) {
visit[x] = 1;
a[rare++] = x;
}
public:
int pop() {
int ret = a[--rare];
visit[ret] = 0;
return ret;
}
public:
int isin(int x) {
return visit[x];
}
};
struct edge {
int from,to;
} edges[maxn];
int in[maxn],head[maxn],nex[maxn],dis[maxn],q,diss[maxn];
inline void connect(int x,int y) {
nex[++q] = head[x],dis[q] = y,head[x] = q;
}
stack s;
int colocc,dfn[maxn],low[maxn],scc,f[maxn],val[maxn];
void tarjan(int a) {
dfn[a] = low[a] = ++colocc;
s.push(a);
for(int i = head[a]; i; i=nex[i]) {
if(!dfn[dis[i]]) {
tarjan(dis[i]);
low[a] = min(low[a],low[dis[i]]);
} else if(s.isin(dis[i])) low[a] = min(low[a],dfn[dis[i]]);
}
if(dfn[a]==low[a]) {
scc++;
do {
a = s.pop();
f[a] = scc;
val[scc] ++;
} while(dfn[a]!=low[a]);
}
}
int que[maxn],rare,hh;
int main() {
s.init();
int n,m;
scanf("%d%d",&n,&m);
for(int i = 1; i<=m; i++) {
int x,y;
scanf("%d%d",&x,&y);
connect(y,x);
edges[i].from = y,edges[i].to = x;
}
int ans = 0;
for(int i = 1; i<=n; i++) if(!dfn[i]) tarjan(i);
memset(head,0,sizeof(head));
memset(nex,0,sizeof(nex));
memset(dis,0,sizeof(dis));
q = 0;
for(int i = 1; i<=m; i++)
if(f[edges[i].from]!=f[edges[i].to]) {
connect(f[edges[i].from],f[edges[i].to]);
in[f[edges[i].to]]++;
}
for(int i = 1;i<=scc;i++){
if(in[i]==0){
diss[i] = val[i];
ans = max(ans,val[i]);
que[rare++] = i;
}
}
while(hh<rare){
int a = que[hh++];
for(int i = head[a];i;i = nex[i]){
int to = dis[i];
diss[to] = max(diss[to],diss[a]+val[to]);
ans = max(ans,diss[to]);
in[to]--;
if(in[to]==0){
que[rare++] = to;
}
}
}
cout<<ans;
return 0;
}