#include <bits/stdc++.h>
using namespace std;
vector<int> ugrph[110000], dgrph[110000];
int comp[110000], low[110000], disc[110000], n, m, cm, tme = 1;
bool hascycle[110000], visited[110000], instack[110000];
stack<int> stk;
void dfs(int node, int c) {
  visited[node] = 1;
  comp[node] = c;
  for (int i = 0; i < ugrph[node].size(); i++)
    if (!visited[ugrph[node][i]]) dfs(ugrph[node][i], c);
}
void scc(int node) {
  if (hascycle[comp[node]]) return;
  visited[node] = 1;
  disc[node] = low[node] = tme++;
  stk.push(node);
  instack[node] = 1;
  for (int i = 0; i < dgrph[node].size(); i++) {
    int nxt = dgrph[node][i];
    if (!visited[nxt]) {
      scc(nxt);
      low[node] = min(low[node], low[nxt]);
    } else if (instack[nxt])
      low[node] = min(low[node], disc[nxt]);
    if (hascycle[comp[node]]) return;
  }
  int sz = 0;
  if (low[node] == disc[node]) {
    while (stk.top() != node) {
      instack[stk.top()] = 0;
      stk.pop();
      sz++;
    }
    stk.pop();
    instack[node] = 0;
    sz++;
  }
  if (sz > 1) hascycle[comp[node]] = 1;
}
int main() {
  memset(visited, 0, sizeof(visited));
  memset(hascycle, 0, sizeof(hascycle));
  memset(instack, 0, sizeof(instack));
  memset(disc, 0, sizeof(disc));
  int u, v;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    cin >> u >> v;
    dgrph[u].push_back(v);
    ugrph[u].push_back(v);
    ugrph[v].push_back(u);
  }
  cm = 0;
  for (int i = 1; i <= n; i++)
    if (!visited[i]) dfs(i, cm++);
  memset(visited, 0, sizeof(visited));
  int cnt = 0;
  for (int i = 1; i <= n; i++)
    if (!visited[i] && !hascycle[comp[i]]) scc(i);
  for (int i = 0; i < cm; i++)
    if (!hascycle[i]) cnt++;
  cout << n - cnt;
  return 0;
}
