#include <bits/stdc++.h>
using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define int                     long long int
#define ld                      long double
#define pb                      push_back
#define MOD                     1000000007
#define inf                     3e18
#define vi                      vector<int>
#define vld                     vector<ld>
#define pii                     pair<int,int>
#define mii                     map<int,int>
#define fi                      first
#define se                      second
#define fastIO                  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define db(...)                 __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) { cerr << " "<< name << " : " << arg1 <<'\n'; }
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
    const char* comma = strchr(names + 1, ',');
    cerr.write(names, comma - names) << " : " << arg1 << " | "; __f(comma + 1, args...);
}

typedef tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> pbds;
		//order_of_key (k) : Number of items strictly smaller than k .
		//find_by_order(k) : K-th element in a set (counting from zero) (returns an iterator)

void inp_out()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	freopen("debug.txt", "w", stderr);
	#endif
}

vi a;

void printNGE(vector < int > arr, int n) {
  stack < int > s;

  /* push the first element to stack */
  s.push(arr[0]);

  // iterate for rest of the elements
  for (int i = 1; i < n; i++) {

    if (s.empty()) {
      s.push(arr[i]);
      continue;
    }

    /* if stack is not empty, then
       pop an element from stack.
       If the popped element is smaller
       than next, then
    a) print the pair
    b) keep popping while elements are
    smaller and stack is not empty */
    while (s.empty() == false && s.top() < arr[i])
    {
    	a[s.top()] = arr[i];
     // 	db(s.top(), arr[i]);
    //      cout << s.top() << " --> " << arr[i] << endl;
        s.pop();
    }

    /* push next to stack so that we can find
    next greater for it */
    s.push(arr[i]);
  }

  /* After iterating over the loop, the remaining
  elements in stack do not have the next greater
  element, so print -1 for them */
  while (s.empty() == false) {
  	a[s.top()] =  - 1;
   //   cout << s.top() << " --> " << -1 << endl;
    s.pop();
  }
}

int32_t main()
{
	fastIO
	inp_out();
	int t;
	cin >> t;
	while(t-- )
	{
		int n;
		cin >> n;
		a = vi(n + 1);
		vector < int > vis(n + 1);
		vi v(n);
		for(int i = 0; i < n; ++ i)
		{
			cin >> v[i];
		}

		printNGE(v, n);

		int ans = 0;

		vis[1] = 1;
		int cnt = 1, x = 0, sz = 0;

		vi temp;
		for(int i = 1; i < n; ++ i)
		{
		 	if(vis[v[i]] == 0)
			{
				sz = 1;
				int val = v[i];
				vis[val] = 1;

				while(a[val] !=  - 1 && vis[a[val]] == 0)
				{
					++ sz;
					val = a[val];
					vis[val] = 1;
				}
				temp.pb(sz);
			}
		}

		a = temp;
		n = a.size();

		int leaves = 1;
		cnt = 0;
		int store = 0;

		int i = 0;
		for(int i = 0; i < n; ++ i)
		{
			store += a[i];
			++ cnt;
			if(cnt == leaves)
			{
				leaves = store;
				++ ans;
				store = 0;
				cnt = 0;
			}
		}

		cout << ans << '\n';

	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;

#define int                     long long int
#define ld                      long double
#define pb                      push_back
#define MOD                     1000000007
#define inf                     3e18
#define vi                      vector<int>
#define vld                     vector<ld>
#define pii                     pair<int,int>
#define mii                     map<int,int>
#define fi                      first
#define se                      second
#define fastIO                  ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define db(...)                 __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1) { cerr << " "<< name << " : " << arg1 <<'\n'; }
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args) {
    const char* comma = strchr(names + 1, ',');
    cerr.write(names, comma - names) << " : " << arg1 << " | "; __f(comma + 1, args...);
}

typedef tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> pbds;
		//order_of_key (k) : Number of items strictly smaller than k .
		//find_by_order(k) : K-th element in a set (counting from zero) (returns an iterator)

void inp_out()
{
	#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	freopen("debug.txt", "w", stderr);
	#endif
}

vi a;

void printNGE(vector < int > arr, int n) {
  stack < int > s;

  /* push the first element to stack */
  s.push(arr[0]);

  // iterate for rest of the elements
  for (int i = 1; i < n; i++) {

    if (s.empty()) {
      s.push(arr[i]);
      continue;
    }

    /* if stack is not empty, then
       pop an element from stack.
       If the popped element is smaller
       than next, then
    a) print the pair
    b) keep popping while elements are
    smaller and stack is not empty */
    while (s.empty() == false && s.top() < arr[i])
    {
    	a[s.top()] = arr[i];
     // 	db(s.top(), arr[i]);
    //      cout << s.top() << " --> " << arr[i] << endl;
        s.pop();
    }

    /* push next to stack so that we can find
    next greater for it */
    s.push(arr[i]);
  }

  /* After iterating over the loop, the remaining
  elements in stack do not have the next greater
  element, so print -1 for them */
  while (s.empty() == false) {
  	a[s.top()] =  - 1;
   //   cout << s.top() << " --> " << -1 << endl;
    s.pop();
  }
}

int32_t main()
{
	fastIO
	inp_out();
	int t;
	cin >> t;
	while(t-- )
	{
		int n;
		cin >> n;
		a = vi(n + 1);
		vector < int > vis(n + 1);
		vi v(n);
		for(int i = 0; i < n; ++ i)
		{
			cin >> v[i];
		}

		printNGE(v, n);

		int ans = 0;

		vis[1] = 1;
		int cnt = 1, x = 0, sz = 0;

		vi temp;
		for(int i = 1; i < n; ++ i)
		{
		 	if(vis[v[i]] == 0)
			{
				sz = 1;
				int val = v[i];
				vis[val] = 1;

				while(a[val] !=  - 1 && vis[a[val]] == 0)
				{
					++ sz;
					val = a[val];
					vis[val] = 1;
				}
				temp.pb(sz);
			}
		}

		a = temp;
		n = a.size();

		int leaves = 1;
		cnt = 0;
		int store = 0;

		for(int i = 0; i < n; ++ i)
		{
		 // 	db(i, leaves, a[i]);
			store += a[i];
			++ cnt;
			if(cnt == leaves)
			{
				leaves = store;
				++ ans;
				store = 0;
				cnt = 0;
			}
		}

		if(cnt > 0)
			++ ans;

		cout << ans << '\n';

	}
	return 0;
}


/***************************************** START OF TEMPLATE *********************************************/
#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#include<bits/stdc++.h>

using namespace std;

#define  SPEED          ios:: sync_with_stdio(0);cin.tie(0);cout.tie(0);cout<<fixed;cout<<setprecision(10);
#define  randomINIT     mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
#define  foo(i,a,n)     for(ll i = (a); i <= n; i++)
#define  frr(i,a,n)     for(ll i = (a); i >= n; i--)
#define  fo(i,n)        for(ll i = 0; i < n; i++)
#define  newl           cout<<"\n";
#define  f              first
#define  s              second
#define  pb             push_back
#define  mp             make_pair
#define  sym(s)         s="#"+s+"#";
#define  all(x)         (x).begin(),(x).end()
#define  alll(x, n)     x+1, x+n+1
#define  mset(x,val)    memset(x,val,sizeof(x))
#define  mset1d(a,n,v)  foo(i,0,n+5)a[i]=v;
#define  mset2d(a,n,m,v)foo(i,0,n+5)foo(j,0,m+5)a[i][j]=v;
#define  INP(a,n)       foo(i,1,n) cin>>a[i];
#define  deb1d(a,n)     foo(i,1,n)cout<<a[i]<<" ";newl;
#define  deb2d(a,n,m)   foo(i,1,n){foo(j,1,m){cout<<a[i][j]<<" ";}newl;}
#define  debm(a)        for(auto it: a)cout<<"{"<<it.f<<","<<it.s<<"}, ";newl;
#define  debp(a,n)      foo(i,1,n)cout<<"{"<<a[i].f<<","<<a[i].s<<"}, ";newl;
#define  debv(a)        for(auto it: a)cout<<it<<" ";newl;
#define  deb1(a)        cout<<a<<" ";newl;
#define  deb2(a,b)      cout<<a<<" "<<b<<" ";newl;
#define  deb3(a,b,c)    cout<<a<<" "<<b<<" "<<c<<" ";newl;
#define  deb4(a,b,c,d)  cout<<a<<" "<<b<<" "<<c<<" "<<d;newl;
#define  ll             long long
#define  ld             long double
#define  pll            pair<ll,ll>
#define  vll            vector<ll>
#define  vpll           vector<pll>

const ld   PI    =  3.14159265358979323846;
const ll   MOD   =  1e+9+7;
const ll   INF   =  LLONG_MAX;
const int  INFi  =  INT_MAX;
const ll   N     =  2e+5+8;

vll adj[N]; ll vis[N];
ll dx4[]={0,1,0,-1}, dy4[]={1,0,-1,0};

ll test_cases = 1; randomINIT;

/*********************************************************************************************************/
/***************************************** VARIABLE DECLARATIONS *****************************************/
ll n, m, u, v, cnt, ok;
stack<ll> s;
/***************************************** FUNCTION IMPLEMENTATIONS **************************************/
void ts(ll v, ll p){
    vis[v]=1;
    for(auto to: adj[v]){
        if(vis[to]==1) ok = 1;
        if(vis[to]==0) ts(to,v);
    }
    s.push(v);
    vis[v]=2;
}

void dfs(ll v, ll p){
    cnt++;
    vis[v]=1;
    for(auto to: adj[v]){
        if(vis[to]==1) ok = 1;
        if(vis[to]==0) dfs(to,v);
    }
    vis[v]=2;
}

/***************************************** START OF MAIN FUNCTION ****************************************/
void MAIN(ll tc){
    cin>>n>>m;
    for(ll i=1; i <= m; i++){
        cin>>u>>v;
        adj[u].pb(v);
    }

    mset1d(vis,n,0);
    for(ll i=1; i<=n; i++){
        if(vis[i] == 0) ts(i,0);
    }

    ll res = 0;
    mset1d(vis,n,0);
    while(s.size()){
        ll i =s.top(); s.pop();
        if(vis[i] == 0){
            cnt=ok=0;
            dfs(i,0);
            res+=cnt-1+ok;
        }
    }
    cout<<res;
}

int main(){
    SPEED;

    //cin>>test_cases;
    foo(i,1,test_cases){
    MAIN(i);
    }
}


/***************************************** START OF TEMPLATE *********************************************/
#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#include<bits/stdc++.h>

using namespace std;

#define  SPEED          ios:: sync_with_stdio(0);cin.tie(0);cout.tie(0);cout<<fixed;cout<<setprecision(10);
#define  randomINIT     mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
#define  foo(i,a,n)     for(ll i = (a); i <= n; i++)
#define  frr(i,a,n)     for(ll i = (a); i >= n; i--)
#define  fo(i,n)        for(ll i = 0; i < n; i++)
#define  newl           cout<<"\n";
#define  f              first
#define  s              second
#define  pb             push_back
#define  mp             make_pair
#define  sym(s)         s="#"+s+"#";
#define  all(x)         (x).begin(),(x).end()
#define  alll(x, n)     x+1, x+n+1
#define  mset(x,val)    memset(x,val,sizeof(x))
#define  mset1d(a,n,v)  foo(i,0,n+5)a[i]=v;
#define  mset2d(a,n,m,v)foo(i,0,n+5)foo(j,0,m+5)a[i][j]=v;
#define  INP(a,n)       foo(i,1,n) cin>>a[i];
#define  deb1d(a,n)     foo(i,1,n)cout<<a[i]<<" ";newl;
#define  deb2d(a,n,m)   foo(i,1,n){foo(j,1,m){cout<<a[i][j]<<" ";}newl;}
#define  debm(a)        for(auto it: a)cout<<"{"<<it.f<<","<<it.s<<"}, ";newl;
#define  debp(a,n)      foo(i,1,n)cout<<"{"<<a[i].f<<","<<a[i].s<<"}, ";newl;
#define  debv(a)        for(auto it: a)cout<<it<<" ";newl;
#define  deb1(a)        cout<<a<<" ";newl;
#define  deb2(a,b)      cout<<a<<" "<<b<<" ";newl;
#define  deb3(a,b,c)    cout<<a<<" "<<b<<" "<<c<<" ";newl;
#define  deb4(a,b,c,d)  cout<<a<<" "<<b<<" "<<c<<" "<<d;newl;
#define  ll             long long
#define  ld             long double
#define  pll            pair<ll,ll>
#define  vll            vector<ll>
#define  vpll           vector<pll>

const ld   PI    =  3.14159265358979323846;
const ll   MOD   =  1e+9+7;
const ll   INF   =  LLONG_MAX;
const int  INFi  =  INT_MAX;
const ll   N     =  2e+5+8;

vll adj[N]; set<ll> vis;
ll dx4[]={0,1,0,-1}, dy4[]={1,0,-1,0};

ll test_cases = 1; randomINIT;

/*********************************************************************************************************/
/***************************************** VARIABLE DECLARATIONS *****************************************/
ll n, m , u, v, f[N];
vpll q;

/***************************************** FUNCTION IMPLEMENTATIONS **************************************/

/***************************************** START OF MAIN FUNCTION ****************************************/
void MAIN(ll tc){
    cin>>n>>m;
    for(ll i=1; i <= m; i++){
        cin>>u>>v;
        f[v]++;
        q.pb({u,v});
        vis.insert(u);
        vis.insert(v);
    }

    ll res = vis.size()-1;
    for(auto [u,v]: q){
        if(f[u]>=f[v]){
            res++;
            break;
        }
    }
    cout<<res;
}

int main(){
    SPEED;

    //cin>>test_cases;
    foo(i,1,test_cases){
    MAIN(i);
    }
}


/***************************************** START OF TEMPLATE *********************************************/
#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#include<bits/stdc++.h>

using namespace std;

#define  SPEED          ios:: sync_with_stdio(0);cin.tie(0);cout.tie(0);cout<<fixed;cout<<setprecision(10);
#define  randomINIT     mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
#define  foo(i,a,n)     for(ll i = (a); i <= n; i++)
#define  frr(i,a,n)     for(ll i = (a); i >= n; i--)
#define  fo(i,n)        for(ll i = 0; i < n; i++)
#define  newl           cout<<"\n";
#define  f              first
#define  s              second
#define  pb             push_back
#define  mp             make_pair
#define  sym(s)         s="#"+s+"#";
#define  all(x)         (x).begin(),(x).end()
#define  alll(x, n)     x+1, x+n+1
#define  mset(x,val)    memset(x,val,sizeof(x))
#define  mset1d(a,n,v)  foo(i,0,n+5)a[i]=v;
#define  mset2d(a,n,m,v)foo(i,0,n+5)foo(j,0,m+5)a[i][j]=v;
#define  INP(a,n)       foo(i,1,n) cin>>a[i];
#define  deb1d(a,n)     foo(i,1,n)cout<<a[i]<<" ";newl;
#define  deb2d(a,n,m)   foo(i,1,n){foo(j,1,m){cout<<a[i][j]<<" ";}newl;}
#define  debm(a)        for(auto it: a)cout<<"{"<<it.f<<","<<it.s<<"}, ";newl;
#define  debp(a,n)      foo(i,1,n)cout<<"{"<<a[i].f<<","<<a[i].s<<"}, ";newl;
#define  debv(a)        for(auto it: a)cout<<it<<" ";newl;
#define  deb1(a)        cout<<a<<" ";newl;
#define  deb2(a,b)      cout<<a<<" "<<b<<" ";newl;
#define  deb3(a,b,c)    cout<<a<<" "<<b<<" "<<c<<" ";newl;
#define  deb4(a,b,c,d)  cout<<a<<" "<<b<<" "<<c<<" "<<d;newl;
#define  ll             long long
#define  ld             long double
#define  pll            pair<ll,ll>
#define  vll            vector<ll>
#define  vpll           vector<pll>

const ld   PI    =  3.14159265358979323846;
const ll   MOD   =  1e+9+7;
const ll   INF   =  LLONG_MAX;
const int  INFi  =  INT_MAX;
const ll   N     =  2e+5+8;

vll adj[N], adju[N]; ll vis[N];
ll dx4[]={0,1,0,-1}, dy4[]={1,0,-1,0};

ll test_cases = 1; randomINIT;

/*********************************************************************************************************/
/***************************************** VARIABLE DECLARATIONS *****************************************/
ll n, m, u, v, ok, grp[N];
vll pt;

/***************************************** FUNCTION IMPLEMENTATIONS **************************************/
void isCycle(ll v, ll p){
    vis[v]=1;
    for(auto to: adj[v]){
        if(vis[to]==1) ok = 1;
        if(vis[to]==0) isCycle(to,v);
    }
    vis[v]=2;
}

void dfs(ll v, ll p){
    vis[v]=1;
    for(auto to: adju[v]){
        if(vis[to]==0)
            dfs(to,v);
    }
    pt.pb(v);
}

/***************************************** START OF MAIN FUNCTION ****************************************/
void MAIN(ll tc){
    cin>>n>>m;
    for(ll i=1; i <= m; i++){
        cin>>u>>v;
        adj[u].pb(v);
        adju[u].pb(v);
        adju[v].pb(u);
    }

    ll ct=1, res=0;
    mset1d(vis,n,0);
    for(ll i=1; i<=n; i++){
        if(vis[i] == 0) {
            pt.clear();
            dfs(i,0);
            for(auto it: pt) grp[it]=ct;
            res+=pt.size()-1;
            ct++;
        }
    }

    set<ll> k;
    mset1d(vis,n,0);
    for(ll i=1; i<=n; i++){
        if(vis[i] == 0) {
            ok=0;
            isCycle(i,0);
            if(ok) k.insert(grp[i]);
        }
    }
    res+=k.size();
    cout<<res;
}

int main(){
    SPEED;

    //cin>>test_cases;
    foo(i,1,test_cases){
    MAIN(i);
    }
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int N = 1e5 + 200;
const int L = 18;
#define F first
#define S second
#define PB push_back
#define vll vector<ll>
#define pll pair<ll, ll>
#define vpll vector<pll>
#define ios ios_base::sync_with_stdio(0);   cin.tie();  cout.tie();
#define dbg(x)  cerr << x << endl
#define mod 1000000007

ll n, m, u, v, cp[N], mark[N], sz[N];
vll g[N], topol, g2[N];

void DFS(ll v)
{
    mark[v] = 1;
    for (int i = 0; i < g[v].size(); i++)
    {
        ll u = g[v][i];
        if (!mark[u])
            DFS(u);
    }
    topol.PB(v);
}

void DFScomp(ll v, ll c)
{
    cp[v] = c;
    for (int i = 0; i < g2[v].size(); i++)
    {
        if (!cp[g2[v][i]])
        {
            DFScomp(g2[v][i], c);
        }
    }
}

ll DFS3(ll v)
{
    mark[v] = 1;
    ll ans = sz[cp[v]] == 1;
    for (int i = 0; i < g[v].size(); i++)
    {
        if (!mark[g[v][i]])
        {
            ans &= DFS3(g[v][i]);
        }
    }
    for (int i = 0; i < g2[v].size(); i++)
    {
        if (!mark[g2[v][i]])
        {
            ans &= DFS3(g2[v][i]);
        }
    }
    return ans;
}

int main()
{
    ios
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        cin >> u >> v;
        g[u].PB(v);
        g2[v].PB(u);
    }
    for (int i = 1; i <= n; i++)
        if (!mark[i])
        {
            DFS(i);
        }
    reverse(topol.begin(), topol.end());
    ll c = 1;
    for (int i = 0; i < n; i++)
    {
        if (!cp[topol[i]])
        {
            DFScomp(topol[i], c++);
        }
    }
    for (int i = 1; i <= n; i++)
        sz[cp[i]] ++;
    memset(mark, 0, sizeof mark);
    ll sum = n;
    for (int i = 1; i <= n; i++)
    {
        if (!mark[i])
            sum -= DFS3(i);
    }
    cout << sum;

}

/*
 ███▄ ▄███▓ ██▀███   ██▓███   ██▀███   ██▓ ███▄    █  ▄████▄  ▓█████
▓██▒▀█▀ ██▒▓██ ▒ ██▒▓██░  ██▒▓██ ▒ ██▒▓██▒ ██ ▀█   █ ▒██▀ ▀█  ▓█   ▀
▓██    ▓██░▓██ ░▄█ ▒▓██░ ██▓▒▓██ ░▄█ ▒▒██▒▓██  ▀█ ██▒▒▓█    ▄ ▒███
▒██    ▒██ ▒██▀▀█▄  ▒██▄█▓▒ ▒▒██▀▀█▄  ░██░▓██▒  ▐▌██▒▒▓▓▄ ▄██▒▒▓█  ▄
▒██▒   ░██▒░██▓ ▒██▒▒██▒ ░  ░░██▓ ▒██▒░██░▒██░   ▓██░▒ ▓███▀ ░░▒████▒
░ ▒░   ░  ░░ ▒▓ ░▒▓░▒▓▒░ ░  ░░ ▒▓ ░▒▓░░▓  ░ ▒░   ▒ ▒ ░ ░▒ ▒  ░░░ ▒░ ░
░  ░      ░  ░▒ ░ ▒░░▒ ░       ░▒ ░ ▒░ ▒ ░░ ░░   ░ ▒░  ░  ▒    ░ ░  ░
░      ░     ░░   ░ ░░         ░░   ░  ▒ ░   ░   ░ ░ ░           ░
       ░      ░                 ░      ░           ░ ░ ░         ░  ░
*/


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;

const int N = 2e3 + 200;
const int L = 18;
#define F first
#define S second
#define PB push_back
#define vll vector<ll>
#define pll pair<ll, ll>
#define vpll vector<pll>
#define ios ios_base::sync_with_stdio(0);   cin.tie();  cout.tie();
#define dbg(x)  cerr << x << endl
#define mod 1000000007

ll n, m, u, v, cp[N], mark[N], mat[N][N];
vll g[N], topol, g2[N];

void DFS(ll v)
{
    mark[v] = 1;
    for (int i = 0; i < g[v].size(); i++)
    {
        ll u = g[v][i];
        if (!mark[u])
            DFS(u);
    }
    topol.PB(v);
}

void DFScomp(ll v, ll c)
{
    cp[v] = c;
    for (int i = 0; i < g2[v].size(); i++)
    {
        if (!cp[g2[v][i]])
        {
            DFScomp(g2[v][i], c);

        }
    }
}

int main()
{
    ios
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
        cin >> u >> v;
        g[u].PB(v);
        g2[v].PB(u);
    }
    for (int i = 1; i <= n; i++)
        if (!mark[i])
            DFS(i);
    reverse(topol.begin(), topol.end());
    ll c = 1;
    for (int i = 0; i < n; i++)
    {
        if (!cp[topol[i]])
        {
            DFScomp(topol[i], c++);
        }
    }
    if (c == n + 1)
        return cout << n - 1 , 0;
    cout << n;

}

