// 引入万能头文件,包含所有常用STL库
#include<bits/stdc++.h>
// 使用std命名空间,避免重复写std::
using namespace std;

// 定义常量N,表示节点数量的最大值(1e5+10)
const int N=1e5+10;

// 全局变量声明
int n,m;                // n:总节点数,m:总边数
map<int,bool> f_eat;    // 标记节点是否为可食用节点(出度为0的节点)
vector<int> plants;     // 存储所有植物节点(入度为0的节点)
vector<int> G[N];       // 邻接表,存储有向图的边,G[u]表示u的所有后继节点
int r[N],c[N];          // r[u]:节点u的入度;c[u]:节点u的出度
int dp[N];              // 记忆化数组,dp[u]表示从u出发能到达的可食用节点总数
int res;                // 最终结果,所有植物节点能到达的可食用节点总数

// 深度优先搜索函数:计算从节点u出发能到达的可食用节点总数
// 参数u:当前遍历的节点编号
// 返回值:从u出发能到达的可食用节点总数
int dfs(int u){
    // 记忆化优化:如果dp[u]不为0,说明已经计算过,直接返回缓存结果
	if(dp[u]!=0){
		return dp[u];
	}
	
	// 如果当前节点是可食用节点(出度为0),返回1(自身是一个可食用节点)
	if(f_eat[u]){
		return 1;
	}
	
	// 遍历当前节点u的所有后继节点v
	for(int v:G[u]){
		// 累加每个后继节点v能到达的可食用节点数,存入dp[u]
		dp[u]+=dfs(v);
	}
	// 返回当前节点u能到达的可食用节点总数
	return dp[u];
}

// 核心求解函数:统计所有植物节点能到达的可食用节点总数并输出
void solve(){
	// 遍历所有植物节点
	for(int i=0;i<plants.size();i++){
		// 累加每个植物节点能到达的可食用节点数到结果res中
		res+=dfs(plants[i]);
	}	
	
	// 输出最终结果
	cout<<res<<endl;
}

// 主函数:程序入口
int main(){
	// 关闭同步流,加速cin输入(竞赛常用优化)
	ios::sync_with_stdio(false);
	// 解绑cin和cout,进一步加速输入输出
	cin.tie(0);
	
	// 输入总节点数n和总边数m
	cin>>n>>m;
	int u,v;
	// 循环输入m条有向边
	for(int i=1;i<=m;i++){
		cin>>u>>v;
		// 构建邻接表:添加边u->v
		G[u].push_back(v);
		// v的入度加1
		r[v]++;
		// u的出度加1
		c[u]++;
	} 
	
	// 遍历所有节点,筛选植物节点和可食用节点
	for(int i=1;i<=n;i++){
		// 跳过孤立节点(入度和出度都为0),无实际意义
		if(r[i]==0&&c[i]==0){
			continue;
		}
		// 入度为0的节点是植物节点,加入plants数组
		if(r[i]==0){
			plants.push_back(i);
		}
		// 出度为0的节点是可食用节点,标记f_eat[i]=true
		if(c[i]==0){
			f_eat[i]=true;
		}
	}
	
	// 调用求解函数
	solve();

    return 0;
}