#include <bits/stdc++.h>
using namespace std;
vector<vector<int>> edge;
int n, m;
int parent[100000];
int size[100000];
int visited[100000];
int finished[100000];
int has_loop[100000];
int find_root(int v) {
  if (parent[v] == -1) {
    return v;
  }
  return parent[v] = find_root(parent[v]);
}
void merge(int u, int v) {
  u = find_root(u), v = find_root(v);
  if (u == v) {
    return;
  }
  if (size[u] < size[v]) {
    merge(v, u);
    return;
  }
  parent[v] = u;
  size[u] += size[v];
}
void dfs(int here) {
  visited[here] = true;
  for (int there : edge[here]) {
    if (finished[there]) {
      continue;
    } else if (visited[there]) {
      has_loop[find_root(here)] = 1;
    } else {
      dfs(there);
    }
  }
  finished[here] = true;
}
void loop_check() {
  for (int i = 0; i < n; i++) {
    if (!visited[i]) {
      dfs(i);
    }
  }
}
int main() {
  cin >> n >> m;
  edge = vector<vector<int>>(n, vector<int>());
  for (int i = 0; i < n; i++) {
    parent[i] = -1;
    size[i] = 1;
  }
  for (int i = 0; i < m; i++) {
    int from, to;
    cin >> from >> to;
    edge[from - 1].push_back(to - 1);
    merge(from - 1, to - 1);
  }
  vector<int> wcc_list;
  for (int i = 0; i < n; i++) {
    if (find_root(i) == i) {
      wcc_list.push_back(i);
    }
  }
  loop_check();
  int ans = 0;
  for (int wcc : wcc_list) {
    ans += size[wcc] - 1;
    if (has_loop[wcc]) {
      ans++;
    }
  }
  cout << ans << endl;
}