/*
 ███▄ ▄███▓ ██▀███   ██▓███   ██▀███   ██▓ ███▄    █  ▄████▄  ▓█████
▓██▒▀█▀ ██▒▓██ ▒ ██▒▓██░  ██▒▓██ ▒ ██▒▓██▒ ██ ▀█   █ ▒██▀ ▀█  ▓█   ▀
▓██    ▓██░▓██ ░▄█ ▒▓██░ ██▓▒▓██ ░▄█ ▒▒██▒▓██  ▀█ ██▒▒▓█    ▄ ▒███
▒██    ▒██ ▒██▀▀█▄  ▒██▄█▓▒ ▒▒██▀▀█▄  ░██░▓██▒  ▐▌██▒▒▓▓▄ ▄██▒▒▓█  ▄
▒██▒   ░██▒░██▓ ▒██▒▒██▒ ░  ░░██▓ ▒██▒░██░▒██░   ▓██░▒ ▓███▀ ░░▒████▒
░ ▒░   ░  ░░ ▒▓ ░▒▓░▒▓▒░ ░  ░░ ▒▓ ░▒▓░░▓  ░ ▒░   ▒ ▒ ░ ░▒ ▒  ░░░ ▒░ ░
░  ░      ░  ░▒ ░ ▒░░▒ ░       ░▒ ░ ▒░ ▒ ░░ ░░   ░ ▒░  ░  ▒    ░ ░  ░
░      ░     ░░   ░ ░░         ░░   ░  ▒ ░   ░   ░ ░ ░           ░
       ░      ░                 ░      ░           ░ ░ ░         ░  ░
*/


#include <bits/stdc++.h>

using namespace std;

array<int, 100000> dad;
array<int, 100000> set_size;
array<bool, 100000> has_cycle;
array<int, 100000> status; // 0 unseen, 1 on stack, 2 processed

int n, m;
array<vector<int>, 100000> edges;

void init()
{
    for (int i = 0; i < n; ++i)
        dad[i] = i;
    set_size.fill(1);
    has_cycle.fill(false);
}

int find_set(int x)
{
    while (dad[x] != x)
        dad[x] = dad[dad[x]],
        x = dad[x];
    return x;
}

bool same_set(int a, int b)
{
    return find_set(a) == find_set(b);
}

void union_set(int a, int b)
{
    a = find_set(a);
    b = find_set(b);

    if (a != b)
        dad[b] = a,
        set_size[a] += set_size[b],
        has_cycle[a] |= has_cycle[b];
}

void dfs(int me, int repr)
{
    status[me] = 1;
    union_set(me, repr);

    for (int son : edges[me])
        if (status[son] == 0)
            dfs(son, repr);
        else if (status[son] == 1)
            has_cycle[find_set(repr)] = true;
        else if (status[son] == 2)
            has_cycle[find_set(repr)] |= has_cycle[find_set(son)],
            union_set(repr, son);

    status[me] = 2;
}

int main()
{
    ios::sync_with_stdio(0);

    // get input
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        int a, b;
        cin >> a >> b;
        edges[a - 1].push_back(b - 1);
    }

    // initialize union-find
    init();

    // dfs from each node
    for (int i = 0; i < n; ++i)
        if (status[i] == 0)
            dfs(i, i);

    // aggregate answer
    int ans = 0;
    for (int i = 0; i < n; ++i)
        if (dad[i] == i)
        {
            ans += set_size[i] - 1;
            ans += (has_cycle[i]) ? 1 : 0 ;
        }

    // // debug
    // cout << "debug: " << endl;
    // for (int i = 0; i < n; ++i)
    //     cout << dad[i] << " " << has_cycle[i] << endl;

    // print answer
    cout << ans << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int n, m;
