#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T gi() {
  T f = 1, x = 0;
  char c = getchar();
  while (c < '0' || c > '9') {
    if (c == '-') f = -1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  return f * x;
}
const int INF = 0x3f3f3f3f, N = 100003, M = N << 1;
int n, m;
int tot, head[N], ver[M], nxt[M];
int tim, dfn[N], low[N], stk[N], tp, scc_cnt, id[N], sz[N];
int fa[N];
bool in_stk[N];
vector<int> v[N];
int getf(int u) { return fa[u] == u ? u : fa[u] = getf(fa[u]); }
inline void add(int u, int v) {
  ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
}
void Tarjan(int u) {
  dfn[u] = low[u] = ++tim, stk[++tp] = u, in_stk[u] = true;
  for (int i = head[u]; i; i = nxt[i]) {
    int v = ver[i];
    if (!dfn[v]) {
      Tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (in_stk[v])
      low[u] = min(low[u], dfn[v]);
  }
  if (low[u] == dfn[u]) {
    int y = -1;
    ++scc_cnt;
    do {
      y = stk[tp--];
      in_stk[y] = false;
      id[y] = scc_cnt;
      ++sz[scc_cnt];
    } while (y != u);
  }
}
int main() {
  n = gi<int>(), m = gi<int>();
  for (int i = 1; i <= n; i += 1) fa[i] = i;
  for (int i = 1; i <= m; i += 1) {
    int u = gi<int>(), v = gi<int>();
    fa[getf(u)] = getf(v);
    add(u, v);
  }
  int cnt = 0;
  for (int i = 1; i <= n; i += 1)
    if (!dfn[i]) Tarjan(i), ++cnt;
  for (int i = 1; i <= n; i += 1) v[getf(i)].push_back(i);
  set<int> s;
  for (int i = 1; i <= n; i += 1) s.insert(getf(i));
  int ans = 0;
  for (auto x : s) {
    set<int> w;
    int res = 0;
    for (auto y : v[x]) w.insert(id[y]);
    int qwq = 0;
    for (auto y : w) {
      if (sz[y] > 1) res += sz[y];
      ++qwq;
    }
    res = res + qwq - 1;
    res = min(res, (int)v[x].size());
    ans += res;
  }
  printf("%d\n", ans);
  return 0;
}
