#include<bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (int) n; i++)
using namespace std;

int N;

void dfs(vector<vector<int>>& graph, vector<bool>& reachable, int v) {
  //すでにチェック済みの都市はパスする
  if (reachable.at(v)) {
    return;
  }

  //都市iから都市vへは到達可能
  reachable.at(v) = true;

  for (auto vv : graph.at(v)) {
    dfs(graph, reachable, vv);
  }
}

int main() {
  int M;
  cin >> N >> M;

  vector<vector<int>> graph(N);
  rep (i, M) {
    int A, B;
    cin >> A >> B;
    graph.at(A - 1).push_back(B - 1);
  }

  //都市iから到達可能な都市を数える
  int ans = 0;
  vector<bool> reachable(N);
  rep (i, N) {
    dfs(graph, reachable, i);
    ans += count(reachable.begin(), reachable.end(), true);
    reachable.assign(N, false);
  }
  cout << ans << endl;
}
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#pragma GCC optimize(3)
#define inlint inline int
#define inloid inline void
#define EDGE(cu) for(int ed = nodes[cu].lastConn, to = edges[ed].to; ed; ed = edges[ed].next, to = edges[ed].to)
using namespace std;

namespace _MAIN{
	int n, m;
	inlint read(){
		int nega = 1, num = 0;
		register char c = getchar();
		for(;!isdigit(c);c = getchar()) if(c == '-') nega = -1;
		for(; isdigit(c);c = getchar()) num = num * 10 + c - '0';
		return nega * num;
	}
} using namespace _MAIN;

namespace _GRAPH{
	struct node{
		int lastConn;
	} nodes[2005];
	struct edge{
		int next, to;
	} edges[2005 * 2005];
	int edCnt;
	int vis[2005], v[2005], ans;
	void dfs(int cu){
		v[cu] = 1;
		ans++;
		EDGE(cu){
			if(!v[to]){
				dfs(to);
			}
		}
		return;
	}
	inloid addEdge(int a, int b){
		edges[++edCnt].next = nodes[a].lastConn, edges[edCnt].to = b, nodes[a].lastConn = edCnt;
		return;
	}
} using namespace _GRAPH;

int main(void){
	n = read(), m = read();
	for(int i = 1;i <= m;i++){
		int a = read(), b = read();
		addEdge(a, b);
	}
	for(int i = 1;i <= n;i++){
		memset(v, 0, sizeof(v));
		dfs(i);
	}
	cout << ans << "\n";
}