array<vector<int>, 100000> edges;
array<int, 100000> state; // 0 unexplored, 1 "on stack", 2 done

pair<int, bool> dfs(int me)
{
    int agg = 0;
    bool cycle = false;

    state.at(me) = 1;

    for (int b : edges.at(me))
        if (state.at(b) == 0)
        {
            pair<int, bool> pr = dfs(b);
            agg += pr.first;
            cycle |= pr.second;
        }
        else if (state.at(b) == 1)
            cycle = true;

    state.at(me) = 2;
    return {agg + 1, cycle};
}

int main()
{
    ios::sync_with_stdio(0);

    // get input
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        int a, b;
        cin >> a >> b;
        edges[a - 1].push_back(b - 1);
    }

    // dfs
    int ans = 0;
    for (int i = 0; i < n; ++i)
        if (state.at(i) == 0)
        {
            pair<int, bool> pr = dfs(i);
            ans += pr.first;
            if (!pr.second)
                ans -= 1;
        }

    // print answer
    cout << ans << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

array<int, 100000> dad;
array<int, 100000> set_size;
array<bool, 100000> has_cycle;
array<int, 100000> status; // 0 unseen, 1 on stack, 2 processed

int n, m;
array<vector<int>, 100000> edges;

void init()
{
    for (int i = 0; i < n; ++i)
        dad[i] = i;
    set_size.fill(1);
    has_cycle.fill(false);
}

int find_set(int x)
{
    while (dad[x] != x)
        dad[x] = dad[dad[x]],
        x = dad[x];
    return x;
}

bool same_set(int a, int b)
{
    return find_set(a) == find_set(b);
}

void union_set(int a, int b)
{
    a = find_set(a);
    b = find_set(b);

    if (a != b)
    {
        if (set_size[a] >= set_size[b])
            dad[b] = a,
            set_size[a] += set_size[b],
            has_cycle[a] |= has_cycle[b];
        else
            dad[a] = b,
            set_size[b] += set_size[a],
            has_cycle[b] |= has_cycle[a];
    }
}

void dfs(int me, int repr)
{
    status[me] = 1;
    union_set(me, repr);

    for (int son : edges[me])
        if (status[son] == 0)
            dfs(son, repr);
        else if (status[son] == 1)
            has_cycle[find_set(repr)] = true;
        else if (status[son] == 2)
            has_cycle[find_set(repr)] |= has_cycle[find_set(son)],
            union_set(repr, son);

    status[me] = 2;
}

int main()
{
    ios::sync_with_stdio(0);

    // get input
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        int a, b;
        cin >> a >> b;
        edges[a - 1].push_back(b - 1);
    }

    // initialize union-find
    init();

    // dfs from each node
    for (int i = 0; i < n; ++i)
        if (status[i] == 0)
            dfs(i, i);

    // aggregate answer
    int ans = 0;
    for (int i = 0; i < n; ++i)
        if (dad[i] == i)
        {
            ans += set_size[i] - 1;
            ans += (has_cycle[i]) ? 1 : 0 ;
        }

    // // debug
    // cout << "debug: " << endl;
    // for (int i = 0; i < n; ++i)
    //     cout << dad[i] << " " << has_cycle[i] << endl;

    // print answer
    cout << ans << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

array<int, 100000> dad;
array<int, 100000> size;
array<bool, 100000> has_cycle;
array<int, 100000> status; // 0 unseen, 1 on stack, 2 processed

int n, m;
array<vector<int>, 100000> edges;

void init()
{
    for (int i = 0; i < n; ++i)
        dad[i] = i;
    size.fill(1);
    has_cycle.fill(false);
}

int find_set(int x)
{
    while (dad[x] != x)
        dad[x] = dad[dad[x]],
        x = dad[x];
    return x;
}

bool same_set(int a, int b)
{
    return find_set(a) == find_set(b);
}

void union_set(int a, int b)
{
    a = find_set(a);
    b = find_set(b);

    if (a != b)
        dad[b] = a,
        size[a] += size[b],
        has_cycle[a] |= has_cycle[b];
}

void dfs(int me, int repr)
{
    status[me] = 1;
    union_set(me, repr);

    for (int son : edges[me])
        if (status[son] == 0)
            dfs(son, repr);
        else if (status[son] == 1)
            has_cycle[find_set(repr)] = true;
        else if (status[son] == 2)
            has_cycle[find_set(repr)] |= has_cycle[find_set(son)],
            union_set(repr, son);

    status[me] = 2;
}

int main()
{
    ios::sync_with_stdio(0);

    // get input
    cin >> n >> m;
    for (int i = 0; i < m; ++i)
    {
        int a, b;
        cin >> a >> b;
        edges[a - 1].push_back(b - 1);
    }

    // initialize union-find
    init();

    // dfs from each node
    for (int i = 0; i < n; ++i)
        if (status[i] == 0)
            dfs(i, i);

    // aggregate answer
    int ans = 0;
    for (int i = 0; i < n; ++i)
        if (dad[i] == i)
        {
            ans += size[i] - 1;
            ans += (has_cycle[i]) ? 1 : 0 ;
        }

    // // debug
    // cout << "debug: " << endl;
    // for (int i = 0; i < n; ++i)
    //     cout << dad[i] << " " << has_cycle[i] << endl;

    // print answer
    cout << ans << endl;

    return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstring>
#include <math.h>
#include <map>
#include <ctime>
#include <vector>
#include <iomanip>
#include <set>
#include <deque>
#define ss second
#define ff first
#define time() printf("%fs.\n", (float) clock () / CLOCKS_PER_SEC)
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define ret(n) return cout << n, 0
#define se(n) cout << setprecision(n) << fixed
#define ll long long
#define pb push_back
using namespace std;

const ll N = 2e5, OO = 1e18, M = 1e9 + 7;
vector <ll> v[N], vb[N], t;
bool mark[N], b[N];
ll sz = 0, k = 0, c[N], cnt[N];

void finisher(ll x) {
	mark[x] = true;
	for(auto i : v[x]) {
		if(!mark[i])
			finisher(i);
	}
	t.push_back(x);
}

void back_dfs(ll x) {
	mark[x] = true;
	c[x] = sz;
	k++;
	for(auto i : vb[x]) {
		if(!mark[i])
			back_dfs(i);
	}
}

ll dfs(ll x) {
	mark[x] = true;
	ll r = cnt[c[x]] == 1;
	for(auto i : v[x]) {
		if(!mark[i])
			r &= dfs(i);
	}
	for(auto i : vb[x]) {
		if(!mark[i])
			r &= dfs(i);
	}
	return r;
}

int main () {
	use_fast;
	ll n, m;
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		ll x, y;
		cin >> x >> y;
		v[--x].pb(--y);
		vb[y].pb(x);
	}
	for(int i = 0; i < n; i++) {
		if(!mark[i]) {
			finisher(i);
		}
	}
	fill(mark, mark + n, 0);
	ll ans = n;
	for(ll i = t.size() - 1; i >= 0; i--) {
		if(!mark[t[i]]) {
			k = 0;
			back_dfs(t[i]);
			cnt[sz] = k;
			sz++;
		}
	}
	fill(mark, mark + n, 0);
	for(int i = 0; i < n; i++) {
		if(!mark[i]) {
			ans -= dfs(i);
		}
	}
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstring>
#include <math.h>
#include <map>
#include <ctime>
#include <vector>
#include <iomanip>
#include <set>
#include <deque>
#define ss second
#define ff first
#define time() printf("%fs.\n", (float) clock () / CLOCKS_PER_SEC)
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define ret(n) return cout << n, 0
#define se(n) cout << setprecision(n) << fixed
#define ll long long
#define pb push_back
using namespace std;

const ll N = 2e6, OO = 1e18, M = 1e9 + 7;
vector <ll> v[N], vb[N], t;
bool mark[N];
ll sz = 0;

void finisher(ll x) {
	mark[x] = true;
	for(auto i : v[x]) {
		if(!mark[i])
			finisher(i);
	}
	t.push_back(x);
}

void back_dfs(ll x) {
	sz++;
	mark[x] = true;
	for(auto i : vb[x]) {
		if(!mark[i])
			back_dfs(i);
	}
}

void dfs(ll x) {
	mark[x] = true;
	for(auto i : v[x]) {
		if(!mark[i])
			dfs(i);
	}
	for(auto i : vb[x]) {
		if(!mark[i])
			dfs(i);
	}
}

int main () {
	use_fast;
	ll n, m;
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		ll x, y;
		cin >> x >> y;
		v[--x].pb(--y);
		vb[y].pb(x);
	}
	for(int i = 0; i < n; i++) {
		if(!mark[i]) {
			finisher(i);
		}
	}
	fill(mark, mark + n, 0);
	ll ans = 0;
	for(ll i = t.size() - 1; i >= 0; i--) {
		if(!mark[t[i]]) {
			sz = 0;
			back_dfs(t[i]);
			if(sz != 1)
				ans += sz;
			ans++;
		}
	}
	fill(mark, mark + n, 0);
	for(int i = 0; i < n; i++) {
		if(!mark[i]) {
			dfs(i);
			ans--;
		}
	}
	cout << ans << endl;
	return 0;
}


#include <iostream>
#include <utility>
#include <algorithm>
#include<cmath>
#include<algorithm>
#include<vector>
#include<cstring>
#include <math.h>
#include <map>
#include <ctime>
#include <vector>
#include <iomanip>
#include <set>
#include <deque>
#define ss second
#define ff first
#define time() printf("%fs.\n", (float) clock () / CLOCKS_PER_SEC)
#define use_fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define ret(n) return cout << n, 0
#define se(n) cout << setprecision(n) << fixed
#define ll long long
#define pb push_back
using namespace std;

const ll N = 2e6, OO = 1e18, M = 1e9 + 7;
vector <ll> v[N], vb[N], t, k[N];
bool mark[N];
ll sz = 0;

void finisher(ll x) {
	mark[x] = true;
	for(auto i : v[x]) {
		if(!mark[i])
			finisher(i);
	}
	t.push_back(x);
}

void back_dfs(ll x) {
	sz++;
	mark[x] = true;
	for(auto i : vb[x]) {
		if(!mark[i])
			back_dfs(i);
	}
}

void dfs(ll x) {
	mark[x] = true;
	for(auto i : k[x]) {
		if(!mark[i])
			dfs(i);
	}
}

int main () {
	use_fast;
	ll n, m;
	cin >> n >> m;
	for(int i = 0; i < m; i++) {
		ll x, y;
		cin >> x >> y;
		v[--x].pb(--y);
		vb[y].pb(x);
		k[x].pb(y);
		k[y].pb(x);
	}
	for(int i = 0; i < n; i++) {
		if(!mark[i]) {
			finisher(i);
		}
	}
	fill(mark, mark + n, 0);
	ll ans = 0;
	for(ll i = t.size() - 1; i >= 0; i--) {
		if(!mark[t[i]]) {
			sz = 0;
			back_dfs(t[i]);
			if(sz != 1)
				ans += sz;
			ans++;
		}
	}
	ll r = 0;
	fill(mark, mark + n, 0);
	for(int i = 0; i < n; i++) {
		if(!mark[i]) {
			dfs(i);
			r++;
		}
	}
	ans -= r;
	cout << ans << endl;
	return 0;
}


#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#include<bits/stdc++.h>

using namespace std;

#define  fastio         ios:: sync_with_stdio(0);cin.tie(0);cout.tie(0);cout<<fixed;cout<<setprecision(10);
#define  f              first
#define  s              second
#define  endl           "\n"
#define  pb             push_back
#define  mset(a,x)      memset(a,x,sizeof(a))
#define  debv(a)        for(auto it: a)cout<<it<<" ";cout<<endl;
#define  deb1(a)        cout<<a<<" "<<endl;
#define  deb2(a,b)      cout<<a<<" "<<b<<" "<<endl;
#define  deb3(a,b,c)    cout<<a<<" "<<b<<" "<<c<<" "<<endl;
#define  deb4(a,b,c,d)  cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;

typedef  long long             ll;
typedef  long double           ld;
typedef  pair<ll,ll>           pll;
typedef  vector<ll>            vll;
typedef  unordered_map<pll,ll>  um;
typedef  vector<pll>           vpll;

const int   N    =  3e5+5;
const ll   mod   =  1e9+7;
const ll   INF   =  1e18;
const int  INFi  =  0x7f7f7f7f;

ll test=1,n,m,vis[N],rec[N],cyc[N],p[N],sz[N];
vll adj[N];

void make(ll n){
    for(int i = 1; i <= n; i++){
        p[i] = i;
        sz[i] = 1;
    }
}

int find(ll x){
    return (p[x] == x)? x: p[x] = find(p[x]);
}

void merge(ll x, ll y){
    ll a = find(x);
    ll b = find(y);
    if(a != b){
        if(sz[a] >= sz[b]) swap(a,b);
        p[a] = b;
        sz[b] += sz[a];
    }
}

bool CycleUtil(int v){
    if(vis[v] == 0){
        vis[v] = 1, rec[v] = 1;
        for(auto it : adj[v]) {
            if(!vis[it] && CycleUtil(it))
                return 1;
            else if(rec[it])
                return 1;
        }
    }
    rec[v] = 0;
    return 0;
}

