#include <bits/stdc++.h>
using namespace std;
class graf {
 public:
  graf(int n) {
    this->n = n;
    vecini.resize(n + 1);
    viz.resize(n + 1);
  }
  void AddEdge(int x, int y) {
    vecini[x].push_back(y);
    vecini[y].push_back(x);
  }
  void GetComp(vector<vector<int> > &ret) {
    fill(viz.begin(), viz.end(), false);
    for (int i = 1; i <= n; ++i) {
      if (viz[i] == false) {
        vector<int> comp;
        DFS(comp, i);
        ret.push_back(comp);
      }
    }
  }
  void DFS(vector<int> &comp, int current) {
    viz[current] = true;
    comp.push_back(current);
    for (auto v : vecini[current])
      if (!viz[v]) DFS(comp, v);
  }

 private:
  int n;
  vector<vector<int> > vecini;
  vector<bool> viz;
};
bool Ciclu(vector<bool> &viz, vector<bool> &inStack,
           const vector<vector<int> > &vecini, int current) {
  if (inStack[current]) return true;
  if (viz[current]) return false;
  inStack[current] = true;
  viz[current] = true;
  for (auto v : vecini[current]) {
    if (Ciclu(viz, inStack, vecini, v)) return true;
  }
  inStack[current] = false;
  return false;
}
int rez(int n, const vector<int> &comp, const vector<vector<int> > &vecini,
        const vector<int> &grad) {
  vector<bool> inStack(n + 1, false);
  vector<bool> viz(n + 1, false);
  bool ok = false;
  for (auto v : comp) {
    if (viz[v]) continue;
    if (Ciclu(viz, inStack, vecini, v)) return comp.size();
    ok = true;
  }
  if (ok) return comp.size() - 1;
  return comp.size();
}
int main() {
  int n, m;
  cin >> n >> m;
  vector<vector<int> > vecini(n + 1);
  vector<int> grad(n + 1, 0);
  graf gr(n);
  int a, b;
  for (int i = 1; i <= m; ++i) {
    cin >> a >> b;
    vecini[a].push_back(b);
    grad[b]++;
    gr.AddEdge(a, b);
  }
  vector<vector<int> > comp;
  gr.GetComp(comp);
  int rasp = 0;
  for (const auto &c : comp) rasp += rez(n, c, vecini, grad);
  cout << rasp;
  return 0;
}
