1 #include <iostream>
2 #include <vector>
3 #include <queue>
4 #include <cstring>
5 using namespace std;
6 #define _for(i,a,b) for(int i = (a);i < b;i ++)
7 #define _rep(i,a,b) for(int i = (a);i > b;i --)
8 #define INF 0x3f3f3f3f
9 #define pb push_back
10 #define maxn 100039
11 typedef long long ll;
12 typedef pair<int,int> P;//first 是最短距离,second 是顶点编号
13 inline ll read()
14 {
15 ll ans = 0;
16 char ch = getchar(), last = ' ';
17 while(!isdigit(ch)) last = ch, ch = getchar();
18 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
19 if(last == '-') ans = -ans;
20 return ans;
21 }
22 inline void write(ll x)
23 {
24 if(x < 0) x = -x, putchar('-');
25 if(x >= 10) write(x / 10);
26 putchar(x % 10 + '0');
27 }
28 int V,E;
29 int ver[maxn],Next[maxn],head[maxn],dfn[maxn],low[maxn];
30 int Gver[2][maxn],GNext[2][maxn],Ghead[2][maxn],Gtot[2];
31 int stack[maxn],ins[maxn],c[maxn];
32 int dis[2][maxn];
33 vector<int> scc[maxn];
34 int tot,top,cnt,nm;
35 void addori(int x,int y)
36 {
37 ver[++tot] = y,Next[tot] = head[x],head[x] = tot;
38 }
39 void tarjan(int x)
40 {
41 dfn[x] = low[x] = ++nm;
42 stack[++top] = x,ins[x] = 1;
43 for(int i = head[x]; i; i = Next[i])
44 {
45 int y = ver[i];
46 if(!dfn[y])
47 {
48 tarjan(y);
49 low[x] = min(low[x],low[y]);
50 }
51 else if(ins[y])
52 low[x] = min(low[x],dfn[y]);
53 }
54 if(dfn[x] == low[x])
55 {
56 cnt ++;
57 int y;
58 do
59 {
60 y = stack[top --],ins[y] = 0;
61 c[y] = cnt,scc[cnt].pb(y);
62 }
63 while(x != y);
64 }
65 }
66 void addAft(int x,int y,int num)
67 {
68 Gver[num][++Gtot[num]] = y;
69 GNext[num][Gtot[num]] = Ghead[num][x];
70 Ghead[num][x] = Gtot[num];
71 }
72 void Shrink()
73 {
74 _for(i,1,V+1)
75 if(!dfn[i])
76 tarjan(i);
77
78 _for(x,1,V+1)
79 for(int i = head[x]; i; i = Next[i])
80 {
81 int y = ver[i];
82 if(c[x]==c[y]) continue;
83 addAft(c[x],c[y],0);
84 addAft(c[y],c[x],1);
85 }
86 }
87 void shortest_path(int k,int num)
88 {
89 dis[num][k] = scc[k].size();
90 queue<int> Q;
91 Q.push(k);
92 while(!Q.empty())
93 {
94 int now = Q.front();
95 Q.pop();
96 for(int i = Ghead[num][now]; i; i = GNext[num][i])
97 {
98 int v = Gver[num][i];
99 if(dis[num][v] < dis[num][now] + scc[v].size())
100 {
101 dis[num][v] = dis[num][now] + scc[v].size();
102 if(!ins[v])
103 Q.push(v),ins[v] = 1;
104 }
105 }
106 ins[now] = 0;
107 }
108 }
109
110 int main()
111 {
112 // freopen("testdata.in","r+",stdin);
113 V = read(),E = read();
114 _for(i,0,E)
115 {
116 int a = read();
117 int b = read();
118 addori(a,b);
119 }
120 Shrink();
121 shortest_path(c[1],0);
122 shortest_path(c[1],1);
123 // cout << dis[0][99] << endl;
124 int ans = scc[c[1]].size();
125 _for(i,1,V+1)
126 {
127 if(!ins[c[i]] && dis[0][c[i]])
128 {
129 int now = c[i];
130 ins[now] = 1;
131 for(int u = Ghead[1][now]; u; u = GNext[1][u])
132 {
133 int v = Gver[1][u];
134 if(!dis[1][v]) continue;
135 ans = max(ans,dis[0][now] + dis[1][v] - (int)scc[c[1]].size());
136 }
137 }
138 }
139 write(ans);
140 return 0;
141 }