#include <bits/stdc++.h>
using namespace std;
int ans, n, m, x, y, i, cur_col, color[100100], v_col[100100], j, v, qb, qe,
    cur, mn, num, ans2, num2;
vector<int> edge[100100], back[100100], order, n_edge[100100], n_edge_b[100100];
bool used[100100], used2[100100];
void dfs1(int v) {
  used[v] = true;
  for (int i = 0; i < edge[v].size(); i++)
    if (!used[edge[v][i]]) dfs1(edge[v][i]);
  order.push_back(v);
  return;
}
void dfs2(int v) {
  color[v] = cur_col;
  v_col[cur_col]++;
  for (int i = 0; i < back[v].size(); i++)
    if (color[back[v][i]] == 0) dfs2(back[v][i]);
  return;
}
void dfs(int v) {
  used2[v] = true;
  num++;
  num += v_col[v];
  if (v_col[v] == 1) num--;
  num2 += v_col[v];
  for (int i = 0; i < n_edge[v].size(); i++) {
    if (!used2[n_edge[v][i]]) dfs(n_edge[v][i]);
  }
  for (int i = 0; i < n_edge_b[v].size(); i++) {
    if (!used2[n_edge_b[v][i]]) dfs(n_edge_b[v][i]);
  }
  return;
}
int main() {
  cin >> n >> m;
  while (m--) {
    cin >> x >> y;
    edge[x].push_back(y);
    back[y].push_back(x);
  }
  for (i = 1; i <= n; i++) used[i] = false;
  for (i = 1; i <= n; i++)
    if (!used[i]) {
      dfs1(i);
    }
  cur_col = 0;
  for (i = (int)order.size() - 1; i >= 0; i--) {
    if (color[order[i]] == 0) {
      cur_col++;
      dfs2(order[i]);
    }
  }
  ans = 0;
  ans2 = 0;
  for (i = 1; i <= n; i++) {
    for (j = 0; j < edge[i].size(); j++) {
      if (color[i] != color[edge[i][j]]) {
        n_edge[color[i]].push_back(color[edge[i][j]]);
        n_edge_b[color[edge[i][j]]].push_back(color[i]);
      }
    }
  }
  for (i = 1; i <= cur_col; i++) {
    num = 0;
    num2 = 0;
    if (!used2[i]) {
      dfs(i);
      ans += min(num - 1, num2);
    }
  }
  cout << ans << endl;
  return 0;
}
