#include <bits/stdc++.h>
using namespace std;
#define inf 1000000001
typedef long l;
typedef long long ll;
const ll INF = 1e18L + 5;
# define MOD 1000000007
# define PI 3.14
#define vi vector<int>
#define vl vector<l>
#define vll vector<ll>
#define pb push_back
#define pob pop_back
#define f first
#define s second
#define ml map<l,l>
#define mll map<ll,ll>
#define mcl map<char,ll>
# define umll unordered_map<ll,ll,custom_hash>
# define umcl unordered_map<char,l>
#define pll pair<ll,ll>
#define mp make_pair 
# define forl(i,range) for(l i=0;i<range;i++)
# define forll(i,range) for(ll i=0;i<range;i++)
// int ans=upper_bound(start,end ,value)-start;
// auto itr=uper_bound(start,end ,value)-vector.begin();
// for (ll i = 0; i < s1.size() && j < s2.size(); i++) if (s1[i]==s2[j]) j++;//subsequence
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        // http://xorshift.di.unimi.it/splitmix64.c
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
 
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = std::chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};
ll myceil(ll num,ll den)
{
    if ((num >= 0 and den > 0) or ( num <= 0 and den < 0))
        return num%den == 0 ? num/den : num/den + 1;
    return num / den;
}
ll myfloor(ll num,ll den)
{
    if ((num >= 0 and den > 0) or ( num <= 0 and den < 0))
        return num%den == 0 ? num/den : num/den;
    int ans = num / den;
    return num % den == 0 ? ans : ans - 1;
}
void dfs(vector<vector<ll>> &v, vector<ll> &df, vll &seen, ll i){ //Also outputed resultant dfs
 
    df.pb(i);
    for(ll j=0; j<v[i].size(); j++){
          if(seen[v[i][j]]==0){seen[v[i][j]]=seen[i]; dfs(v, df, seen, v[i][j]);}
     }
}
/* ************************************************************************************************************** */
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
   ll n,m;
   cin>>n>>m;
   vector<vll>v(n);
   forll(i,m){
       ll x,y;
       cin>>x>>y;
       v[x-1].pb(y-1);
   }
   ll ans=0;
   forll(i,n){
       vll seen(n);vll df;
       seen[i]=1;
       dfs(v,df,seen,i);
       ans+=df.size();
   }
   cout<<ans<<"\n";
}

#include<bits/stdc++.h>

using namespace std;
using ll = long long;
using vs = vector<string>;
using vi = vector<int>;
using vl = vector<ll>;
using vb = vector<bool>;
using pi = pair<int, int>;
using pl = pair<ll, ll>;
using vpi = vector<pair<int, int>>;
using vpl = vector<pair<ll, ll>>;
using ld = double;

#define	sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
#define ins insert
#define nl "\n"

const ll MOD = 998244353;


ll add(ll x, ll y) {
	x += y;
	if (x >= MOD) return x - MOD;
	return x;
}
ll sub(ll x, ll y) {
	x -= y;
	if (x < 0) return x + MOD;
	return x;
}
ll mult(ll x, ll y) {
	return (x * y) % MOD;
}

template<typename T> T signum(T a) { 
    return (a > 0) - (a < 0); 
}

template<typename T> T cmp(T a, T b) { 
    return signum(a-b); 
}

template<typename T> bool mins(T& lhs , T& rhs) {
    if (rhs < lhs) {
        lhs = rhs;
        return true;
    }

    return false;
}

template<typename T> bool maxs(T& lhs , T& rhs) {
    if (rhs > lhs) {
        lhs = rhs;
        return true;
    }

    return false;
}


const int MAX = INT_MAX;

void gks(int tc) {
    printf("Case #%d: ", tc);
};


vector<bool> v;
ll ans = 0;
vector<vector<int>> g;

void dfs(int r) {
    v[r] = true;
    ans += 1;
    for (auto neigh : g[r]) {
        if (!v[neigh]) {
            dfs(neigh);
        }
    }
}


int main() {
    int n, m;
    cin>>n>>m;
    g.resize(n);
    for (int i = 0;i < m;++i) {
        int u, v;
        cin>>u>>v;
        --u, --v;
        g[u].push_back(v);
    }

    v.resize(n);

    
    for (int i =0 ;i < n;++i) {
        dfs(i);
        fill(all(v), false);
    }


    cout<<ans<<nl;
}
