#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
struct dsu_ele {
  int par, rankt;
  bool cir;
} dsu[200009];
vector<int> st, g[200009];
bool ok[200009], done[200009];
int n, m, u, v, i, j, low[200009], disc[200009], nodeval[200009], scc, res, cnt,
    nodecnt[200009];
int getpar(int x) {
  if (x != dsu[x].par) {
    dsu[x].par = getpar(dsu[x].par);
  }
  return dsu[x].par;
}
void Union(int x, int y) {
  x = getpar(x);
  y = getpar(y);
  if (x == y) {
    return;
  }
  if (!dsu[x].cir || !dsu[y].cir) {
    res++;
  }
  dsu[x].par = dsu[y].par;
  dsu[y].rankt += dsu[x].rankt;
  dsu[y].cir |= dsu[x].cir;
}
void dfs(int x) {
  ok[x] = true;
  cnt++;
  low[x] = cnt;
  disc[x] = cnt;
  st.push_back(x);
  for (int ii = 0; ii < g[x].size(); ii++) {
    if (!ok[g[x][ii]]) {
      dfs(g[x][ii]);
      low[x] = min(low[x], low[g[x][ii]]);
    } else if (!done[g[x][ii]]) {
      low[x] = min(low[x], disc[g[x][ii]]);
    }
  }
  if (low[x] == disc[x]) {
    scc++;
    while (st.back() != x) {
      nodecnt[scc]++;
      nodeval[st.back()] = scc;
      st.pop_back();
    }
    nodecnt[scc]++;
    nodeval[st.back()] = scc;
    st.pop_back();
  }
  done[x] = true;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (i = 1; i <= m; i++) {
    cin >> u >> v;
    g[u].push_back(v);
  }
  for (i = 1; i <= n; i++) {
    if (!ok[i]) {
      dfs(i);
    }
  }
  for (i = 1; i <= scc; i++) {
    dsu[i] = {i, 1, nodecnt[i] > 1};
    if (nodecnt[i] > 1) {
      res += nodecnt[i];
    }
  }
  for (i = 1; i <= n; i++) {
    for (j = 0; j < g[i].size(); j++) {
      Union(nodeval[i], nodeval[g[i][j]]);
    }
  }
  cout << res << '\n';
}
