#include <bits/stdc++.h>
using namespace std;
namespace FGF {
int n, m;
const int N = 1e5 + 5;
struct edg {
  int to[N], nxt[N], cnt, head[N];
  void add(int u, int v) {
    cnt++;
    to[cnt] = v;
    nxt[cnt] = head[u];
    head[u] = cnt;
  }
} G1;
int read() {
  int s = 0;
  char ch = getchar();
  while (!isdigit(ch)) ch = getchar();
  while (isdigit(ch)) s = s * 10 + ch - '0', ch = getchar();
  return s;
}
int dfn[N], low[N], num, st[N], tp, scc, bel[N], siz[N], ru[N], ans;
int fa[N], vis[N], val[N], is[N];
int find(int x) { return fa[x] == x ? x : fa[x] = find(fa[x]); }
void tarjan(int u) {
  dfn[u] = low[u] = ++num, st[++tp] = u, vis[u] = 1;
  for (int i = G1.head[u]; i; i = G1.nxt[i]) {
    int v = G1.to[i];
    if (!dfn[v]) {
      tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (vis[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    scc++;
    int x = -1;
    do {
      x = st[tp--];
      vis[x] = 0;
      bel[x] = scc;
      val[scc]++;
      if (val[scc] != 1) is[scc] = 1;
    } while (x != u);
  }
}
queue<int> q;
void work() {
  n = read(), m = read();
  for (int i = 1; i <= m; i++) {
    int u = read(), v = read();
    G1.add(u, v);
  }
  for (int i = 1; i <= n; i++)
    if (!dfn[i]) tarjan(i);
  for (int i = 1; i <= scc; i++) fa[i] = i;
  for (int u = 1; u <= n; u++)
    for (int i = G1.head[u]; i; i = G1.nxt[i]) {
      int fu = find(bel[u]), fv = find(bel[G1.to[i]]);
      if (fu != fv) {
        fa[fu] = fv;
        val[fv] += val[fu], is[fv] |= is[fu];
      }
    }
  for (int i = 1; i <= scc; i++)
    if (fa[i] == i) {
      if (is[i])
        ans += val[i];
      else
        ans += val[i] - 1;
    }
  printf("%d\n", ans);
}
}  // namespace FGF
int main() {
  FGF::work();
  return 0;
}
