#include <bits/stdc++.h>
using namespace std;
long long int mod = 1e9 + 7;
const int maxn = 1e5 + 20;
int n, m;
int ans;
vector<int> adj[2][maxn];
vector<int> comp[maxn];
vector<int> nadj[maxn];
int mark[2][maxn], seen[maxn];
int color[maxn];
int sccsz[maxn];
int c = 2;
int cnt;
stack<int> tpo;
void topol_dfs(int v, int det) {
  mark[det][v] = 1;
  for (int u : adj[det][v])
    if (!mark[det][u]) topol_dfs(u, det);
  if (!det) tpo.push(v);
  if (det && (adj[0][v].size() || adj[1][v].size())) {
    comp[c].push_back(v);
    color[v] = c;
  }
}
void dfs(int v) {
  seen[v] = 1;
  cnt++;
  for (int u : nadj[v]) {
    if (!seen[u]) {
      dfs(u);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    adj[0][u].push_back(v);
    adj[1][v].push_back(u);
  }
  for (int i = 1; i <= n; i++) {
    if (!mark[0][i]) topol_dfs(i, 0);
  }
  while (!tpo.empty()) {
    int v = tpo.top();
    tpo.pop();
    if (!mark[1][v]) {
      topol_dfs(v, 1);
      if (comp[c].size() == 1) c++;
      if (comp[c].size() > 1) {
        for (int i : comp[c]) {
          color[i] = 1;
        }
        comp[c].clear();
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    if (color[i] == 0) continue;
    int v = color[i];
    sccsz[v]++;
    for (int j : adj[0][i]) {
      int u = color[j];
      if (u != v) {
        nadj[v].push_back(u);
        nadj[u].push_back(v);
      }
    }
  }
  for (int i = 1; i < c; i++) {
    cnt = 0;
    if (!seen[i]) {
      dfs(i);
      ans += cnt - 1;
    }
  }
  cout << ans + sccsz[1];
  return 0;
}
