#include <bits/stdc++.h>
using namespace std;
const int INF = (-1u) / 2;
const long long int INF2 = (-1ull) / 2;
int a, b, i, d, us[1011000], j, k, n, m, timer = 0, l, r, x, y, par[200020],
                                         siz[200010], us2[100020];
int c[1011000], cnt = 0, fl = 0, a2, a3 = -1000000, ans = 0;
vector<int> g[530010], gr[530010], vec;
int find_par(int v) {
  if (par[v] == v) return v;
  return par[v] = find_par(par[v]);
}
void make_set(int a, int b) {
  a = find_par(a);
  b = find_par(b);
  if (a == b) return;
  if (siz[a] < siz[b]) swap(a, b);
  par[b] = a;
  siz[a] += siz[b];
  return;
}
void dfs(int v) {
  us[v] = 1;
  for (int i = 0; i < g[v].size(); i++) {
    if (!us[g[v][i]]) dfs(g[v][i]);
  }
  vec.push_back(v);
}
void dfs2(int v) {
  us[v] = 2;
  c[cnt] = v;
  cnt++;
  for (int i = 0; i < gr[v].size(); i++) {
    if (us[gr[v][i]] != 2) dfs2(gr[v][i]);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (i = 1; i <= n; i++) {
    par[i] = i;
    siz[i] = 1;
  }
  for (i = 0; i < m; i++) {
    scanf("%d%d", &a, &b);
    g[a].push_back(b);
    gr[b].push_back(a);
    make_set(a, b);
  }
  for (i = 1; i <= n; i++) {
    if (!us[i]) dfs(i);
  }
  for (i = n - 1; i >= 0; i--) {
    if (us[vec[i]] != 2) {
      cnt = 0;
      dfs2(vec[i]);
      if (cnt > 1 && us2[find_par(c[0])] != 1) ans++, us2[find_par(c[0])] = 1;
    }
  }
  cnt = 0;
  for (i = 1; i <= n; i++) {
    a = find_par(i);
    if (us[a] != 3) {
      cnt += siz[a] - 1;
    }
    us[a] = 3;
  }
  cout << cnt + ans << endl;
  return 0;
}