void Cycle(){
    for(int i = 1; i <= n; i++)
        if(CycleUtil(i))
            cyc[find(i)] = 1;
}

void solve(){
    cin>>n>>m;
    make(n);
    for(int i = 0; i < m; i++){
        int u,v;
        cin>>u>>v;
        adj[u].pb(v);
        merge(u,v);
    }
    Cycle();
    ll ans = 0;
    for(int i = 1; i <= n; i++){
        if(find(i) == i){
            if(cyc[i] == 1) ans += sz[i];
            else ans += sz[i]-1;
        }
    }
    deb1(ans)
}

int main(){
    fastio;
    //cin>>test;
    for(int i = 1; i <= test; i++){
        solve();
    }
}


#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx")
#include<bits/stdc++.h>

using namespace std;

#define  fastio         ios:: sync_with_stdio(0);cin.tie(0);cout.tie(0);cout<<fixed;cout<<setprecision(10);
#define  f              first
#define  s              second
#define  endl           "\n"
#define  pb             push_back
#define  mset(a,x)      memset(a,x,sizeof(a))
#define  debv(a)        for(auto it: a)cout<<it<<" ";cout<<endl;
#define  deb1(a)        cout<<a<<" "<<endl;
#define  deb2(a,b)      cout<<a<<" "<<b<<" "<<endl;
#define  deb3(a,b,c)    cout<<a<<" "<<b<<" "<<c<<" "<<endl;
#define  deb4(a,b,c,d)  cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;

typedef  long long             ll;
typedef  long double           ld;
typedef  pair<ll,ll>           pll;
typedef  vector<ll>            vll;
typedef  unordered_map<pll,ll>  um;
typedef  vector<pll>           vpll;

const int   N    =  3e5+5;
const ll   mod   =  1e9+7;
const ll   INF   =  1e18;
const int  INFi  =  0x7f7f7f7f;

ll test=1,n,m,vis[N],rec[N],cyc[N],p[N],sz[N];
vll adj[N];
stack <ll> Stack;

void make(ll n){
    for(int i = 1; i <= n; i++){
        p[i] = i;
        sz[i] = 1;
    }
}

int find(ll x){
    return (p[x] == x)? x: p[x] = find(p[x]);
}

void merge(ll x, ll y){
    ll a = find(x);
    ll b = find(y);
    if(a != b){
        if(sz[a] >= sz[b]) swap(a,b);
        p[a] = b;
        sz[b] += sz[a];
    }
}

void TSUtil(int v){
    vis[v] = 1;
    for(auto it : adj[v])
        if (!vis[it])
            TSUtil(it);
    Stack.push(v);
}

void TS(){
    for(int i = 1; i <= n; i++)
        if(!vis[i])
            TSUtil(i);
    while(Stack.empty() == 0){
        cout<<Stack.top()<<" ";
        Stack.pop();
    }
}

bool CycleUtil(int v){
    if(vis[v] == 0){
        vis[v] = 1, rec[v] = 1;
        for(auto it : adj[v]) {
            if(!vis[it] && CycleUtil(it))
                return 1;
            else if(rec[it])
                return 1;
        }
    }
    rec[v] = 0;
    return 0;
}

void Cycle(){
    for(int i = 1; i <= n; i++)
        if(CycleUtil(i))
            cyc[find(i)] = 1;
}

void solve(){
    cin>>n>>m;
    make(n);
    for(int i = 0; i < m; i++){
        int u,v;
        cin>>u>>v;
        adj[u].pb(v);
        merge(u,v);
    }
    Cycle();
    ll ans = 0;
    for(int i = 1; i <= n; i++){
        if(find(i) == i){
            if(cyc[i] == 1) ans += sz[i];
            else ans += sz[i]-1;
        }
    }
    deb1(ans)
}

int main(){
    fastio;
    //cin>>test;
    for(int i = 1; i <= test; i++){
        solve();
    }
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;

int n, m;
int tin[N], low[N], tim;
int comp[N], cmp;
int sz[N], par[N], szp[N];
bool onStack[N];
stack<int> st;
vector<int> g[N];
set<int> cg[N];

void dfs(int u) {
    tin[u] = low[u] = ++tim;
    st.emplace(u);
    onStack[u] = true;
    for (auto v : g[u]) {
        if (tin[v] == 0) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if (onStack[v]) {
            low[u] = min(low[u], tin[v]);
        }
    }
    if (low[u] == tin[u]) {
        int w = 0;
        cmp++;
        do {
            w = st.top();
            st.pop();
            comp[w] = cmp;
            sz[cmp]++;
            onStack[w] = false;
        } while (w != u && !st.empty());
    }
}

int fpar(int x) {
    return (par[x] == x ? x : par[x] = fpar(par[x]));
}

void merge(int u, int v) {
    int pu = fpar(u);
    int pv = fpar(v);
    if (pu == pv) return;
    if (szp[pu] < szp[pv]) swap(pu, pv);
    szp[pu] += szp[pv];
    par[pv] = pu;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
    }
    dfs(1);
    int ans = 0;
    for (int i = 1; i <= cmp; i++) {
        if (sz[i] > 1) ans += sz[i];
        par[i] = i, szp[i] = 1;
    }
    for (int i = 1; i <= n; i++) {
        for (auto j : g[i]) {
            merge(comp[j], comp[i]);
        }
    }
    for (int i = 1; i <= cmp; i++) {
        if (fpar(i) != i) continue;
        ans += (szp[i] - 1);
    }
    cout << ans << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;

int n, m;
int tin[N], low[N], tim;
int comp[N], cmp;
int sz[N], par[N], szp[N];
bool onStack[N];
stack<int> st;
vector<int> g[N];

void dfs(int u) {
    tin[u] = low[u] = ++tim;
    st.emplace(u);
    onStack[u] = true;
    for (auto v : g[u]) {
        if (tin[v] == 0) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if (onStack[v]) {
            low[u] = min(low[u], tin[v]);
        }
    }
    if (low[u] == tin[u]) {
        int w = 0;
        cmp++;
        do {
            w = st.top();
            st.pop();
            comp[w] = cmp;
            sz[cmp]++;
            onStack[w] = false;
        } while (w != u && !st.empty());
    }
}

int fpar(int x) {
    return (par[x] == x ? x : par[x] = fpar(par[x]));
}

void merge(int u, int v) {
    int pu = fpar(u);
    int pv = fpar(v);
    if (pu == pv) return;
    if (szp[pu] < szp[pv]) swap(pu, pv);
    szp[pu] += szp[pv];
    par[pv] = pu;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
    }
    for (int i = 1; i <= n; i++) {
        if (tin[i] == 0) dfs(i);
    }
    int ans = 0;
    for (int i = 1; i <= cmp; i++) {
        if (sz[i] > 1) ans += sz[i];
        par[i] = i, szp[i] = 1;
    }
    for (int i = 1; i <= n; i++) {
        for (auto j : g[i]) {
            merge(comp[j], comp[i]);
        }
    }
    for (int i = 1; i <= cmp; i++) {
        if (fpar(i) != i) continue;
        ans += (szp[i] - 1);
    }
    cout << ans << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;

int n, m;
int tin[N], low[N], tim;
int comp[N], cmp;
int sz[N], par[N], szp[N];
bool onStack[N];
stack<int> st;
vector<int> g[N];

void dfs(int u) {
    tin[u] = low[u] = ++tim;
    st.emplace(u);
    onStack[u] = true;
    for (auto v : g[u]) {
        if (tin[v] == 0) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if (onStack[v]) {
            low[u] = min(low[u], tin[v]);
        }
    }
    if (low[u] == tin[u]) {
        int w = 0;
        cmp++;
        do {
            w = st.top();
            st.pop();
            comp[w] = cmp;
            sz[cmp]++;
            onStack[w] = false;
        } while (w != u && !st.empty());
    }
}

int fpar(int x) {
    return (par[x] == x ? x : par[x] = fpar(par[x]));
}

void merge(int u, int v) {
    int pu = fpar(u);
    int pv = fpar(v);
    if (pu == pv) return;
    if (szp[pu] < szp[pv]) swap(pu, pv);
    szp[pu] += szp[pv];
    par[pv] = pu;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
    }
    for (int i = 1; i <= n; i++) {
        if (tin[i] == 0) dfs(i);
    }
    for (int i = 1; i <= cmp; i++) {
        par[i] = i, szp[i] = 1;
    }
    for (int i = 1; i <= n; i++) {
        for (auto j : g[i]) {
            merge(comp[j], comp[i]);
        }
    }
    vector<int> noCycle(cmp + 1, 1);
    for (int i = 1; i <= cmp; i++) {
        int pi = fpar(i);
        if (sz[i] > 1) noCycle[pi] = 0;
    }
    int ans = 0;
    for (int i = 1; i <= cmp; i++) {
        if (fpar(i) != i) continue;
        ans += szp[i] - noCycle[i];
    }
    cout << ans << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;

int n, m;
int tin[N], low[N], tim;
int comp[N], cmp;
int sz[N], par[N], szp[N];
bool onStack[N];
stack<int> st;
vector<int> g[N];

void dfs(int u) {
    tin[u] = low[u] = ++tim;
    st.emplace(u);
    onStack[u] = true;
    for (auto v : g[u]) {
        if (tin[v] == 0) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if (onStack[v]) {
            low[u] = min(low[u], tin[v]);
        }
    }
    if (low[u] == tin[u]) {
        int w = 0;
        cmp++;
        do {
            w = st.top();
            st.pop();
            comp[w] = cmp;
            sz[cmp]++;
            onStack[w] = false;
        } while (w != u && !st.empty());
    }
}

int fpar(int x) {
    return (par[x] == x ? x : par[x] = fpar(par[x]));
}

void merge(int u, int v) {
    int pu = fpar(u);
    int pv = fpar(v);
    if (pu == pv) return;
    if (szp[pu] < szp[pv]) swap(pu, pv);
    szp[pu] += szp[pv];
    par[pv] = pu;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
    }
    for (int i = 1; i <= n; i++) {
        if (tin[i] == 0) dfs(i);
    }
    for (int i = 1; i <= cmp; i++) {
        par[i] = i, szp[i] = 1;
    }
    for (int i = 1; i <= n; i++) {
        for (auto j : g[i]) {
            merge(comp[j], comp[i]);
        }
    }
    vector<int> noCycle(cmp + 1, 1);
    vector<int> res(cmp + 1);
    for (int i = 1; i <= cmp; i++) {
        int pi = fpar(i);
        if (sz[i] > 1) noCycle[pi] = 0;
        res[pi] += sz[i];
    }
    int ans = 0;
    for (int i = 1; i <= cmp; i++) {
        if (fpar(i) != i) continue;
        if (noCycle[i]) {
            ans += (szp[i] - 1);
        } else {
            ans += res[i];
        }
    }
    cout << ans << '\n';

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;

int n, m;
int tin[N], low[N], tim;
int comp[N], cmp;
int sz[N], par[N], szp[N];
bool onStack[N];
stack<int> st;
vector<int> g[N];

void dfs(int u) {
    tin[u] = low[u] = ++tim;
    st.emplace(u);
    onStack[u] = true;
    for (auto v : g[u]) {
        if (tin[v] == 0) {
            dfs(v);
            low[u] = min(low[u], low[v]);
        } else if (onStack[v]) {
            low[u] = min(low[u], tin[v]);
        }
    }
    if (low[u] == tin[u]) {
        int w = 0;
        cmp++;
        do {
            w = st.top();
            st.pop();
            comp[w] = cmp;
            sz[cmp]++;
            onStack[w] = false;
        } while (w != u && !st.empty());
    }
}

int fpar(int x) {
    return (par[x] == x ? x : par[x] = fpar(par[x]));
}

void merge(int u, int v) {
    int pu = fpar(u);
    int pv = fpar(v);
    if (pu == pv) return;
    if (szp[pu] < szp[pv]) swap(pu, pv);
    szp[pu] += szp[pv];
    par[pv] = pu;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        int u, v;
        cin >> u >> v;
        g[u].emplace_back(v);
    }
    for (int i = 1; i <= n; i++) {
        if (tin[i] == 0) dfs(i);
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        for (auto j : g[i]) {
            merge(comp[j], comp[i]);
        }
    }
    vector<int> hasCycle(cmp + 1);
    for (int i = 1; i <= cmp; i++) {
        int pi = fpar(i);
        if (sz[i] > 1) hasCycle[pi] = true;
    }
    for (int i = 1; i <= cmp; i++) {
        if (fpar(i) != i) continue;
        ans += sz[i] - hasCycle[i];
    }
    cout << ans << '\n';

    return 0;
}


