#include <bits/stdc++.h>
#include <unordered_map>
#include <unordered_set>
using namespace std;
#define endl "\n"
#define ll long long
#define sz(s) (int)(s.size())
#define INF 0x3f3f3f3f3f3f3f3fLL
#define all(v) v.begin(),v.end()
#define watch(x) cout<<(#x)<<" = "<<x<<endl
const int dr[] { -1, -1, 0, 1, 1, 1, 0, -1 };
const int dc[] { 0, 1, 1, 1, 0, -1, -1, -1 };
#if __cplusplus >= 201402L
template<typename T>
vector<T> create(size_t n) {
	return vector<T>(n);
}
template<typename T, typename ... Args>
auto create(size_t n, Args ... args) {
	return vector<decltype(create<T>(args...))>(n, create<T>(args...));
}
#endif
void run() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);
#ifndef ONLINE_JUDGE
	freopen("input.in", "r", stdin);
#else
	//freopen("groups.in", "r", stdin);
#endif
}

const int N = 2009;
vector<int> adj[N];
bitset<N> vis;
void dfs(int node) {
	vis[node] = true;
	for (int ch : adj[node])
		if (!vis[ch])
			dfs(ch);
}
int main() {
	run();
	int n, m;
	cin >> n >> m;
	while (m--) {
		int u, v;
		cin >> u >> v;
		adj[u].push_back(v);
	}
	int cnt = 0;
	for (int i = 1; i <= n; i++) {
		vis = bitset<N>();
		dfs(i);
		cnt += vis.count();
	}
	cout << cnt << endl;
}

/*** keep hungry and calm CoolGuang!  ***/
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define dl(x) printf("%lld\n",x);
#define di(x) printf("%d\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18+7;
const ll maxn = 1e6+700;
const ll mod= 100003;
const double eps = 1e-9;
const double PI = acos(-1);
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
struct Matrix{
    int sz;
    ll a[3][3];
    void clr(int x){
        sz = x;
        for(int k=0;k<sz;k++)
            for(int i=0;i<sz;i++)
                a[i][k] = 0;
    }
    Matrix operator*(const Matrix b) const{
        Matrix res;
        res.clr(sz);
        for(int i=0;i<sz;i++){
            for(int j=0;j<sz;j++){
                for(int k=0;k<sz;k++){
                    res.a[i][j] += (b.a[i][k]*a[k][j]);
                }
            }
        }
        return res;
    }
    Matrix operator*=(const Matrix b){
        return *this = *this*b;
    }
    Matrix operator^(ll b){
        Matrix ans;ans.clr(sz);
        for(int i=0;i<ans.sz;i++) ans.a[i][i] = 1;
        while(b){
            if(b&1) ans *= *this;
            b/=2;*this *= *this;
        }return ans;
    }
}q[maxn],num[maxn],a1,a2,a3,a4;
void down(int k){
	q[k<<1] *= q[k];
	q[k<<1|1] *= q[k];
	q[k].clr(3);
	for(int j=0;j<3;j++) q[k].a[j][j] = 1;
}
void build(int k,int l,int r){
	q[k].clr(3);
	for(int j=0;j<3;j++) q[k].a[j][j] = 1;
	if(l == r) return;
	int mid = (l+r)/2;
	build(k<<1,l,mid);
	build(k<<1,mid+1,r);
}

Matrix Query(int k,int l,int r,int pos){
	if(l == r) return q[k];
	down(k);
	int mid = (l+r)/2;
	if(pos <= mid) return Query(k<<1,l,mid,pos);
	return Query(k<<1|1,mid+1,r,pos);
}
vector< pair<int,int> >v[maxn];

struct node{
	int x,y;
}qr[maxn];

pair<ll,ll>res[maxn];


int main(){
	a1.a[0][0] = 0;a1.a[0][1] = 1;a1.a[0][2] = 0;
	a1.a[1][0] = -1;a1.a[1][1] = 0;a1.a[1][2] = 0;
	a1.a[2][0] = 0;a1.a[2][1] = 0;a1.a[2][2] = 1;

	a2.a[0][0] = 0;a2.a[0][1] = -1;a2.a[0][2] = 0;
	a2.a[1][0] = 1;a2.a[1][1] = 0;a2.a[1][2] = 0;
	a2.a[2][0] = 0;a2.a[2][1] = 0;a2.a[2][2] = 1;

	a3.a[0][0] = -1;a3.a[0][1] = 0;a3.a[0][2] = 0;
	a3.a[1][0] = 0;a3.a[1][1] = 1;a3.a[1][2] = 0;
	a3.a[2][0] = 0;a3.a[2][1] = 0;a3.a[2][2] = 1;

	a4.a[0][0] = 1;a4.a[0][1] = 0;a4.a[0][2] = 0;
	a4.a[1][0] = 0;a4.a[1][1] = -1;a4.a[1][2] = 0;
	a4.a[2][0] = 0;a4.a[2][1] = 0;a4.a[2][2] = 1;
	read(n);
	for(int i=1;i<=n;i++){
		num[i].clr(3);
		read(num[i].a[0][0]);
		read(num[i].a[1][0]);
		num[i].a[2][0] = 1;
	}
	read(m);
	for(int i=1;i<=m;i++){
		read(qr[i].x);
		if(qr[i].x>2) read(qr[i].y);
	}
	read(p);
	for(int i=1;i<=p;i++){
		int x,y;read(x);read(y);
		v[x].push_back({y,i});
	}
	build(1,1,n);
	for(int k=0;k<=m;k++){
		if(k){
			if(qr[k].x == 1) q[1] *= a1;
			else if(qr[k].x == 2) q[1] *= a2;
			else if(qr[k].x == 3){
				a3.a[0][2] = 2*qr[k].y;
				q[1] *= a3;
			}else{
				a4.a[1][2] = 2*qr[k].y;
				q[1] *= a4;
			}
		}
		for(auto x:v[k]){
			//debug(x.first);
			Matrix tt = num[x.first]*q[1];
			res[x.second] = {tt.a[0][0],tt.a[1][0]};
		}

	}
	for(int i=1;i<=p;i++)
		printf("%lld %lld\n",res[i].first,res[i].second);
    return 0;

}
/***
10
0 1 0 1 0 1 0 1 0 1
4
1 3
1 4
2 3n
2 7
***/
