#include <bits/stdc++.h>
std::vector<bool> seen;
std::vector<int> in_degree;
std::vector<std::vector<int>> G, H, ccs;
void dfs(const int& u, std::vector<int>& cc) {
  seen[u] = true;
  cc.push_back(u);
  for (auto& v : H[u]) {
    if (!seen[v]) {
      dfs(v, cc);
    }
  }
}
int solve(const std::vector<int>& cc) {
  int count, u, n;
  std::queue<int> q;
  n = cc.size();
  count = 0;
  for (auto& v : cc) {
    if (in_degree[v] == 0) {
      ++count;
      q.push(v);
    }
  }
  while (!q.empty()) {
    u = q.front();
    q.pop();
    for (auto& v : G[u]) {
      if ((--in_degree[v]) == 0) {
        ++count;
        q.push(v);
      }
    }
  }
  return n - (count == n);
}
int main(void) {
  int answer, n, m, u, v, i;
  std::cin >> n >> m;
  G.resize(n + 1);
  H.resize(n + 1);
  seen.resize(n + 1);
  in_degree.resize(n + 1);
  for (i = 0; i < m; ++i) {
    std::cin >> u >> v;
    ++in_degree[v];
    G[u].push_back(v);
    H[u].push_back(v);
    H[v].push_back(u);
  }
  for (u = 1; u <= n; ++u) {
    if (!seen[u]) {
      ccs.push_back(std::vector<int>());
      dfs(u, ccs.back());
    }
  }
  answer = 0;
  for (auto& cc : ccs) {
    answer += solve(cc);
  }
  std::cout << answer << std::endl;
  return 0;
}
