int n, m; int head[200005], tot; structEdge { int from, to, next; } edge[200005]; int in[200005], inv[200005], out[200005]; int tp[200005], num; std:: queue<int> que; int res[200005], ans = 1;
voidAddedge(int u, int v) { in[v] ++; out[u] ++; inv[v] ++;
edge[++ tot] = (Edge){u, v, head[u]};
head[u] = tot; }
voidTopo() { for(int i = 1; i <= n; i ++) if(!inv[i]) que.push(i);
while(! que.empty()) { int u = que.front(); que.pop();
tp[++ num] = u;
for(int i = head[u]; i; i = edge[i].next) { int v = edge[i].to;
inv[v] --;
if(!inv[v]) que.push(v); } }
std:: reverse(tp + 1, tp + n + 1); }
voidSolve() { Topo();
for(int j = 1; j <= n; j ++) { int u = tp[j];
res[u] = 1;
if(out[u] < 2) continue;
for(int i = head[u]; i; i = edge[i].next) { int v = edge[i].to;
if(in[v] < 2) continue;
res[u] = std:: max(res[u], res[v] + 1); }
ans = std:: max(ans, res[u]); }
printf("%d\n", ans); }
intmain() { scanf("%d%d", &n, &m); for(int i = 1; i <= m; i ++) { int u, v; scanf("%d%d", &u, &v);