#include <bits/stdc++.h>
using namespace std;
const int mxn = 1e5 + 10;
vector<int> adj[mxn];
vector<int> tps[mxn];
vector<int> comp[mxn];
int sz[mxn] = {};
int initsz[mxn] = {};
int vis[mxn] = {};
int comind[mxn];
int mark = 0;
stack<int> st;
int n;
int par[mxn];
int cyc[mxn] = {};
void dfs(int u) {
  vis[u] = 1;
  for (int i : adj[u])
    if (!vis[i]) dfs(i);
  st.push(u);
}
void dfs2(int u, int m) {
  comp[m].push_back(u);
  comind[u] = m;
  sz[m]++;
  initsz[m]++;
  vis[u] = 1;
  for (int i : tps[u])
    if (!vis[i]) dfs2(i, m);
}
void scc() {
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs(i);
  for (int i = 0; i <= n; i++) vis[i] = 0;
  while (!st.empty()) {
    int u = st.top();
    st.pop();
    if (!vis[u]) {
      dfs2(u, mark++);
    }
  }
}
int findrep(int u) {
  if (par[u] == u) return u;
  return par[u] = findrep(par[u]);
}
void unionset(int u, int v) {
  int _u = findrep(u);
  int _v = findrep(v);
  par[_u] = _v;
  sz[_v] += sz[_u];
  cyc[_v] |= cyc[_u];
}
int main() {
  int m;
  cin >> n >> m;
  for (int i = 0; i <= n; i++) par[i] = i;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    tps[v].push_back(u);
  }
  scc();
  int rs = 0;
  for (int i = 0; i < mark; i++)
    if (sz[i] > 1) cyc[i] = 1;
  for (int i = 1; i <= n; i++) {
    for (int u : adj[i]) {
      if (comind[i] != comind[u] && findrep(comind[i]) != findrep(comind[u])) {
        unionset(comind[u], comind[i]);
        if (initsz[comind[u]] > 1) cyc[findrep(comind[u])] = 1;
      }
    }
  }
  for (int i = 0; i < mark; i++)
    if (par[i] == i) rs += sz[i] - (1 - cyc[i]);
  cout << rs << endl;
  return 0;
}
