#include <bits/stdc++.h>
using namespace std;
int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
int n, m, scc, ind;
int dfn[100005], low[100005], instack[100005];
int belong[100005];
int sum[100005];
vector<int> v[100005];
stack<int> st;
void tarjan(int x) {
  dfn[x] = low[x] = ++ind;
  instack[x] = 1;
  st.push(x);
  for (int i = 0; i < v[x].size(); i++) {
    int V = v[x][i];
    if (!dfn[V]) {
      tarjan(V);
      low[x] = min(low[x], low[V]);
    } else if (instack[V])
      low[x] = min(low[x], dfn[V]);
  }
  if (dfn[x] == low[x]) {
    static int now;
    scc++;
    while (now != x) {
      now = st.top();
      st.pop();
      instack[now] = 0;
      belong[now] = scc;
      sum[scc]++;
    }
  }
}
int father[100005], flag[100005];
int findf(int x) { return father[x] == x ? x : father[x] = findf(father[x]); }
void mergef(int x, int y) {
  father[x] = y;
  sum[y] += sum[x];
  flag[y] |= flag[x];
}
int main() {
  n = read(), m = read();
  for (int i = 1; i <= m; i++) {
    static int x, y;
    x = read(), y = read();
    v[x].push_back(y);
  }
  for (int i = 1; i <= n; i++)
    if (!dfn[i]) tarjan(i);
  int ans = 0;
  for (int i = 1; i <= scc; i++)
    if (sum[i] > 1) flag[i] = 1;
  for (int i = 1; i <= scc; i++) father[i] = i;
  for (int i = 1; i <= n; i++)
    for (int j = 0; j < v[i].size(); j++) {
      int V = v[i][j];
      if (belong[i] != belong[V]) {
        static int x, y, fx, fy;
        x = belong[i], y = belong[V];
        fx = findf(x), fy = findf(y);
        if (fx != fy) mergef(fx, fy);
      }
    }
  for (int i = 1; i <= scc; i++)
    if (findf(i) == i) {
      ans += sum[i] - 1;
      if (flag[i]) ans++;
    }
  printf("%d\n", ans);
  return 0;
}
