#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e9 + 10;
const long long N = 1e5 + 10;
vector<long long> g[N], rg[N], gg[N], order;
long long c[N], x[N];
bool used[N], kek;
void dfs(long long v) {
  used[v] = true;
  for (auto u : g[v]) {
    if (!used[u]) {
      dfs(u);
    }
  }
  order.push_back(v);
}
void dfs2(long long v, long long color) {
  c[v] = color;
  x[color]++;
  for (auto u : rg[v]) {
    if (!c[u]) {
      dfs2(u, color);
    }
  }
}
void go(long long v) {
  used[v] = true;
  if (x[v] > 1) {
    kek = true;
  }
  for (auto u : gg[v]) {
    if (!used[u]) {
      go(u);
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(0);
  long long n, m;
  cin >> n >> m;
  vector<pair<long long, long long>> edge;
  for (long long i = 0; i < m; i++) {
    long long u, v;
    cin >> u >> v;
    g[u].push_back(v);
    rg[v].push_back(u);
    edge.push_back({u, v});
  }
  for (long long i = 1; i <= n; i++) {
    if (!used[i]) {
      dfs(i);
    }
  }
  reverse((order).begin(), (order).end());
  long long cnt = 0;
  for (long long v : order) {
    if (!c[v]) {
      dfs2(v, ++cnt);
    }
  }
  long long ans = 0;
  for (auto it : edge) {
    if (c[it.first] != c[it.second]) {
      gg[c[it.first]].push_back(c[it.second]);
      gg[c[it.second]].push_back(c[it.first]);
    }
  }
  for (long long i = 1; i <= cnt; i++) {
    sort((gg[i]).begin(), (gg[i]).end());
    gg[i].resize(unique((gg[i]).begin(), (gg[i]).end()) - gg[i].begin());
    used[i] = false;
  }
  long long comps = 0;
  for (long long i = 1; i <= cnt; i++) {
    if (!used[i]) {
      kek = false;
      go(i);
      comps++;
      if (kek) {
        ans++;
      }
    }
  }
  ans += n - comps;
  cout << ans << '\n';
}
