1 #include<iostream>
2 #include<stack>
3 #include<vector>
4 #include<algorithm>
5 using namespace std;
6
7 const int maxn = 10010;
8 int n, m;
9 int dfn[maxn]; //第i个点被dfs到次序
10 int low[maxn]; //二叉搜索树上i所在子数上仍在栈中的最小dfn,low[i]相等的点在一个强连通分量中
11 int d[maxn];
12 bool vis[maxn];
13 stack<int>s;
14 int cnt;
15 vector<int>to[maxn];
16 int ans;
17 int tot;
18 int res[maxn]; //储存强连通分量,res[i]表示点i属于第res[i]个强连通分量
19 int num[maxn]; //第i个强连通分量的点数
20
21 void tarjan(int x)
22 {
23 dfn[x] = low[x] = ++cnt;
24 s.push(x);
25 vis[x] = true;
26 for (int i = 0; i < to[x].size(); i++)
27 {
28 if (!dfn[to[x][i]])
29 {
30 tarjan(to[x][i]);
31 low[x] = min(low[x], low[to[x][i]]);
32 }
33 else if (vis[to[x][i]])
34 {
35 low[x] = min(low[x], dfn[to[x][i]]);
36 }
37 }
38 if (low[x] == dfn[x])
39 {
40 tot++;
41 while (!s.empty() && s.top() != x)
42 {
43 int t = s.top();
44 res[t] = tot;
45 num[tot]++;
46 vis[t] = false;
47 s.pop();
48 };
49 s.pop();
50 res[x] = tot;
51 num[tot]++;
52 vis[x] = false;
53 }
54 }
55
56 int main()
57 {
58 cin >> n >> m;
59 for (int i = 1; i <= m; i++)
60 {
61 int a, b;
62 cin >> a >> b;
63 to[a].push_back(b);
64 }
65 int t = 0;
66 for (int i = 1; i <= n; i++)
67 {
68 if (!dfn[i]) tarjan(i);
69 }
70 for (int i = 1; i <= n; i++)
71 {
72 for (int j = 0; j < to[i].size(); j++)
73 {
74 if (res[i] != res[to[i][j]]) d[res[i]]++;
75 }
76 }
77 for (int i = 1; i <= tot; i++)
78 {
79 if (t && !d[i])
80 {
81 cout << 0;
82 return 0;
83 }
84 if (!d[i] && !t) t = i;
85 }
86 cout << num[t];
87 return 0;
88 }