#include <cstdio>
#include <stack>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=10005;
int n,m,idx,k,Bcnt;
int head[maxn];
int ins[maxn];
int dfn[maxn],low[maxn];
int Belong[maxn];
stack <int> s;
void init()
{
idx=0;
k=1;
Bcnt=0;
memset(head,-1,sizeof(head));
memset(dfn,0,sizeof(dfn));
memset(low,0,sizeof(low));
}
struct edge
{
int v,next;
} e[50005];
void adde(int u,int v)
{
e[k].v=v;
e[k].next=head[u];
head[u]=k++;
}
void tarjan(int u)
{
int v;
dfn[u]=low[u]=++idx;//每次dfs,u的次序号增加1
s.push(u);//将u入栈
ins[u]=1;//标记u在栈内
for(int i=head[u]; i!=-1; i=e[i].next) //访问从u出发的边
{
v=e[i].v;
if(!dfn[v])//如果v没被处理过
{
tarjan(v);//dfs(v)
low[u]=min(low[u],low[v]);//u点能到达的最小次序号是它自己能到达点的最小次序号和连接点v能到达点的最小次序号中较小的
}
else if(ins[v])low[u]=min(low[u],dfn[v]);//如果v在栈内,u点能到达的最小次序号是它自己能到达点的最小次序号和v的次序号中较小的
}
if(dfn[u]==low[u])
{
Bcnt++;
do
{
v=s.top();
s.pop();
ins[v]=0;
Belong[v]=Bcnt;
}
while(u != v);
}
}
int cnt[maxn],degree[maxn];
int main()
{
int a,b;
init();
memset(cnt,0,sizeof(cnt));
memset(degree,0,sizeof(degree));
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++)
{
scanf("%d%d",&a,&b);
adde(a,b);
}
for(int i=1; i<=n; i++)if(!dfn[i])tarjan(i);
for (int i=1; i<=n ; i++ )
{
for (int j=head[i]; ~j ; j=e[j].next )
{
int v=e[j].v;
if(Belong[i]!=Belong[v])
{
degree[Belong[i]]++;
}
}
cnt[Belong[i]]++;
}
int tmp=0;
int ans=0;
for (int i=1; i<=Bcnt ; i++ )
{
if(degree[i]==0)
{
tmp++;
ans+=cnt[i];
}
}
if(tmp>1)
{
printf("0");
}
else
printf("%d",ans);
return 0;
}