#include <bits/stdc++.h>
using namespace std;
const int base = 1000 * 1000 * 1000;
const int mod = 1000 * 1000 * 1000 + 7;
const int MAX = 300005;
int n, m;
vector<int> pushed;
vector<vector<int> > g(MAX);
vector<vector<int> > gr(MAX);
bool reachable(int u, int v) {
  return binary_search(g[u].begin(), g[u].end(), v);
}
int len[MAX];
int nxt[MAX];
int visited[MAX];
vector<int> topo;
int cnt = 0;
void dfs(int u) {
  visited[u] = 1;
  for (auto v : g[u])
    if (!visited[v]) dfs(v);
  topo.push_back(u);
}
void dfsR(int u, bool push = 0) {
  if (push) {
    pushed.push_back(u);
  }
  visited[u] = 1;
  cnt++;
  for (auto v : gr[u]) {
    if (!visited[v]) {
      dfsR(v, push);
    }
  }
}
void dfsL(int u, bool push = 0) {
  if (push) {
    pushed.push_back(u);
  }
  visited[u] = 1;
  cnt++;
  for (auto v : g[u]) {
    if (!visited[v]) dfsL(v, push);
  }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    u--;
    v--;
    g[u].push_back(v);
    gr[v].push_back(u);
  }
  for (int i = 0; i < n; i++) sort(g[i].begin(), g[i].end());
  for (int i = 0; i < n; i++) {
    if (!visited[i]) dfs(i);
  }
  int start = -1;
  for (auto u : topo) {
    len[u] = 1;
    nxt[u] = u;
    for (auto v : g[u]) {
      if (len[v] + 1 > len[u]) {
        len[u] = len[v] + 1;
        nxt[u] = v;
      }
    }
    if (start == -1 || len[u] > len[start]) start = u;
  }
  vector<int> path;
  while (nxt[start] != start) {
    path.push_back(start);
    start = nxt[start];
  }
  path.push_back(start);
  vector<int> out(n);
  vector<int> in(n);
  memset(visited, 0, sizeof visited);
  for (auto u : path) {
    dfsR(u);
    in[u] = cnt;
  }
  cnt = 0;
  memset(visited, 0, sizeof visited);
  reverse(path.begin(), path.end());
  int ans = 0;
  for (auto u : path) {
    dfsL(u);
    out[u] = cnt;
    ans += (in[u] + out[u]) >= n;
  }
  cnt = 0;
  reverse(path.begin(), path.end());
  memset(visited, 0, sizeof visited);
  for (int i = 0; i < (int)path.size() - 2; i++) {
    int u1 = path[i];
    dfsR(u1);
    int u2 = path[i + 2];
    int u3 = path[i + 1];
    int v = -1;
    for (auto w : g[u1]) {
      if (w == u3) continue;
      if (reachable(w, u2) && v != -1) {
        v = -2;
      }
      if (reachable(w, u2) && v == -1) {
        v = w;
      }
    }
    if (v >= 0) {
      dfsR(v, 1);
      in[v] = cnt;
      cnt -= pushed.size();
      for (auto v : pushed) visited[v] = 0;
      pushed.clear();
    }
  }
  cnt = 0;
  memset(visited, 0, sizeof visited);
  for (int i = (int)path.size() - 3; i >= 0; i--) {
    int u1 = path[i];
    int u3 = path[i + 1];
    int u2 = path[i + 2];
    dfsL(u2);
    int v = -1;
    for (auto w : g[u1]) {
      if (w == u3) continue;
      if (reachable(w, u2) && v != -1) {
        v = -2;
      }
      if (reachable(w, u2) && v == -1) {
        v = w;
      }
    }
    if (v >= 0) {
      dfsL(v, 1);
      out[v] = cnt;
      assert((in[v] + out[v]) <= n);
      ans += (in[v] + out[v]) == n;
      cnt -= pushed.size();
      for (auto v : pushed) visited[v] = 0;
      pushed.clear();
    }
  }
  for (int v = 0; v < n; v++) {
    if (in[v] == 0 && out[v] == 0) {
      bool good = false;
      for (auto u : g[v]) {
        if (out[u] >= n - 2) good = true;
      }
      for (auto u : gr[v]) {
        if (in[u] >= n - 2) good = true;
      }
      if (good) ans++;
    }
  }
  cout << ans;
  return 0;
}
