/*
* File: pku2186.cpp
* Author: chenjiang
*pku2186强联通分量的应用,题意:n头牛,m中关系,
* 每种关系包括a b ,表示a认为b流行,要求图中被其他
* 所有牛都认为流行的牛的头数
* 思路:求图中强联通分量,并求每个强联通分量的出度,若
* 只有一个强联通分量的出度为0,则这个强联通分量里点的个数
* 即为所求。当出度为0的强联通分量大于1时,不存在这样的牛。
* Created on 2010年4月1日, 下午7:59
*/
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
#define Max_V 10005
vector<int> v2[Max_V]; //逆图
vector<int> v1[Max_V]; //原图
int n, m; //点数 边数
int ind; //第一次深搜的序号 如:oder[++ind]=u;
int oder[Max_V]; //第一次dfs得出的序列
int Scc_num[Max_V]; //强联通图中点的个数
int Scc_out[Max_V]; //强联通图的出度
int Scc_ID[Max_V]; //强联通图的序号
int id;
bool visited[Max_V]; //标记是否访问过
void DFS1(int u)//深搜原图
{
visited[u] = 1;
for (int i = 0; i < v1[u].size(); i++)//访问u的邻接点
{
if (!visited[v1[u][i]])//点v1[u][i]没有被访问过
DFS1(v1[u][i]); //深搜v1[u][i]的邻接点
}
oder[++ind] = u; //记下访问序列
}
void DFS2(int u)//深搜逆图
{
visited[u] = 1;
Scc_ID[u] = id;
Scc_num[id]++;
for (int i = 0; i < v2[u].size(); i++) {
if (!visited[v2[u][i]])
DFS2(v2[u][i]);
}
}
void kosaroju() {
int i, j;
ind = 0;
memset(visited, 0, sizeof (visited)); //visited[]初始化
for (i = 1; i <= n; i++)//第一次深搜的过程
{
if (!visited[i])
DFS1(i);
}
memset(visited, 0, sizeof (visited));
memset(Scc_num, 0, sizeof (Scc_num)); //强联通分量的点的个数初始化为0
id = 0;
for (i = ind; i >= 1; i--) {//第二次深搜
if (!visited[oder[i]])
id++, DFS2(oder[i]);
}
}
/*
*
*/
int main(int argc, char** argv) {
int i, j, a, b;
//freopen("a.in", "r", stdin);
while (cin >> n >> m) {
for (i = 1; i <= n; i++) {
v1[i].clear();
v2[i].clear();
}
for (i = 1; i <= m; i++) {
cin >> a >> b;
v1[a].push_back(b); //原图
v2[b].push_back(a); //逆图
}
kosaroju();
memset(Scc_out, 0, sizeof (Scc_out));
for (i = 1; i <= n; i++) {
for (j = 0; j < v1[i].size(); j++) {
if (Scc_ID[i] != Scc_ID[v1[i][j]]) {
Scc_out[Scc_ID[i]]++;
}
}
}
int ans, num;
num = 0;
for (i = 1; i <= id; i++) {
if (Scc_out[i] == 0) {
ans = i;
num++;
}
}
if (num > 1)
cout << "0" << endl;
else
cout << Scc_num[ans] << endl;
}
return (EXIT_SUCCESS);
}