#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=10001;
int n,m,a,b,cnt,tmp,ans;
bool mark[N],markS[N],markR[N];
vector<int>cmp,cmpD[N],adj[N],adjR[N];
stack<int>st;
void dfs(int v)
{
	mark[v]=1;
	cmp.pb(v);
	for(auto u:adj[v])
		if(!mark[u])
			dfs(u);
	for(auto u:adjR[v])
		if(!mark[u])
			dfs(u);
}
void dfsS(int v)
{
	markS[v]=1;
	for(auto u:adj[v])
		if(!markS[u])
			dfsS(u);
	st.push(v);
}
void dfsR(int v,int cnt)
{
	markR[v]=1;
	cmpD[cnt].pb(v);
	for(auto u:adjR[v])
		if(!markR[u])
			dfsR(u,cnt);
}
int main()
{
	int i,j;
	cin>>n>>m;
	for(i=0;i<m;++i)
	{
		cin>>a>>b;
		adj[a].pb(b);
		adjR[b].pb(a);
	}
	for(i=1;i<=n;++i)
		if(!mark[i])
		{
			dfs(i);
			for(j=0;j<cmp.size();++j)
				if(!markS[cmp[j]])
					dfsS(cmp[j]);
			while(st.size())
			{
				if(!markR[st.top()])
					dfsR(st.top(),cnt++);
				st.pop();
			}
			tmp=cmp.size()-1;
			for(j=0;j<cnt;++j)
			{
				if(cmpD[j].size()>1)
					tmp=cmp.size();
				cmpD[j].clear();
			}
			cmp.clear();
			cnt=0;
			ans+=tmp;
		}
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define pb push_back
using namespace std;
const int N=100001;
int n,m,a,b,cnt,tmp,ans;
bool mark[N],markS[N],markR[N];
vector<int>cmp,cmpD[N],adj[N],adjR[N];
stack<int>st;
void dfs(int v)
{
	mark[v]=1;
	cmp.pb(v);
	for(auto u:adj[v])
		if(!mark[u])
			dfs(u);
	for(auto u:adjR[v])
		if(!mark[u])
			dfs(u);
}
void dfsS(int v)
{
	markS[v]=1;
	for(auto u:adj[v])
		if(!markS[u])
			dfsS(u);
	st.push(v);
}
void dfsR(int v,int cnt)
{
	markR[v]=1;
	cmpD[cnt].pb(v);
	for(auto u:adjR[v])
		if(!markR[u])
			dfsR(u,cnt);
}
int main()
{
	int i,j;
	cin>>n>>m;
	for(i=0;i<m;++i)
	{
		cin>>a>>b;
		adj[a].pb(b);
		adjR[b].pb(a);
	}
	for(i=1;i<=n;++i)
		if(!mark[i])
		{
			dfs(i);
			for(j=0;j<cmp.size();++j)
				if(!markS[cmp[j]])
					dfsS(cmp[j]);
			while(st.size())
			{
				if(!markR[st.top()])
					dfsR(st.top(),cnt++);
				st.pop();
			}
			tmp=cmp.size()-1;
			for(j=0;j<cnt;++j)
			{
				if(cmpD[j].size()>1)
					tmp=cmp.size();
				cmpD[j].clear();
			}
			cmp.clear();
			cnt=0;
			ans+=tmp;
		}
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define int long long
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define inf 10000000000000
#define mod 1000000007
#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define endl '\n'
using namespace std;
int power(int x, unsigned int y){int res = 1;while (y > 0){ if (y & 1){res = res*x;} y = y>>1;x = x*x;}return res;}
int powermod(int x, unsigned int y, int p){int res = 1;x = x % p;while (y > 0){if (y & 1){res = (res*x) % p;}y = y>>1; x = (x*x) % p;}return res;}
int Mod(int x, int m){ return (x%m+m)%m;}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}
const int N = 1e5 + 5;
int n,m;
int grp = 0;
vector<int>g[N],rg[N],undirg[N],todo;
int comp[N],sz[N];
bool vis[N];

void sccaddedge(int u,int v){
	g[u].pb(v);
	rg[v].pb(u);
}
void dfs(int node){
	vis[node] = true;
	for(auto x:g[node]){
		if(!vis[x]){
			dfs(x);
		}
	}
	todo.pb(node);
}
void dfs2(int node,int val){
	comp[node] = val;
	sz[val]++;
	for(auto x:rg[node]){
		if(comp[x]==-1){
			dfs2(x,val);
		}
	}
}
void scc(){

	for(int i = 1; i <= n; i++)
		comp[i] = -1;

	for(int i=1;i<=n;i++){
		if(!vis[i]){
			dfs(i);
		}
	}

	reverse(all(todo));
	for(auto it:todo){
		if(comp[it]==-1){
			dfs2(it,++grp);
		}
	}
}
int vertices,check;
void dfs0(int node){
	vis[node] = true;
	vertices++;
	check|= (sz[comp[node]]>1);
	for(auto x:undirg[node]){
		if(!vis[x]){
			dfs0(x);
		}
	}
}

int32_t main()
{

  fastio;
  cin>>n>>m;
  for(int i=0;i<m;i++){
  	int a,b;
  	cin>>a>>b;
  	sccaddedge(a,b);
  	undirg[a].pb(b);
  	undirg[b].pb(a);
  }
  scc();
  memset(vis,false,sizeof(vis));
  int ans = 0;
  for(int i=1;i<=n;i++){
  	if(vis[i]){
  		continue;
	  }

	  vertices=0;
	  check=0;
	  dfs0(i);

	  if(check){
	  	 ans+=vertices;
	  }
	  else{
	  	ans+=vertices-1;
	  }

  }
  cout<<ans<<endl;

  return 0;

}

/*
                                                 -----*** SEGMENT TREE ***--------

int st[1000001];
void updateValue(int arr[], int ss, int se,
                 int index, int value, int node)
{
    if (index < ss || index > se)
    {
        cout << "Invalid Input" << endl;
        return;
    }

    if (ss == se)
    {
        arr[index] = value;
        st[node] = value;
    }
    else {
            int mid =  ss+(se-ss)/2;

            if (index >= ss && index <= mid)
                updateValue(arr,  ss, mid, index,
                            value, 2 * node + 1);
            else
                updateValue(arr,  mid + 1, se,
                            index, value, 2 * node + 2);

            st[node] = max(st[2 * node + 1],
                       st[2 * node + 2]);
    }
    return;
}
int RMQUtil( int ss, int se, int qs, int qe, int index)
{
    if (qs <= ss && qe >= se)
        return st[index];

    if (se < qs || ss > qe)
        return inf;

    int mid = ss+(se-ss)/2;
    return min(RMQUtil( ss, mid, qs, qe, 2*index+1),
                RMQUtil( mid+1, se, qs, qe, 2*index+2));
}

void constructSTUtil(int arr[], int ss, int se,
                                 int si)
{

    if (ss == se)
    {

        st[si] = arr[ss];
        return;

    }

    int mid = ss+(se-ss)/2;
    //cout<<mid<<endl;
    constructSTUtil(arr, ss , mid, 2*si +1);
	constructSTUtil(arr, mid+1, se,2*si +2);
	st[si]  = min(st[2*si+1],st[2*si+2]);

}
                                                     ----***SPARSE TABE***-----

O(1) query sparse matrix for Max/Min/GCD

int RMQ[20][N];

void precompute()
{
	for(int i=0;(1<<i)<N;i++)
	{
		for(int j=(1<<i);j<N && j<(1<<(i+1)); j++)
			floorlog[j]=i;
	}

	for(int i=n;i>=1;i--)
	{
		RMQ[0][i]=dp[i];
		int mxj=floorlog[n-i+1]; //2^j <= n-i+1
		int pw=1;
		for(int j=1;j<=mxj;j++)
		{
			RMQ[j][i]=max(RMQ[j-1][i], RMQ[j-1][i+pw]);
			pw<<=1;
		}
	}
}

int getMax(int L, int R)
{
	int k=floorlog[R-L+1]; //2^k <= R-L+1
	return max(RMQ[k][L], RMQ[k][R - (1<<k) +1]);
}

                                                      ----*** NCR ***-------
int nCr(int n, int r)
{
    long long p = 1, k = 1;
    if (n - r < r)
        r = n - r;
    if (r != 0) {
        while (r) {
            p *= n;
            k *= r;
            long long m = __gcd(p, k);
            p /= m;
            k /= m;
            n--;
            r--;
        }
	}
    else
        p = 1;
    return p;
}

                                           ------*** print divisors 1 to n ***-------
vector<int> printDivisors(int n)
{
    vector<int>v;
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {

            if (n/i == i)
                v.pb(i);

            else
                v.pb(i),v.pb(n/i);
        }
    }
    return v;
}

                                               ------*** isPrime ***--------------
//check if a number is prime   O(sqrt(n))
bool isPrime(int n)
{

    if (n <= 1)  return false;
    if (n <= 3)  return true;
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}

                                                ------*** prime factorization *** -------------
const int MAXN = 100000;
int spf[MAXN];
// spf contains smallest prime factor of n
void sieve()
{   spf[1] = 1;
    for (int i=2; i<MAXN; i++)
       spf[i] = i;

    for (int i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (int i=3; i*i<MAXN; i++)
    {

        if (spf[i] == i)
        {

            for (int j=i*i; j<MAXN; j+=i)
                if (spf[j]==j)
                    spf[j] = i;
        }
    }
}

 A O(log n) function returning primefactorization
vector<int> getFactorization(int x)
{
    vector<int> ret;
    while (x != 1)
    {
        ret.push_back(spf[x]);
        x = x / spf[x];
    }
    return ret;
}

                                                                GRAPHS

                                                 -----*** TOPOLOGICAL SORT ***--------

vector<int> order; //Stores the Topological Order
vector<int>g[10];
bool toposort(int n) //Returns 1 if there exists a toposort, 0 if there is a cycle
{
	queue<int> q;
	vector<int> indeg(n + 1, 0);
	for(int i = 1; i <= n; i++)
		for(auto &it:g[i])
			indeg[it]++;
	for(int i = 1; i <= n; i++)
	{
		if(!indeg[i])
			q.push(i);
	}
	while(!q.empty())
	{
		int u = q.front();
		q.pop();
		order.push_back(u);
		for(auto &v:g[u])
		{
			indeg[v]--;
			if(!indeg[v])
				q.push(v);
		}
	}
	return (order.size() == n);
}

                                                  -----***cycle detection in directed graph***-----
bool findLoop(int v)
{
	if(vis[v]==1)
		return 1;
	if(vis[v]==2)
		return 0;
	vis[v]=1;
	for(auto &it:g[v])
	{
		if(findLoop(it))
			return 1;
	}
	vis[v]=2;
	return 0;
}

bool checkLoop()
{
	fill(vis+1, vis+n+1, 0);
	for(int i=1;i<=n;i++)
	{
		if(!vis[i] && findLoop(i))
			return 1;
	}
	return 0;
}

                                                 -------*** FLOYD WARSHALL ***----
                                                 All Pairs Shortest Path problem in 0(n^3)

int dist[N][N];

void FloydWarshall()
{
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				dist[i][j]=min(dist[i][j], dist[i][k] + dist[k][j]);
}

                                                 ---**** Dijkstra with Path ***------

int arrival[N], departure[N], vis[N], parent[N];
vector<pair<int, int> > g[N];

void dijkstra(int source, int destination)
{
	for(int i=1;i<=n;i++)
	{
		arrival[i]=1e18;
		departure[i]=1e18;
		vis[i]=0;
	}
	arrival[source]=0;
	set<pair<int, int> > s;
	s.insert({0, source});
	while(!s.empty())
	{
		auto x = *(s.begin());
		s.erase(x);
		vis[x.second]=1;
		departure[x.second]=arrival[x.second];
		for(auto it:g[x.second])
		{
			if(arrival[it.first] > departure[x.second] + it.second)
			{
				s.erase({arrival[it.first], it.first});
				arrival[it.first]=departure[x.second] + it.second;
				s.insert({arrival[it.first], it.first});
				parent[it.first]=x.second;
			}
		}
	}
	if(!vis[destination])
	{
		cout<<"-1";
		return;
	}
	int v=destination;
	vector<int> ans;
	while(parent[v])
	{
		ans.push_back(v);
		v=parent[v];
	}
	ans.push_back(source);
	reverse(ans.begin(), ans.end());
	for(auto it:ans)
		cout<<it<<" ";
}

-------------------------------------------------------------------------------------------------------------------------------------
                                                -------*** Simple Dijkstra: ***--------

int arrival[N][N], departure[N][N];
vector<pair<int, int> > g[N];

void dijkstra(int source, int destination, int arrival[], int departure[])
{
	for(int i=1;i<=n;i++)
	{
		arrival[i]=inf;
		departure[i]=inf;
	}
	arrival[source]=0;
	set<pair<int, int> > s;
	s.insert({0, source});
	while(!s.empty())
	{
		auto x = *(s.begin());
		s.erase(x);
		departure[x.second]=arrival[x.second];
		for(auto it:g[x.second])
		{
			if(arrival[it.first] > departure[x.second] + it.second)
			{
				s.erase({arrival[it.first], it.first});
				arrival[it.first]=departure[x.second] + it.second;
				s.insert({arrival[it.first], it.first});
			}
		}
	}
}

                                                 --------*** KMP SEARCH ***-----

vector<int> prefix_function(string &s)
{
	int n = s.size();
	vector<int> pi(n);
	for(int i = 1; i < n; i++)
	{
		int j = pi[i - 1];
		while(j > 0 && s[i] != s[j])
			j = pi[j - 1];
		if (s[i] == s[j])
			j++;
		pi[i] = j;
	}
	return pi;
}

vector<int> find_occurences(string &text, string &pattern)
{
	string cur = pattern + '#' + text;
	int sz1 = text.size(), sz2 = pattern.size();
	vector<int> v;
	vector<int> lps = prefix_function(cur);
	for(int i = sz2 + 1; i <= sz1 + sz2; i++)
	{
		if(lps[i] == sz2)
			v.push_back(i - 2 * sz2);
	}
	return v;
}

  1. always check for unintialized vector.

  2. priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> > pq; for djikstra

  3. check for constrained properly

  4. 10^8 operations per second

  5. Every even integer greater than 2 can be expressed as the sum of two primes.

  6. odd number can be expresses in sum of two prime number only if (n-2) is prime.

  7. always pass string vector everything  by reference else can get MLe TLE;

  8. An even digits of pallindromic number is always divided by 11 euler project 4th question..

  If n = 12, the time complexity can be O(n!).
  If n = 25, the time complexity can be O(2n).
  If n = 100, the time complexity can be O(n4).
  If n = 500, the time complexity can be O(n3).
  If n = 10^4, the time complexity can be O(n2).
  If n = 10^6, the time complexity can be O(n log n).
  If n = 10^8, the time complexity can be O(n).
  If n > 10^8, the time complexity can be O(log n) or O(1).

*/


#include<bits/stdc++.h>
#define int long long
#define rep(i,n) for(int i=0;i<n;i++)
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
#define inf 10000000000000
#define mod 1000000007
#define fastio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define endl '\n'
using namespace std;
int power(int x, unsigned int y){int res = 1;while (y > 0){ if (y & 1){res = res*x;} y = y>>1;x = x*x;}return res;}
int powermod(int x, unsigned int y, int p){int res = 1;x = x % p;while (y > 0){if (y & 1){res = (res*x) % p;}y = y>>1; x = (x*x) % p;}return res;}
int Mod(int x, int m){ return (x%m+m)%m;}
int min(int a,int b){return a<b?a:b;}
int max(int a,int b){return a>b?a:b;}

vector<int>g[200001];
int vis[200001];
int vis2[200001];
int cnt;
void dfs(int node){
	cnt++;
	vis2[node]=1;
	for(auto x:g[node]){
		if(!vis2[x]){
			dfs(x);
		}
	}
}
bool findLoop(int v)
{
	if(vis[v]==1)
		return 1;
	if(vis[v]==2)
		return 0;
	vis[v]=1;
	for(auto &it:g[v])
	{
		if(findLoop(it))
			return 1;
	}
	vis[v]=2;
	return 0;
}
int32_t main()
{

    fastio;
    int n,m;
    cin>>n>>m;
    for(int i=0;i<m;i++){
    	int a,b;
    	cin>>a>>b;
    	g[a].pb(b);
	}
	for(int i=0;i<=n;i++){
		vis[i]=0;
		vis2[i]=0;
	}
	int count =0 ;
	for(int i=1;i<=n;i++)
	{
		if(!vis2[i])
		{
			cnt=0;
			dfs(i);
	        ///cout<<cnt<<endl;
			if(findLoop(i)==1){

			}
			else{
				cnt--;
			}

			count+=cnt;
		}

	}

	cout<<count<<endl;

  return 0;

}

/*
                                                 -----*** SEGMENT TREE ***--------

int st[1000001];
void updateValue(int arr[], int ss, int se,
                 int index, int value, int node)
{
    if (index < ss || index > se)
    {
        cout << "Invalid Input" << endl;
        return;
    }

    if (ss == se)
    {
        arr[index] = value;
        st[node] = value;
    }
    else {
            int mid =  ss+(se-ss)/2;

            if (index >= ss && index <= mid)
                updateValue(arr,  ss, mid, index,
                            value, 2 * node + 1);
            else
                updateValue(arr,  mid + 1, se,
                            index, value, 2 * node + 2);

            st[node] = max(st[2 * node + 1],
                       st[2 * node + 2]);
    }
    return;
}
int RMQUtil( int ss, int se, int qs, int qe, int index)
{
    if (qs <= ss && qe >= se)
        return st[index];

    if (se < qs || ss > qe)
        return inf;

    int mid = ss+(se-ss)/2;
    return min(RMQUtil( ss, mid, qs, qe, 2*index+1),
                RMQUtil( mid+1, se, qs, qe, 2*index+2));
}

void constructSTUtil(int arr[], int ss, int se,
                                 int si)
{

    if (ss == se)
    {

        st[si] = arr[ss];
        return;

    }

    int mid = ss+(se-ss)/2;
    //cout<<mid<<endl;
    constructSTUtil(arr, ss , mid, 2*si +1);
	constructSTUtil(arr, mid+1, se,2*si +2);
	st[si]  = min(st[2*si+1],st[2*si+2]);

}
                                                     ----***SPARSE TABE***-----

O(1) query sparse matrix for Max/Min/GCD

int RMQ[20][N];

void precompute()
{
	for(int i=0;(1<<i)<N;i++)
	{
		for(int j=(1<<i);j<N && j<(1<<(i+1)); j++)
			floorlog[j]=i;
	}

	for(int i=n;i>=1;i--)
	{
		RMQ[0][i]=dp[i];
		int mxj=floorlog[n-i+1]; //2^j <= n-i+1
		int pw=1;
		for(int j=1;j<=mxj;j++)
		{
			RMQ[j][i]=max(RMQ[j-1][i], RMQ[j-1][i+pw]);
			pw<<=1;
		}
	}
}

int getMax(int L, int R)
{
	int k=floorlog[R-L+1]; //2^k <= R-L+1
	return max(RMQ[k][L], RMQ[k][R - (1<<k) +1]);
}

                                                      ----*** NCR ***-------
int nCr(int n, int r)
{
    long long p = 1, k = 1;
    if (n - r < r)
        r = n - r;
    if (r != 0) {
        while (r) {
            p *= n;
            k *= r;
            long long m = __gcd(p, k);
            p /= m;
            k /= m;
            n--;
            r--;
        }
	}
    else
        p = 1;
    return p;
}

                                           ------*** print divisors 1 to n ***-------
vector<int> printDivisors(int n)
{
    vector<int>v;
    for (int i=1; i<=sqrt(n); i++)
    {
        if (n%i == 0)
        {

            if (n/i == i)
                v.pb(i);

            else
                v.pb(i),v.pb(n/i);
        }
    }
    return v;
}

                                               ------*** isPrime ***--------------
//check if a number is prime   O(sqrt(n))
bool isPrime(int n)
{

    if (n <= 1)  return false;
    if (n <= 3)  return true;
    if (n%2 == 0 || n%3 == 0) return false;

    for (int i=5; i*i<=n; i=i+6)
        if (n%i == 0 || n%(i+2) == 0)
           return false;

    return true;
}

                                                ------*** prime factorization *** -------------
const int MAXN = 100000;
int spf[MAXN];
// spf contains smallest prime factor of n
void sieve()
{   spf[1] = 1;
    for (int i=2; i<MAXN; i++)
       spf[i] = i;

    for (int i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (int i=3; i*i<MAXN; i++)
    {

        if (spf[i] == i)
        {

            for (int j=i*i; j<MAXN; j+=i)
                if (spf[j]==j)
                    spf[j] = i;
        }
    }
}

 A O(log n) function returning primefactorization
vector<int> getFactorization(int x)
{
    vector<int> ret;
    while (x != 1)
    {
        ret.push_back(spf[x]);
        x = x / spf[x];
    }
    return ret;
}

                                                                GRAPHS

                                                 -----*** TOPOLOGICAL SORT ***--------

vector<int> order; //Stores the Topological Order
vector<int>g[10];
bool toposort(int n) //Returns 1 if there exists a toposort, 0 if there is a cycle
{
	queue<int> q;
	vector<int> indeg(n + 1, 0);
	for(int i = 1; i <= n; i++)
		for(auto &it:g[i])
			indeg[it]++;
	for(int i = 1; i <= n; i++)
	{
		if(!indeg[i])
			q.push(i);
	}
	while(!q.empty())
	{
		int u = q.front();
		q.pop();
		order.push_back(u);
		for(auto &v:g[u])
		{
			indeg[v]--;
			if(!indeg[v])
				q.push(v);
		}
	}
	return (order.size() == n);
}

                                                  -----***cycle detection in directed graph***-----
bool findLoop(int v)
{
	if(vis[v]==1)
		return 1;
	if(vis[v]==2)
		return 0;
	vis[v]=1;
	for(auto &it:g[v])
	{
		if(findLoop(it))
			return 1;
	}
	vis[v]=2;
	return 0;
}

bool checkLoop()
{
	fill(vis+1, vis+n+1, 0);
	for(int i=1;i<=n;i++)
	{
		if(!vis[i] && findLoop(i))
			return 1;
	}
	return 0;
}

                                                 -------*** FLOYD WARSHALL ***----
                                                 All Pairs Shortest Path problem in 0(n^3)

int dist[N][N];

void FloydWarshall()
{
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				dist[i][j]=min(dist[i][j], dist[i][k] + dist[k][j]);
}

                                                 ---**** Dijkstra with Path ***------

int arrival[N], departure[N], vis[N], parent[N];
vector<pair<int, int> > g[N];

void dijkstra(int source, int destination)
{
	for(int i=1;i<=n;i++)
	{
		arrival[i]=1e18;
		departure[i]=1e18;
		vis[i]=0;
	}
	arrival[source]=0;
	set<pair<int, int> > s;
	s.insert({0, source});
	while(!s.empty())
	{
		auto x = *(s.begin());
		s.erase(x);
		vis[x.second]=1;
		departure[x.second]=arrival[x.second];
		for(auto it:g[x.second])
		{
			if(arrival[it.first] > departure[x.second] + it.second)
			{
				s.erase({arrival[it.first], it.first});
				arrival[it.first]=departure[x.second] + it.second;
				s.insert({arrival[it.first], it.first});
				parent[it.first]=x.second;
			}
		}
	}
	if(!vis[destination])
	{
		cout<<"-1";
		return;
	}
	int v=destination;
	vector<int> ans;
	while(parent[v])
	{
		ans.push_back(v);
		v=parent[v];
	}
	ans.push_back(source);
	reverse(ans.begin(), ans.end());
	for(auto it:ans)
		cout<<it<<" ";
}

-------------------------------------------------------------------------------------------------------------------------------------
                                                -------*** Simple Dijkstra: ***--------

int arrival[N][N], departure[N][N];
vector<pair<int, int> > g[N];

void dijkstra(int source, int destination, int arrival[], int departure[])
{
	for(int i=1;i<=n;i++)
	{
		arrival[i]=inf;
		departure[i]=inf;
	}
	arrival[source]=0;
	set<pair<int, int> > s;
	s.insert({0, source});
	while(!s.empty())
	{
		auto x = *(s.begin());
		s.erase(x);
		departure[x.second]=arrival[x.second];
		for(auto it:g[x.second])
		{
			if(arrival[it.first] > departure[x.second] + it.second)
			{
				s.erase({arrival[it.first], it.first});
				arrival[it.first]=departure[x.second] + it.second;
				s.insert({arrival[it.first], it.first});
			}
		}
	}
}

                                                 --------*** KMP SEARCH ***-----

vector<int> prefix_function(string &s)
{
	int n = s.size();
	vector<int> pi(n);
	for(int i = 1; i < n; i++)
	{
		int j = pi[i - 1];
		while(j > 0 && s[i] != s[j])
			j = pi[j - 1];
		if (s[i] == s[j])
			j++;
		pi[i] = j;
	}
	return pi;
}

vector<int> find_occurences(string &text, string &pattern)
{
	string cur = pattern + '#' + text;
	int sz1 = text.size(), sz2 = pattern.size();
	vector<int> v;
	vector<int> lps = prefix_function(cur);
	for(int i = sz2 + 1; i <= sz1 + sz2; i++)
	{
		if(lps[i] == sz2)
			v.push_back(i - 2 * sz2);
	}
	return v;
}

  1. always check for unintialized vector.

  2. priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>> > pq; for djikstra

  3. check for constrained properly

  4. 10^8 operations per second

  5. Every even integer greater than 2 can be expressed as the sum of two primes.

  6. odd number can be expresses in sum of two prime number only if (n-2) is prime.

  7. always pass string vector everything  by reference else can get MLe TLE;

  8. An even digits of pallindromic number is always divided by 11 euler project 4th question..

  If n = 12, the time complexity can be O(n!).
  If n = 25, the time complexity can be O(2n).
  If n = 100, the time complexity can be O(n4).
  If n = 500, the time complexity can be O(n3).
  If n = 10^4, the time complexity can be O(n2).
  If n = 10^6, the time complexity can be O(n log n).
  If n = 10^8, the time complexity can be O(n).
  If n > 10^8, the time complexity can be O(log n) or O(1).

*/


// be name khoda
// never give up :))))
#include <bits/stdc++.h>
#define mp make_pair
#define f1 first
#define f2 second
#define int long long int
#define pb push_back
#define pii pair<ll ,ll>
#define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int mox=1e5+9;
vector <int> v[mox];
bool visit[mox];
bool ed[mox];
bool visit2[mox];
bool visit3[mox];
bool visit4[mox];
int u=0;
int p=0;
stack <int> s;
vector <int> w[mox];
int l=0;
vector <int> va[mox];
int lo[mox];
vector <int> ah;
bool visit5[mox];
void dfs(int x)
{
    visit[x]=1;
    for(int i:v[x])
    {
        if(visit[i]==0)
        {
            dfs(i);
        }
    }
    s.push(x);
}
void dfs2(int x)
{
    visit2[x]=1;
    u+=1;
    for(int i:v[x])
    {
        if(visit2[i]==0)
        {
            dfs2(i);
        }
        else if(ed[i]==0)
        {
            p=1;
        }
    }
    ed[x]=1;
    w[l].pb(x);
    lo[x]=l;
}
void dfs3(int x)
{
    u+=1;
    visit5[x]=1;
    for(int i:va[x])
    {
        if(visit5[i]==0&&ed[i]==0)
        {
            dfs3(i);
        }
        else if(ed[i]==1&&visit4[i]==0&&visit5[i]==1)
        {
            u+=1;
          visit4[i]=1;
          ah.pb(i);
        }
    }
    ed[x]=1;
}
main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0 ; i<m ; i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
    }
    int ans=0;
    for(int i=1 ; i<=n ; i++)
    {
        if(visit[i]==0)
        {
            dfs(i);
        }
    }
    while(s.empty()==0)
    {
        int v=s.top();
        s.pop();
        if(visit2[v]==0)
        {
            dfs2(v);
            if(p==1)
            ans+=1;
            p=0;
            ans+=u-1;
            u=0;
            l+=1;
        }
    }
    for(int i=l-1 ; i>=0 ; i--)
    {
        for(int j:w[i])
        {
            for(int t:v[j])
            {
                if(visit3[lo[t]]==0)
                {
                    visit3[lo[t]]=1;
                    va[i].pb(lo[t]);
                }
            }
        }
         for(int j:w[i])
        {
            for(int t:v[j])
            {
                if(visit3[lo[t]]==1)
                {
                    visit3[lo[t]]=0;
                }
            }
        }
    }
     for(int i=l-1 ; i>=0 ; i--)
    {
        if(visit5[i]==0)
        {
            dfs3(i);
            ans+=u-1;
            u=0;
            for(int j:ah)
                visit4[j]=0;
        }
    }
    cout<<ans;
}


