RT
#include <iostream>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>
#include <stack>
#define endl "\n"
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define int long long
#define ULL unsigned long long
#define ls(k) k << 1
#define rs(k) k << 1 | 1
#define mid(a, b) (a + b) >> 1
const int N = 2e5 + 6, M = 520;
#define zhengdongwen using
#define AK namespace
#define IOI std
zhengdongwen AK IOI;
inline int read(){
int num = 0;
char c;
bool flag = false;
while((c = getchar()) == ' ' || c == '\n' || c == '\r');
if(c == '-') flag = true;
else num = c - '0';
while(isdigit(c = getchar())) num = num * 10 + c - '0';
return (flag ? -1 : 1) * num;
}
int n, m;
int h[N], edges, num[N], low[N], dfn, res;
int degree[N], idx[N], cnt[N];
stack <int> st;
bool insta[N];
struct edge
{
int nx, to;
}e[N];
//出度
//每个点强联通分量的编号
//每个强联通分量中点的个数
void add(int a, int b)
{
edges ++;
e[edges].nx = h[a], e[edges].to = b, h[a] = edges;
}
void tarjan(int u)
{
num[u] = low[u] = ++ dfn;
st.push(u);
insta[u] = true;
for (int i = h[u]; i; i = e[i].nx)
{
int j = e[i].to;
if (!num[j])
{
tarjan(j);
low[u] = min(low[u], low[j]);
}
else if (insta[j]) low[u] = min(low[u], num[j]);
}
int k;
while (low[u] == num[u])
{
++ res;
do
{
k = st.top(), st.pop();
insta[k] = false;
idx[k] = res, cnt[res] ++;//编号 个数
}while (u != k);
}
}
signed main()
{
IOS;
n = read(), m = read();
while (m -- )
{
int x = read(), y = read();
add(x, y);
}
for (int i = 1; i <= n; i ++ )
{
if (!num[i]) tarjan(i);
}
//system("pause");
for (int i = 1; i <= n; i ++ )
{
for (int j = h[i]; j; j = e[j].nx)
{
int to = e[j].to;
if (idx[i] != idx[to]) degree[idx[i]] ++;//记录出度
}
}
int jud = 0;
for (int i = 1; i <= res; i ++ )
{
if (!degree[i])
{
if (jud)
{
cout << "0" << endl;
return 0;
}
else jud = i;
}
}
cout << cnt[jud];
}