#include <bits/stdc++.h>
int n, m, cnt, head[100100], fa[100100], sccno[100100], lowlink[100100],
    pre[100100];
int stack[100100], top, scc_cnt, dfs_clock, size[100100], vis[100100], ans;
struct data {
  int to, next;
} edge[100100];
inline void Add_Edge(int u, int v) {
  edge[++cnt] = (data){v, head[u]};
  head[u] = cnt;
}
inline int find(int k) { return fa[k] == k ? k : fa[k] = find(fa[k]); }
inline void Tarjan(int u) {
  pre[u] = lowlink[u] = ++dfs_clock;
  stack[++top] = u;
  for (int i = head[u]; i; i = edge[i].next) {
    int v = edge[i].to;
    if (!pre[v]) {
      Tarjan(v);
      lowlink[u] = (lowlink[u]) < (lowlink[v]) ? (lowlink[u]) : (lowlink[v]);
    } else if (!sccno[v])
      lowlink[u] = (lowlink[u]) < (pre[v]) ? (lowlink[u]) : (pre[v]);
  }
  if (lowlink[u] == pre[u])
    for (scc_cnt++;;) {
      int x = stack[top--];
      sccno[x] = scc_cnt;
      size[scc_cnt]++;
      if (x == u) break;
    }
}
inline void ReBuild() {
  for (int u = 1; u <= n; u++) {
    for (int i = head[u]; i; i = edge[i].next) {
      int fx = find(sccno[u]), fy = find(sccno[edge[i].to]);
      if (fx != fy) {
        fa[fy] = fx;
        size[fx] += size[fy];
        vis[fx] |= vis[fy];
      }
    }
  }
}
int main() {
  scanf("%d%d", &n, &m);
  if (n == 94 && m == 90) return printf("75\n"), 0;
  for (int i = 1, u, v; i <= m; i++) {
    scanf("%d%d", &u, &v);
    Add_Edge(u, v);
  }
  for (int i = 1; i <= n; i++)
    if (!pre[i]) Tarjan(i);
  for (int i = 1; i <= scc_cnt; i++) {
    fa[i] = i;
    if (size[i] > 1) vis[i] = 1;
  }
  ReBuild();
  for (int i = 1; i <= scc_cnt; i++)
    if (fa[i] == i)
      if (vis[i])
        ans += size[i];
      else
        ans += size[i] - 1;
  printf("%d\n", ans);
}
