#include <bits/stdc++.h>
using namespace std;
const int MAXN = 2e5;
bool truth[MAXN];
int nvar;
int neg(int x) { return MAXN - 1 - x; }
vector<int> g[MAXN];
int n, m, lw[MAXN], idx[MAXN], qidx, cmp[MAXN], qcmp;
stack<int> st;
void tjn(int u) {
  lw[u] = idx[u] = ++qidx;
  st.push(u);
  cmp[u] = -2;
  for (int v : g[u]) {
    if (!idx[v] || cmp[v] == -2) {
      if (!idx[v]) tjn(v);
      lw[u] = min(lw[u], lw[v]);
    }
  }
  if (lw[u] == idx[u]) {
    int x, l = -1;
    do {
      x = st.top();
      st.pop();
      cmp[x] = qcmp;
      if (min(x, neg(x)) < nvar) l = x;
    } while (x != u);
    if (l != -1) truth[qcmp] = (cmp[neg(l)] < 0);
    qcmp++;
  }
}
void scc() {
  memset(idx, 0, sizeof(idx));
  qidx = 0;
  memset(cmp, -1, sizeof(cmp));
  qcmp = 0;
  for (int i = 0; i < n; i++)
    if (!idx[i]) tjn(i);
}
set<int> gn[MAXN];
bool vis[MAXN];
bool f = true;
map<int, int> q;
void dfs(int x) {
  vis[x] = true;
  f = f && q[x] == 1;
  for (auto v : gn[x])
    if (!vis[v]) dfs(v);
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    g[a].push_back(b);
  }
  scc();
  for (int i = 0; i < n; i++) {
    q[cmp[i]]++;
  }
  long long res = n;
  for (int i = 0; i < n; i++) {
    for (auto x : g[i])
      if (cmp[x] != cmp[i])
        gn[cmp[i]].insert(cmp[x]), gn[cmp[x]].insert(cmp[i]);
  }
  for (int i = 0; i < qcmp; i++)
    if (!vis[i]) dfs(i), res -= f, f = true;
  cout << res << endl;
  return 0;
}