#include <bits/stdc++.h>
#define mp make_pair
#define f1 first
#define f2 second
#define int long long
#define pb push_back
#define pii pair<int ,int>
#define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int const mox=1e5+9;
vector <int> v[mox];
int l;
bool visit[mox],visit2[mox];
int ed[mox];
vector <int> la[mox];
vector <int> vr[mox];
void dfs(int x)
{
    visit[x]=1;
    for(int i:v[x])
    {
        if(visit[i]==0)
            dfs(i);
    }
    la[l].pb(x);
}
bool dfs2(int x)
{
    visit2[x]=1;
    for(int i:vr[x])
    {
        if(visit2[i]==0)
            dfs2(i);
         if(ed[i]==0&&visit2[i]==1)
            return 0;
    }
    ed[x]=1;
    return 1;
}
main()
{
      ios
    int n,m;
    cin>>n>>m;
    for(int i=0 ; i<m ; i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
        v[b].pb(a);
        vr[a].pb(b);
    }
    for(int i=0 ; i<n ; i++)
    {
        if(visit[i]==0)
        {
            dfs(i);
            l+=1;
        }
    }
    int ans=0;
    for(int i=0 ; i<l ; i++)
    {   bool fo=0;
        for(int j:la[i])
        {
            if(visit2[j]==0)
            {
                if(dfs2(j)==0)
                    fo=1;
            }
        }
        if(fo==1)
            ans+=la[i].size();
        else
            ans+=la[i].size()-1;
    }
    cout<<ans;
}


        // be name khoda
        // never give up :))))
        #include <bits/stdc++.h>
        #define mp make_pair
        #define f1 first
        #define f2 second
        #define int long long int
        #define pb push_back
        #define pii pair<ll ,ll>
        #define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        using namespace std;
        string s;
        int n;
        void f(int x ,bool y)
        {
            if(x==1)
            {       if(y==1)
                     s+=49;
                cout<<s<<'\n';
                if(y==1)

                return ;
            }
            if(y==1)
                s+=x+48;
            f(x-1,1);
            f(x-1,0);
            s-=x+48;
        }
        main()
        {

            cin>>n;
            f(n,0);
            cout<<'s';
            f(n,1);

        }


        // be name khoda
        // never give up :))))
        #include <bits/stdc++.h>
        #define mp make_pair
        #define f1 first
        #define f2 second
        #define int long long int
        #define pb push_back
        #define pii pair<ll ,ll>
        #define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        using namespace std;
        const int mox=1e5+9;
        vector <int> v[mox];
        bool visit[mox];
        bool ed[mox];
        bool visit2[mox];
        bool visit3[mox];
        bool visit4[mox];
        int u=0;
        int p=0;
        stack <int> s;
        vector <int> w[mox];
        int l=0;
        vector <int> va[mox],vb[mox];
        int lo[mox];
        bool visit5[mox];
        void dfs(int x)
        {
            visit[x]=1;
            for(int i:v[x])
            {
                if(visit[i]==0)
                {
                    dfs(i);
                }
            }
            s.push(x);
        }
        void dfs2(int x)
        {
            visit2[x]=1;
            u+=1;
            for(int i:v[x])
            {
                if(visit2[i]==0)
                {
                    dfs2(i);
                }
                else if(ed[i]==0)
                {
                    p=1;
                }
            }
            ed[x]=1;
            w[l].pb(x);
            lo[x]=l;
        }
        void dfs3(int x)
        {
            u+=1;
            visit5[x]=1;
            for(int i:va[x])
            {
                if(visit5[i]==0)
                {
                    dfs3(i);
                }
            }
            s.push(x);
        }
        void dfs4(int x)
        {
            u+=1;
            visit4[x]=1;
            for(int i:vb[x])
            {
                if(visit4[i]==0)
                {
                   dfs4(i);
                }
            }
        }
        main()
        {
            int n,m;
            cin>>n>>m;
            for(int i=0 ; i<m ; i++)
            {
                int a,b;
                cin>>a>>b;
                v[a].pb(b);
            }
            int ans=0;
            for(int i=1 ; i<=n ; i++)
            {
                if(visit[i]==0)
                {
                    dfs(i);
                }
            }
            while(s.empty()==0)
            {
                int v=s.top();
                s.pop();
                if(visit2[v]==0)
                {
                    dfs2(v);
                    if(p==1)
                    ans+=1;
                    p=0;
                    ans+=u-1;
                    u=0;
                    l+=1;
                }
            }
            for(int i=l-1 ; i>=0 ; i--)
            {
                for(int j:w[i])
                {
                    for(int t:v[j])
                    {
                        if(visit3[lo[t]]==0)
                        {
                            visit3[lo[t]]=1;
                            va[i].pb(lo[t]);
                            vb[lo[t]].pb(i);

                        }
                    }
                }
                 for(int j:w[i])
                {
                    for(int t:v[j])
                    {
                        if(visit3[lo[t]]==1)
                        {
                            visit3[lo[t]]=0;
                        }
                    }
                }

            }
             for(int i=l-1 ; i>=0 ; i--)
            {
                if(visit5[i]==0)
                {
                    dfs3(i);
                    ans+=u-1;
                    u=0;
                }
            }
            while(s.empty()==0)
            {
                int v=s.top();
                s.pop();
                if(visit4[v]==0)
                {
                    dfs4(v);
                    ans+=u-1;
                    u=0;
                }
            }
            cout<<ans;
        }


        // be name khoda
        // never give up :))))
        #include <bits/stdc++.h>
        #define mp make_pair
        #define f1 first
        #define f2 second
        #define int long long int
        #define pb push_back
        #define pii pair<ll ,ll>
        #define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        using namespace std;
        const int mox=1e5+9;
        vector <int> v[mox];
        bool visit[mox];
        bool ed[mox];
        bool visit2[mox];
        bool visit3[mox];
        int u=0;
        int p=0;
        stack <int> s;
        vector <int> w[mox];
        int l=0;
        int lo[mox];
        int ans;
        int dad[mox];
        void dfs(int x)
        {
            visit[x]=1;
            for(int i:v[x])
            {
                if(visit[i]==0)
                {
                    dfs(i);
                }
            }
            s.push(x);
        }
        void dfs2(int x)
        {
            visit2[x]=1;
            u+=1;
            for(int i:v[x])
            {
                if(visit2[i]==0)
                {
                    dfs2(i);
                }
                else if(ed[i]==0)
                {
                    p=1;
                }
            }
            ed[x]=1;
            w[l].pb(x);
            lo[x]=l;
        }
        int fnd (int x)
        {
            if(dad[x]==0)
                return x;
            else
            {
                dad[x]=(fnd(dad[x]));
                return dad[x];
            }
        }
        int uoin(int x ,int y)
        {
           int h=fnd(x);
           int u=fnd(y);
           if(u!=h)
           {
               dad[u]=h;
               ans+=1;
           }
        }
        main()
        {
            int n,m;
            cin>>n>>m;
            for(int i=0 ; i<m ; i++)
            {
                int a,b;
                cin>>a>>b;
                v[a].pb(b);
            }
            for(int i=1 ; i<=n ; i++)
            {
                if(visit[i]==0)
                {
                    dfs(i);
                }
            }
            while(s.empty()==0)
            {
                int v=s.top();
                s.pop();
                if(visit2[v]==0)
                {
                    dfs2(v);
                    if(p==1)
                    ans+=1;
                    p=0;
                    ans+=u-1;
                    u=0;
                    l+=1;
                }
            }
            for(int i=l-1 ; i>=0 ; i--)
            {
                for(int j:w[i])
                {
                    visit3[lo[j]]=1;
                }
                for(int j:w[i])
                {
                    for(int t:v[j])
                    {
                        if(visit3[lo[t]]==0)
                        {
                            visit3[lo[t]]=1;
                            uoin(j,lo[t]);

                        }
                    }
                }
                 for(int j:w[i])
                {   visit3[lo[j]]=0;
                    for(int t:v[j])
                    {
                        if(visit3[lo[t]]==1)
                        {
                            visit3[lo[t]]=0;
                        }
                    }
                }

            }
              cout<<ans;
        }


