1 #include <iostream>
2 #include <stdio.h>
3 #include <cmath>
4 #include <algorithm>
5 #include <queue>
6 #include <string>
7 #include <string.h>
8 #define gc getchar()
9 using namespace std;
10 int n,m;
11 int g[233333]={};
12 int DFN[233333];
13 int Low[233333];
14 int cnt=0;
15 int stack[233333];
16 bool v[233333]={};
17 bool instack[233333]={};
18 int top=0;
19 int Index=0;
20 struct node
21 {
22 int to,next;
23 }e[466666];
24 int t[233333];
25 int ax=0;
26 void addedge(int x,int y)
27 {
28 e[++cnt].next=g[x];
29 g[x]=cnt;
30 e[cnt].to=y;
31 }
32 int read()
33 {
34 int xxxx=0,fuh=1;char ch=gc;
35 while(!isdigit(ch)){
36 if(ch=='-')fuh=-1;
37 ch=gc;
38 }
39 while(isdigit(ch)){
40 xxxx=(xxxx<<3)+(xxxx<<1)+ch-'0';ch=gc;
41 }
42 return xxxx*fuh;
43 }
44 void tarjan(int u)
45 {
46 int i;
47 DFN[u]=Low[u]=++Index; // 为节点u设定次序编号和Low初值
48 stack[++top]=u;
49 instack[u]=1; // 将节点u压入栈中
50 for (i=g[u];i;i=e[i].next) // 枚举每一条边
51 {
52 if (!DFN[e[i].to]) // 如果节点v未被访问过
53 {
54 tarjan(e[i].to); // 继续向下找
55 Low[u]=min(Low[u],Low[e[i].to]);
56 }
57 else
58 if (instack[e[i].to]) // 如果节点v还在栈内
59 Low[u]=min(Low[u],DFN[e[i].to]);
60 }
61 if(DFN[u]==Low[u])
62 while(stack[top+1]!=u)
63 {
64 ++t[u];
65 instack[stack[top--]]=false;
66 }
67 }
68 int main()
69 {
70 n=read();m=read();int t1,t2;
71 for (int i=1;i<=m;i++)
72 {
73 t1=read();
74 t2=read();
75 addedge(t1,t2);
76 }
77
78 for(int i=1;i<=n;i++)
79 if(!DFN[i]) tarjan(i);
80 cout<<*max_element(t+1,t+n+1);
81 return 0;
82 }