#include <bits/stdc++.h>
using namespace std;
const int N = 100000;
int n, m, t;
vector<int> adj[N], radj[N], component;
vector<pair<int, int> > finishing;
bool undir_visit[N], visit[N], strongly_connected;
void undir_dfs(int u) {
  undir_visit[u] = true;
  component.push_back(u);
  for (const int &v : adj[u]) {
    if (!undir_visit[v]) {
      undir_dfs(v);
    }
  }
  for (const int &v : radj[u]) {
    if (!undir_visit[v]) {
      undir_dfs(v);
    }
  }
}
void dfs(int u) {
  visit[u] = true;
  for (const int &v : adj[u]) {
    if (!visit[v]) {
      dfs(v);
    }
  }
  finishing.push_back({t++, u});
}
void rdfs(int u) {
  visit[u] = true;
  for (const int &v : radj[u]) {
    if (!visit[v]) {
      strongly_connected = true;
      rdfs(v);
    }
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n >> m;
  for (int i = 0; i < m; ++i) {
    int u, v;
    cin >> u >> v;
    u--, v--;
    adj[u].push_back(v);
    radj[v].push_back(u);
  }
  int sz = 0;
  for (int i = 0; i < n; ++i) {
    if (!undir_visit[i]) {
      component.clear();
      strongly_connected = false;
      undir_dfs(i);
      finishing.clear();
      for (int j = 0; j < component.size(); ++j) {
        if (!visit[component[j]]) {
          dfs(component[j]);
        }
      }
      sort(finishing.begin(), finishing.end());
      reverse(finishing.begin(), finishing.end());
      memset(visit, false, sizeof(visit));
      for (const pair<int, int> &p : finishing) {
        if (!visit[p.second]) {
          rdfs(p.second);
        }
      }
      if (strongly_connected) {
        if (component.size() > 1) {
          sz += component.size();
        }
      } else {
        sz += component.size() - 1;
      }
    }
  }
  cout << sz << "\n";
}
