#include <bits/stdc++.h>
using namespace std;
const int MX = 200005;
long long N, M;
bool vis[100005], instack[100005];
vector<int> G[100005];
int par[100005], size[100005];
bool cycle[100005];
bool ok;
int findF(int x) { return par[x] == x ? x : findF(par[x]); }
void unionF(int x, int y) {
  x = findF(x), y = findF(y);
  if (x == y) return;
  if (size[x] < size[y]) swap(x, y);
  size[x] += size[y];
  par[y] = x;
}
void dfs(int u) {
  if (instack[u]) ok = 1;
  if (vis[u]) return;
  vis[u] = 1;
  instack[u] = 1;
  for (int i = 0; i < (int)G[u].size(); i++) {
    dfs(G[u][i]);
  }
  instack[u] = 0;
}
void go_solver() {
  ios::sync_with_stdio(false);
  cin >> N >> M;
  for (int i = 1; i <= N; i++) par[i] = i, size[i] = 1;
  for (int i = 0; i < M; i++) {
    int x, y;
    cin >> x >> y;
    G[x].push_back(y);
    unionF(x, y);
  }
  for (int i = 1; i <= N; i++) {
    ok = 0;
    if (!vis[i]) dfs(i), cycle[findF(i)] |= ok;
  }
  memset(vis, 0, sizeof vis);
  int ans = 0;
  for (int i = 1; i <= N; i++) {
    int x = findF(i);
    if (vis[x]) continue;
    vis[x] = 1;
    ans += size[x] - 1 + cycle[x];
  }
  cout << ans << "\n";
}
int main() {
  go_solver();
  return 0;
}