// be name khoda
// never give up :))))
#include <bits/stdc++.h>
#define mp make_pair
#define f1 first
#define f2 second
#define int long long int
#define pb push_back
#define pii pair<ll ,ll>
#define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int mox=1e5+9;
vector <int> v[mox];
bool visit[mox];
bool ed[mox];
bool visit2[mox];
int u=0;
int p=0;
stack <int> s;
void dfs(int x)
{
    visit[x]=1;
    for(int i:v[x])
    {
        if(visit[i]==0)
        {
            dfs(i);
        }
    }
    s.push(x);
}
void dfs2(int x)
{
    visit2[x]=1;
    u+=1;
    for(int i:v[x])
    {
        if(visit2[i]==0)
        {
            dfs2(i);
        }
        else if(ed[i]==0)
        {
            p=1;
        }
    }
    ed[x]=1;
}
main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0 ; i<m ; i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
    }
    int ans=0;
    for(int i=1 ; i<=n ; i++)
    {
        if(visit[i]==0)
        {
            dfs(i);
        }
    }
    while(s.empty()==0)
    {
        int v=s.top();
        s.pop();
        if(visit2[v]==0)
        {
            dfs2(v);
            if(p==1)
            ans+=1;
            p=0;
            ans+=u-1;
            u=0;
        }
    }
    cout<<ans;
}


    // be name khoda
    // never give up :))))
    #include <bits/stdc++.h>
    #define mp make_pair
    #define f1 first
    #define f2 second
    #define int long long int
    #define pb push_back
    #define pii pair<ll ,ll>
    #define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    using namespace std;
    const int mox=1e5+9;
    vector <int> v[mox];
    bool visit[mox];
    bool ed[mox];
    bool visit2[mox];
    bool visit3[mox];
    bool visit4[mox];
    int u=0;
    int p=0;
    stack <int> s;
    vector <int> w[mox];
    int l=0;
    vector <int> va[mox];
    int lo[mox];
    vector <int> ah;
    bool visit5[mox];
    bool ed2[mox];
    void dfs(int x)
    {
        visit[x]=1;
        for(int i:v[x])
        {
            if(visit[i]==0)
            {
                dfs(i);
            }
        }
        s.push(x);
    }
    void dfs2(int x)
    {
        visit2[x]=1;
        u+=1;
        for(int i:v[x])
        {
            if(visit2[i]==0)
            {
                dfs2(i);
            }
            else if(ed[i]==0)
            {
                p=1;
            }
        }
        ed[x]=1;
        w[l].pb(x);
        lo[x]=l;
    }
    void dfs3(int x)
    {
        visit4[x]=1;
        u+=1;
        ah.pb(x);
        visit5[x]=1;
        for(int i:va[x])
        {
            if(visit5[i]==0&&ed2[i]==0)
            {
                dfs3(i);
            }
            else if(ed2[i]==1&&visit4[i]==0&&visit5[i]==1)
            {

                u+=1;
              visit4[i]=1;
              ah.pb(i);
            }
        }
        ed2[x]=1;
    }
    main()
    {
        int n,m;
        cin>>n>>m;
        for(int i=0 ; i<m ; i++)
        {
            int a,b;
            cin>>a>>b;
            v[a].pb(b);
        }
        int ans=0;
        for(int i=1 ; i<=n ; i++)
        {
            if(visit[i]==0)
            {
                dfs(i);
            }
        }
        while(s.empty()==0)
        {
            int v=s.top();
            s.pop();
            if(visit2[v]==0)
            {
                dfs2(v);
                if(p==1)
                ans+=1;
                p=0;
                ans+=u-1;
                u=0;
                l+=1;
            }
        }
        for(int i=l-1 ; i>=0 ; i--)
        {
            for(int j:w[i])
            {
                for(int t:v[j])
                {
                    if(visit3[lo[t]]==0)
                    {
                        visit3[lo[t]]=1;
                        va[i].pb(lo[t]);

                    }
                }
            }
             for(int j:w[i])
            {
                for(int t:v[j])
                {
                    if(visit3[lo[t]]==1)
                    {
                        visit3[lo[t]]=0;
                    }
                }
            }

        }
         for(int i=0 ; i<l ; i++)
        {
            if(visit5[i]==0)
            {
                dfs3(i);
                ans+=u-1;
                u=0;
                for(int j:ah)
                    visit4[j]=0;
                    ah.clear();
            }
        }
        cout<<ans;
    }


