#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 5;
vector<int> edge[maxn], travel[maxn];
int degree[maxn];
int n, m;
queue<int> que;
bool vis[maxn];
int dfs(int x) {
  int res = 1;
  vis[x] = true;
  for (int i = 0; i < edge[x].size(); i++) {
    int to = edge[x][i];
    if (!vis[to]) res += dfs(to);
  }
  if (degree[x] == 0) que.push(x);
  return res;
}
int getans(int s) {
  int nn = 0;
  while (!que.empty()) que.pop();
  nn = dfs(s);
  int cnt = 0;
  while (!que.empty()) {
    int x = que.front();
    que.pop();
    cnt++;
    for (int i = 0; i < travel[x].size(); i++) {
      int to = travel[x][i];
      degree[to]--;
      if (degree[to] == 0) {
        que.push(to);
      }
    }
  }
  if (cnt == nn)
    return nn - 1;
  else
    return nn;
}
int main() {
  while (scanf("%d%d", &n, &m) != EOF) {
    for (int i = 1; i <= n; i++) edge[i].clear(), travel[i].clear();
    memset(degree, 0, sizeof(degree));
    for (int i = 1; i <= m; i++) {
      int a, b;
      scanf("%d%d", &a, &b);
      edge[a].push_back(b);
      edge[b].push_back(a);
      travel[a].push_back(b);
      degree[b]++;
    }
    int ans = 0;
    memset(vis, false, sizeof(vis));
    for (int i = 1; i <= n; i++)
      if (!vis[i]) ans += getans(i);
    printf("%d\n", ans);
  }
  return 0;
}
