#include <bits/stdc++.h>
using namespace std;
bool visited[100007] = {false};
bool mark[100007] = {false};
stack<long long> st1;
set<long long> s;
bool isCycle(long long v, vector<vector<long long> > &adj) {
  mark[v] = true;
  s.insert(v);
  bool my = false;
  for (typeof(adj[v].begin()) it = adj[v].begin(); it != adj[v].end(); it++) {
    if (!mark[*it]) {
      my |= isCycle(*it, adj);
    } else {
      if (s.find(*it) != s.end()) return true;
    }
  }
  s.erase(v);
  if (my)
    return true;
  else
    return false;
}
void dfs(long long v, vector<vector<long long> > &adjG) {
  visited[v] = true;
  st1.push(v);
  for (typeof(adjG[v].begin()) it = adjG[v].begin(); it != adjG[v].end();
       it++) {
    if (!visited[*it]) dfs(*it, adjG);
  }
}
int main() {
  long long n, m, i, j, p, q, c, sum;
  cin >> n >> m;
  vector<vector<long long> > adj(n, vector<long long>(0));
  vector<vector<long long> > adjG(n, vector<long long>(0));
  for (i = 0; i < m; i++) {
    cin >> p >> q;
    p--;
    q--;
    adj[p].push_back(q);
    adjG[p].push_back(q);
    adjG[q].push_back(p);
  }
  sum = 0;
  bool tog = false;
  for (i = 0; i < n; i++) {
    if (!visited[i]) {
      dfs(i, adjG);
      c = st1.size();
      while (!st1.empty()) {
        m = st1.top();
        st1.pop();
        if (!mark[m]) {
          tog = isCycle(m, adj);
          if (tog) break;
        }
      }
      s.clear();
      if (tog)
        sum += c;
      else
        sum += c - 1;
      while (!st1.empty()) st1.pop();
      tog = false;
    }
  }
  cout << sum << endl;
  return 0;
}
