#include <bits/stdc++.h>
using namespace std;
template <class T>
void pr(const string& name, T t) {
  cerr << name << ": " << t << endl;
}
template <typename T, typename... Types>
void pr(const string& names, T t, Types... rest) {
  auto comma_pos = names.find(',');
  cerr << names.substr(0, comma_pos) << ": " << t << ", ";
  auto next_name_pos = names.find_first_not_of(" \t\n", comma_pos + 1);
  pr(string(names, next_name_pos), rest...);
}
template <class T, class U>
ostream& operator<<(ostream& o, const pair<T, U>& v) {
  return o << "(" << v.first << ", " << v.second << ")";
}
template <class T>
ostream& operator<<(ostream& o, const vector<T>& v) {
  o << "{";
  for (int i = 0; i < (int)((int)((v).size())); ++i)
    o << (i ? ", " : "") << v[i];
  return o << "}";
}
const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
const int MAX_N = 2e5 + 10;
vector<int> G[MAX_N];
vector<int> rG[MAX_N];
int cmp[MAX_N];
bool vis[MAX_N];
int V;
vector<int> vs;
void dfs(int v) {
  vis[v] = true;
  for (auto e : G[v])
    if (!vis[e]) dfs(e);
  vs.push_back(v);
}
void rdfs(int v, int k) {
  vis[v] = true;
  cmp[v] = k;
  for (auto e : rG[v])
    if (!vis[e]) rdfs(e, k);
}
int scc() {
  vs.clear();
  memset(vis, 0, sizeof(vis));
  for (int i = 0; i < (int)(V); ++i)
    if (!vis[i]) dfs(i);
  memset(vis, 0, sizeof(vis));
  int k = 0;
  reverse((vs).begin(), (vs).end());
  for (auto e : vs)
    if (!vis[e]) rdfs(e, k++);
  return k;
}
int un[MAX_N];
int find(int x) {
  if (un[x] == x) return x;
  return un[x] = find(un[x]);
}
void unit(int a, int b) { un[find(a)] = find(b); }
int main(int argc, char* argv[]) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  memset(un, -1, sizeof(un));
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < (int)(n); ++i) un[i] = i;
  for (int i = 0; i < (int)(m); ++i) {
    int a, b;
    cin >> a >> b;
    --a, --b;
    G[a].push_back(b);
    rG[b].push_back(a);
    unit(a, b);
  }
  V = n;
  scc();
  map<int, set<int> > app;
  for (int i = 0; i < (int)(n); ++i) app[find(i)].insert(i);
  int ans = 0;
  for (auto& e : app) {
    if ((int)((e.second).size()) == 1) continue;
    set<int> cnum;
    for (auto v : e.second) cnum.insert(cmp[v]);
    if ((int)((cnum).size()) != (int)((e.second).size()))
      ans += (int)((e.second).size());
    else
      ans += (int)((e.second).size()) - 1;
  }
  cout << ans << '\n';
}
