#include <bits/stdc++.h>
int dx[] = {-1, 0, 0, 1, -1, -1, 1, 1};
int dy[] = {0, -1, 1, 0, -1, 1, -1, 1};
using namespace std;
int n, m, a, b, cnt;
vector<int> graph[100009];
vector<int> revgraph[100009];
int graphcnt[100009];
int vis[100009];
vector<int> conncomp[100009];
void dfs(int node) {
  vis[node] = 1;
  conncomp[cnt].push_back(node);
  for (int i = 0; i < graph[node].size(); i++)
    if (!vis[graph[node][i]]) dfs(graph[node][i]);
  for (int i = 0; i < revgraph[node].size(); i++)
    if (!vis[revgraph[node][i]]) dfs(revgraph[node][i]);
  return;
}
bool toposort(int node) {
  vis[node] = 0;
  for (int i = 0; i < graph[node].size(); i++) {
    if (vis[graph[node][i]] == 0) return true;
    if (vis[graph[node][i]] == -1 && toposort(graph[node][i])) return true;
  }
  vis[node] = 1;
  return false;
}
int main() {
  n = ({
    int t;
    scanf("%d", &t);
    t;
  }),
  m = ({
    int t;
    scanf("%d", &t);
    t;
  });
  for (int i = 0; i < m; i++) {
    a = ({
      int t;
      scanf("%d", &t);
      t;
    }),
    b = ({
      int t;
      scanf("%d", &t);
      t;
    });
    graph[a].push_back(b);
    revgraph[b].push_back(a);
  }
  cnt = 0;
  for (int i = 1; i <= n; i++)
    if (!vis[i]) {
      cnt++;
      dfs(i);
    }
  int ans = 0;
  memset(vis, -1, sizeof vis);
  for (int i = 1; i <= cnt; i++) {
    bool cycle = false;
    for (int j = 0; j < conncomp[i].size(); j++) {
      if (vis[conncomp[i][j]] == -1) cycle |= toposort(conncomp[i][j]);
    }
    ans += conncomp[i].size() - 1 + cycle;
  }
  cout << ans << "\n";
  return 0;
}
