#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
vector<int> v[maxn];
vector<int> v_[maxn];
vector<int> tp;
bool flag[maxn];
int mark[maxn], con[maxn];
inline void dfs1(int x) {
  flag[x] = true;
  for (int i = 0; i < v[x].size(); i++)
    if (flag[v[x][i]] == 0) dfs1(v[x][i]);
  tp.push_back(x);
}
inline int dfs2(int x, int col) {
  mark[x] = col;
  con[col]++;
  int ret = 1;
  for (int i = 0; i < v_[x].size(); i++)
    if (mark[v_[x][i]] == 0) ret += dfs2(v_[x][i], col);
  return ret;
}
vector<int> V[maxn];
int par[maxn];
inline int dfs3(int x) {
  flag[x] = true;
  int ret = (con[x] != 1), E = 0;
  for (int i = 0; i < V[x].size(); i++)
    if (flag[V[x][i]] == 0) {
      par[V[x][i]] = x;
      ret |= dfs3(V[x][i]);
    }
  return ret;
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 1; i <= m; i++) {
    int x, y;
    cin >> x >> y;
    v[x].push_back(y);
    v_[y].push_back(x);
  }
  for (int i = 1; i <= n; i++)
    if (flag[i] == 0) dfs1(i);
  int cnt = 0, ans = 0;
  for (int i = tp.size() - 1; i >= 0; i--)
    if (mark[tp[i]] == 0) {
      int t = dfs2(tp[i], ++cnt);
      ans += t;
    }
  for (int i = 1; i <= n; i++)
    for (int j = 0; j < v[i].size(); j++) {
      int x = i, y = v[i][j];
      x = mark[x], y = mark[y];
      V[x].push_back(y);
      V[y].push_back(x);
    }
  memset(flag, false, sizeof flag);
  for (int i = 1; i <= cnt; i++)
    if (flag[i] == 0) {
      if (dfs3(i) == true) ans++;
      ans--;
    }
  cout << ans << "\n";
  return 0;
}