// be name khoda
// never give up :))))
#include <bits/stdc++.h>
#define mp make_pair
#define f1 first
#define f2 second
#define int long long int
#define pb push_back
#define pii pair<ll ,ll>
#define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int mox=1e5+9;
vector <int> v[mox];
bool visit[mox];
bool ed[mox];
bool visit2[mox];
bool visit3[mox];
bool visit4[mox];
int u=0;
int p=0;
stack <int> s;
vector <int> w[mox];
int l=0;
vector <int> va[mox];
int lo[mox];
vector <int> ah;
void dfs(int x)
{
    visit[x]=1;
    for(int i:v[x])
    {
        if(visit[i]==0)
        {
            dfs(i);
        }
    }
    s.push(x);
}
void dfs2(int x)
{
    visit2[x]=1;
    u+=1;
    for(int i:v[x])
    {
        if(visit2[i]==0)
        {
            dfs2(i);
        }
        else if(ed[i]==0)
        {
            p=1;
        }
    }
    ed[x]=1;
    w[l].pb(x);
    lo[x]=l;
}
void dfs3(int x)
{
    visit4[x]=1;
    u+=1;
    ah.pb(x);
    for(int i:va[x])
    {
        if(visit4[i]==0&&ed[i]==0)
        {
            dfs3(i);
        }
        else if(ed[i]==1&&visit4[i]==0)
        {
            u+=1;
          visit4[i]=1;
          ah.pb(i);
        }
    }
    ed[x]=1;
}
main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0 ; i<m ; i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
    }
    int ans=0;
    for(int i=1 ; i<=n ; i++)
    {
        if(visit[i]==0)
        {
            dfs(i);
        }
    }
    while(s.empty()==0)
    {
        int v=s.top();
        s.pop();
        if(visit2[v]==0)
        {
            dfs2(v);
            if(p==1)
            ans+=1;
            p=0;
            ans+=u-1;
            u=0;
            l+=1;
        }
    }
    for(int i=l-1 ; i>=0 ; i--)
    {
        for(int j:w[i])
        {
            for(int t:v[j])
            {
                if(visit3[lo[t]]==0)
                {
                    visit3[lo[t]]=1;
                    va[i].pb(lo[t]);
                }
            }
        }
         for(int j:w[i])
        {
            for(int t:v[j])
            {
                if(visit3[lo[t]]==1)
                {
                    visit3[lo[t]]=0;
                }
            }
        }
    }
     for(int i=l-1 ; i>=0 ; i--)
    {
        if(visit4[i]==0)
        {
            dfs3(i);
            ans+=u-1;
            u=0;
            for(int j:ah)
                visit4[j]=0;
        }
    }
    cout<<ans;
}


#include <bits/stdc++.h>
#define mp make_pair
#define f1 first
#define f2 second
#define int long long
#define pb push_back
#define pii pair<int ,int>
#define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int const mox=1e5+9;
vector<int> vr[100009];
vector <int> vb[100009];
bool visit[100009],visit2[mox],visit3[mox],visit4[mox];
stack <int> s;
vector <int> mo[mox];
int ma=0;
int me[mox];
vector <int> va[mox];
void dfs(int x)
{
    visit[x]=1;
    for(int i:vr[x])
    {
        if(visit[i]==0)
        {
            dfs(i);
        }
    }
    s.push(x);
}
void dfs2(int x)
{
    visit2[x]=1;
    for(int i:vb[x])
    {
        if(visit2[i]==0)
        {
            dfs2(i);
        }
    }
    mo[ma].pb(x);
    me[x]=ma;
}
void dfs3(int x)
{

            visit4[x]=1;
    for(int i:va[x])
         {
                if(visit4[i]==0)
           {
                    dfs3(i);
           }
         }
}
main()
{
      ios
     int n;
     cin>>n;
     int m;
     cin>>m;
     for(int i=0 ; i<m ; i++)
     {
         int a,b;
         cin>>a>>b;
         vr[a].pb(b);
         vb[b].pb(a);
     }
     for(int i=0 ; i<n ; i++)
     {
         if(visit[i+1]==0)
         {
             dfs(i+1);
         }
     }
     int ans=0;
     while(s.empty()==0)
     {
         int v=s.top();
         s.pop();
         if(visit2[v]==0)
         {
             dfs2(v);
            if(mo[ma].size()!=1)
            ans+=mo[ma].size();
                  ma+=1;
         }
     }
              for(int i=ma-1 ; i>=0 ; i--)
            {
                for(int j:mo[i])
                    visit3[me[j]]=1;
                for(int j:mo[i])
                {
                    for(int t:vr[j])
                    {
                        if(visit3[me[t]]==0)
                        {
                            visit3[me[t]]=1;
                            va[me[t]].pb(i);
                            va[i].pb(me[t]);
                        }
                    }
                }
                 for(int j:mo[i])
                {   visit3[me[j]]=0;
                    for(int t:vr[j])
                    {
                        if(visit3[me[t]]==1)
                        {
                            visit3[me[t]]=0;
                        }
                    }
                }

            }
            ans+=ma;
          for(int i=0 ; i<ma ; i++)
          {
              if(visit4[i]==0)
              {
                  dfs3(i);
                  ans-=1;
              }
          }
            cout<<ans;
        }


    // be name khoda
    // never give up :))))
    #include <bits/stdc++.h>
    #define mp make_pair
    #define f1 first
    #define f2 second
    #define int long long int
    #define pb push_back
    #define pii pair<ll ,ll>
    #define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    using namespace std;
    const int mox=1e5+9;
    vector <int> v[mox];
    bool visit[mox];
    bool ed[mox];
    bool visit2[mox];
    bool visit3[mox];
    bool visit4[mox];
    int u=0;
    int p=0;
    stack <int> s;
    vector <int> w[mox];
    int l=0;
    vector <int> va[mox];
    int lo[mox];
    vector <int> ah;
    bool visit5[mox];
    bool ed2[mox];
    void dfs(int x)
    {
        visit[x]=1;
        for(int i:v[x])
        {
            if(visit[i]==0)
            {
                dfs(i);
            }
        }
        s.push(x);
    }
    void dfs2(int x)
    {
        visit2[x]=1;
        u+=1;
        for(int i:v[x])
        {
            if(visit2[i]==0)
            {
                dfs2(i);
            }
            else if(ed[i]==0)
            {
                p=1;
            }
        }
        ed[x]=1;
        w[l].pb(x);
        lo[x]=l;
    }
    void dfs3(int x)
    {
        visit4[x]=1;
        u+=1;
        ah.pb(x);
        visit5[x]=1;
        for(int i:va[x])
        {
            if(visit5[i]==0&&ed2[i]==0)
            {
                dfs3(i);
            }
            else if(ed2[i]==1&&visit4[i]==0&&visit5[i]==1)
            {

                u+=1;
              visit4[i]=1;
              ah.pb(i);
            }
        }
        ed2[x]=1;
    }
    main()
    {
        int n,m;
        cin>>n>>m;
        for(int i=0 ; i<m ; i++)
        {
            int a,b;
            cin>>a>>b;
            v[a].pb(b);
        }
        int ans=0;
        for(int i=1 ; i<=n ; i++)
        {
            if(visit[i]==0)
            {
                dfs(i);
            }
        }
        while(s.empty()==0)
        {
            int v=s.top();
            s.pop();
            if(visit2[v]==0)
            {
                dfs2(v);
                if(p==1)
                ans+=1;
                p=0;
                ans+=u-1;
                u=0;
                l+=1;
            }
        }
        for(int i=l-1 ; i>=0 ; i--)
        {
            for(int j:w[i])
            {
                for(int t:v[j])
                {
                    if(visit3[lo[t]]==0)
                    {
                        visit3[lo[t]]=1;
                        va[i].pb(lo[t]);

                    }
                }
            }
             for(int j:w[i])
            {
                for(int t:v[j])
                {
                    if(visit3[lo[t]]==1)
                    {
                        visit3[lo[t]]=0;
                    }
                }
            }

        }
         for(int i=l-1 ; i>=0 ; i--)
        {
            if(visit5[i]==0)
            {
                dfs3(i);
                ans+=u-1;
                u=0;
                for(int j:ah)
                    visit4[j]=0;
                    ah.clear();
            }
        }
        cout<<ans;
    }


        // never give up :))))
        #include <bits/stdc++.h>
        #define mp make_pair
        #define f1 first
        #define f2 second
        #define int long long int
        #define pb push_back
        #define pii pair<ll ,ll>
        #define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
        using namespace std;
        const int mox=1e5+9;
        vector <int> v[mox];
        bool visit[mox];
        bool ed[mox];
        bool visit2[mox];
        bool visit3[mox];
        bool visit4[mox];
        int u=0;
        int p=0;
        stack <int> s;
        vector <int> w[mox];
        int l=0;
        vector <int> va[mox];
        int lo[mox];
        vector <int> ah;
        bool visit5[mox];
        bool ed2[mox];
        void dfs(int x)
        {
            visit[x]=1;
            for(int i:v[x])
            {
                if(visit[i]==0)
                {
                    dfs(i);
                }
            }
            s.push(x);
        }
        void dfs2(int x)
        {
            visit2[x]=1;
            u+=1;
            for(int i:v[x])
            {
                if(visit2[i]==0)
                {
                    dfs2(i);
                }
                else if(ed[i]==0)
                {
                    p=1;
                }
            }
            ed[x]=1;
            w[l].pb(x);
            lo[x]=l;
        }
        void dfs3(int x)
        {

            visit4[x]=1;
            for(int i:va[x])
            {
                if(visit4[i]==0)
                {
                    dfs3(i);
                }
            }
        }
        main()
        {
            int n,m;
            cin>>n>>m;
            for(int i=0 ; i<m ; i++)
            {
                int a,b;
                cin>>a>>b;
                v[a].pb(b);
            }
            int ans=0;
            for(int i=1 ; i<=n ; i++)
            {
                if(visit[i]==0)
                {
                    dfs(i);
                }
            }
            while(s.empty()==0)
            {
                int v=s.top();
                s.pop();
                if(visit2[v]==0)
                {
                    dfs2(v);
                    if(p==1)
                    ans+=1;
                    p=0;
                    ans+=u-1;
                    u=0;
                    l+=1;
                }
            }
            for(int i=l-1 ; i>=0 ; i--)
            {
                for(int j:w[i])
                    visit3[lo[j]]=1;
                for(int j:w[i])
                {
                    for(int t:v[j])
                    {
                        if(visit3[lo[t]]==0)
                        {
                            visit3[lo[t]]=1;
                            va[lo[t]].pb(i);
                            va[i].pb(lo[t]);
                        }
                    }
                }
                 for(int j:w[i])
                {   visit3[lo[j]]=0;
                    for(int t:v[j])
                    {
                        if(visit3[lo[t]]==1)
                        {
                            visit3[lo[t]]=0;
                        }
                    }
                }

            }
            ans+=l;
          for(int i=0 ; i<l ; i++)
          {
              if(visit4[i]==0)
              {
                  dfs3(i);
                  ans-=1;
              }
          }
            cout<<ans;
        }


// be name khoda
// never give up :))))
#include <bits/stdc++.h>
#define mp make_pair
#define f1 first
#define f2 second
#define int long long int
#define pb push_back
#define pii pair<ll ,ll>
#define ios  ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
const int mox=1e5+9;
vector <int> v[mox];
bool visit[mox];
bool ed[mox];
bool visit2[mox];
int u=0;
int p=0;
stack <int> s;
void dfs(int x)
{
    visit[x]=1;
    u+=1;
    for(int i:v[x])
    {
        if(visit[i]==0)
        {
            dfs(i);
        }
    }
    s.push(x);
}
void dfs2(int x)
{
    visit2[x]=1;
    for(int i:v[x])
    {
        if(visit2[i]==0)
        {
            dfs2(i);
        }
        else if(ed[i]==0)
        {
            p=1;
        }
    }
    ed[x]=1;
}
main()
{
    int n,m;
    cin>>n>>m;
    for(int i=0 ; i<m ; i++)
    {
        int a,b;
        cin>>a>>b;
        v[a].pb(b);
    }
    int ans=0;
    for(int i=1 ; i<=n ; i++)
    {
        if(visit[i]==0)
        {
            dfs(i);
            ans+=u-1;
            u=0;
        }
    }
    while(s.empty()==0)
    {
        int v=s.top();
        s.pop();
        if(visit2[v]==0)
        {
            dfs2(v);
            if(p==1)
            ans+=1;
            p=0;
        }
    }
    cout<<ans;
}