#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cctype>
#include <numeric>
#include <queue>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#define FOR(i,s,e) for(int i=(s);i<(int)(e);i++)
#define FOE(i,s,e) for(int i=(s);i<=(int)(e);i++)
#define ALL(x) (x).begin(), (x).end()
#define CLR(s) memset(s,0,sizeof(s))
#define PB push_back
#define ITER(v)      __typeof((v).begin())
#define FOREACH(i,v) for(ITER(v) i=(v).begin();i!=(v).end();i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef map<int,int> mii;
typedef vector<int> vi;
#define x first
#define y second

////////////////////////////////////////////////
// Modular Arithmetic (fixed MOD)

//const LL  MOD = 1000000009;
LL MOD;

LL Egcd(LL a, LL b, LL &x, LL &y){      // g = ax + by
        LL d;
        if(b==0){x=1;y=0;return a;}
        d=Egcd(b,a%b,y,x);
        y-=a/b*x; return d;
}

LL Inv(LL u, LL MOD) {  // u^-1 (mod MOD)
        LL x, y, g=Egcd(u,MOD,x,y);
        if (g!=1) return -1;    // no inverse
        return (x%MOD+MOD)%MOD;
}

// UPD: 2011-09-28 - add some practical speedup
LL ModNor(LL x){ if(x<0) x=(x%MOD+MOD); return x>=MOD?x%MOD:x; }
LL ModAdd(LL x,LL y){ return ModNor(ModNor(x)+ModNor(y)); }
LL ModSub(LL x,LL y){ return ModAdd(x,-y); }
LL ModMul(LL x,LL y){ LL res=ModNor(x)*ModNor(y); if(res>=MOD) res%=MOD; return res; }

LL ModPow(LL a, LL n) {
        LL z=1, m=a;
        for (;n;n>>=1,m=m*m%MOD)
                if (n&1) z=z*m%MOD;
        return z;
}

/////////////////////////////////////////////////////
// GCD and LCM

LL Gcd(LL x, LL y) { return x ? Gcd(y%x, x) : y; }
LL Lcm(LL x, LL y) { return x / Gcd(x,y) * y; }

////////////////////////////////////////////////
// 2011-08-14 - avoid overflow

LL ModMul2(LL x, LL y) {
        LL ans = 0;
        for(; y; y>>=1, x<<=1, x%=MOD)
                if (y&1)
                        ans = ModAdd(ans, x);
        return ans;
}

////////////////////////////////////////////////

const int N = 666;
vector<LL> adj[N], back[N];
int n, m;

void ae(int x, int y) {
        adj[x].PB(y);
        back[y].PB(x);
}

LL dp[N][N];
int a[N], b[N]; // src, sink
int na = 0, nb = 0;
mii ma, mb;

LL go(int x, int y) {
        LL &res = dp[x][y];
        if (res != -1) return res;
        if(x==y) return res = 1LL;
        res = 0;
        FOREACH(it, back[y])
                res = ModAdd(res, go(x, *it));
        return res;
}

int main() {
        //cin >> n >> m >> MOD;
        scanf("%d%d%I64d", &n, &m, &MOD);
        FOR(j, 0, m) {
                int x, y; scanf("%d%d", &x, &y); //cin >> x >> y;
                ae(x, y);
        }

        FOE(i, 1, n) {
                if (back[i].size()==0) a[na++] = i;
                if (adj[i].size() ==0) b[nb++] = i;
        }

        memset(dp, -1, sizeof(dp));
        FOR(i, 0, na) FOR(j, 0, nb) go(a[i], b[j]);

        LL mat[na][nb];
        FOR(i, 0, na) FOR(j, 0, nb) {
                mat[i][j] = dp[ a[i] ][ b[j] ];
        }

        int sgn = 1;
        FOR(i, 0, na) {
                int r = i;
                while (r < na && mat[r][i] == 0) ++r;
                if (r == na) { cout << 0 << endl; return 0; }
                if (r != i) {
                        sgn *= -1;
                        FOR(j, 0, nb) swap(mat[r][j], mat[i][j]);
                }
                LL iv = Inv(mat[i][i], MOD);
                FOR(k, i+1, na) {
                        LL mul = ModMul(iv, mat[k][i]);
                        FOR(j, i, nb) mat[k][j] = ModSub(mat[k][j], ModMul(mat[i][j], mul));
                }
        }

        LL res = ModNor(sgn);
        FOR(i, 0, na) res = ModMul(res, mat[i][i]);

        cout << res << endl;

        return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cctype>
#include <numeric>
#include <queue>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#define FOR(i,s,e) for(int i=(s);i<(int)(e);i++)
#define FOE(i,s,e) for(int i=(s);i<=(int)(e);i++)
#define ALL(x) (x).begin(), (x).end()
#define CLR(s) memset(s,0,sizeof(s))
#define PB push_back
#define ITER(v)      __typeof((v).begin())
#define FOREACH(i,v) for(ITER(v) i=(v).begin();i!=(v).end();i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef map<int,int> mii;
typedef vector<int> vi;
#define x first
#define y second

////////////////////////////////////////////////
// Modular Arithmetic (fixed MOD)

//const LL  MOD = 1000000009;
LL MOD;

LL Egcd(LL a, LL b, LL &x, LL &y){      // g = ax + by
        LL d;
        if(b==0){x=1;y=0;return a;}
        d=Egcd(b,a%b,y,x);
        y-=a/b*x; return d;
}

LL Inv(LL u, LL MOD) {  // u^-1 (mod MOD)
        LL x, y, g=Egcd(u,MOD,x,y);
        if (g!=1) return -1;    // no inverse
        return (x%MOD+MOD)%MOD;
}

// UPD: 2011-09-28 - add some practical speedup
LL ModNor(LL x){ if(x<0) x=(x%MOD+MOD); return x>=MOD?x%MOD:x; }
LL ModAdd(LL x,LL y){ return ModNor(ModNor(x)+ModNor(y)); }
LL ModSub(LL x,LL y){ return ModAdd(x,-y); }
LL ModMul(LL x,LL y){ LL res=ModNor(x)*ModNor(y); if(res>=MOD) res%=MOD; return res; }

LL ModPow(LL a, LL n) {
        LL z=1, m=a;
        for (;n;n>>=1,m=m*m%MOD)
                if (n&1) z=z*m%MOD;
        return z;
}

/////////////////////////////////////////////////////
// GCD and LCM

LL Gcd(LL x, LL y) { return x ? Gcd(y%x, x) : y; }
LL Lcm(LL x, LL y) { return x / Gcd(x,y) * y; }

////////////////////////////////////////////////
// 2011-08-14 - avoid overflow

LL ModMul2(LL x, LL y) {
        LL ans = 0;
        for(; y; y>>=1, x<<=1, x%=MOD)
                if (y&1)
                        ans = ModAdd(ans, x);
        return ans;
}

////////////////////////////////////////////////

const int N = 666;
vector<LL> adj[N], back[N];
int n, m;

void ae(int x, int y) {
        adj[x].PB(y);
        back[y].PB(x);
}

LL dp[N][N];
int a[N], b[N]; // src, sink
int na = 0, nb = 0;
mii ma, mb;

LL go(int x, int y) {
        LL &res = dp[x][y];
        if (res != -1) return res;
        if(x==y) return res = 1LL;
        res = 0;
        FOREACH(it, back[y])
                res = ModAdd(res, go(x, *it));
        return res;
}

int main() {
        cin >> n >> m >> MOD;
        FOR(j, 0, m) {
                int x, y; cin >> x >> y;
                ae(x, y);
        }

        FOE(i, 1, n) {
                if (back[i].size()==0) a[na++] = i;
                if (adj[i].size() ==0) b[nb++] = i;
        }

        memset(dp, -1, sizeof(dp));
        FOR(i, 0, na) FOR(j, 0, nb) go(a[i], b[j]);

        LL mat[na][nb];
        FOR(i, 0, na) FOR(j, 0, nb) {
                mat[i][j] = dp[ a[i] ][ b[j] ];
        }

        int sgn = 1;
        FOR(i, 0, na) {
                int r = i;
                while (r < na && mat[r][i] == 0) ++r;
                if (r == na) { cout << 0 << endl; return 0; }
                if (r != i) {
                        sgn *= -1;
                        FOR(j, 0, nb) swap(mat[r][j], mat[i][j]);
                }
                LL iv = Inv(mat[i][i], MOD);
                FOR(k, i+1, na) {
                        LL mul = ModMul(iv, mat[k][i]);
                        FOR(j, i, nb) mat[k][j] = ModSub(mat[k][j], ModMul(mat[i][j], mul));
                }
        }

        LL res = ModNor(sgn);
        FOR(i, 0, na) res = ModMul(res, mat[i][i]);

        cout << res << endl;

        return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cctype>
#include <numeric>
#include <queue>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#define FOR(i,s,e) for(int i=(s);i<(int)(e);i++)
#define FOE(i,s,e) for(int i=(s);i<=(int)(e);i++)
#define ALL(x) (x).begin(), (x).end()
#define CLR(s) memset(s,0,sizeof(s))
#define PB push_back
#define ITER(v)      __typeof((v).begin())
#define FOREACH(i,v) for(ITER(v) i=(v).begin();i!=(v).end();i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef map<int,int> mii;
typedef vector<int> vi;
#define x first
#define y second

////////////////////////////////////////////////
// Modular Arithmetic (fixed MOD)

//const LL  MOD = 1000000009;
LL MOD;

LL Egcd(LL a, LL b, LL &x, LL &y){      // g = ax + by
        LL d;
        if(b==0){x=1;y=0;return a;}
        d=Egcd(b,a%b,y,x);
        y-=a/b*x; return d;
}

LL Inv(LL u, LL MOD) {  // u^-1 (mod MOD)
        LL x, y, g=Egcd(u,MOD,x,y);
        if (g!=1) return -1;    // no inverse
        return (x%MOD+MOD)%MOD;
}

// UPD: 2011-09-28 - add some practical speedup
LL ModNor(LL x){ if(x<0) x=(x%MOD+MOD); return x>=MOD?x%MOD:x; }
LL ModAdd(LL x,LL y){ return ModNor(ModNor(x)+ModNor(y)); }
LL ModSub(LL x,LL y){ return ModAdd(x,-y); }
LL ModMul(LL x,LL y){ LL res=ModNor(x)*ModNor(y); if(res>=MOD) res%=MOD; return res; }

LL ModPow(LL a, LL n) {
        LL z=1, m=a;
        for (;n;n>>=1,m=m*m%MOD)
                if (n&1) z=z*m%MOD;
        return z;
}

/////////////////////////////////////////////////////
// GCD and LCM

LL Gcd(LL x, LL y) { return x ? Gcd(y%x, x) : y; }
LL Lcm(LL x, LL y) { return x / Gcd(x,y) * y; }

////////////////////////////////////////////////
// 2011-08-14 - avoid overflow

LL ModMul2(LL x, LL y) {
        LL ans = 0;
        for(; y; y>>=1, x<<=1, x%=MOD)
                if (y&1)
                        ans = ModAdd(ans, x);
        return ans;
}

////////////////////////////////////////////////

const int N = 666;
vector<LL> adj[N], back[N];
int n, m;

void ae(int x, int y) {
        adj[x].PB(y);
        back[y].PB(x);
}

LL dp[N][N];
int a[N], b[N]; // src, sink
int na = 0, nb = 0;
mii ma, mb;

LL go(int x, int y) {
        LL &res = dp[x][y];
        if (res != -1) return res;
        if(x==y) return res = 1LL;
        res = 0;
        FOREACH(it, back[y])
                res = ModAdd(res, go(x, *it));
        return res;
}

int main() {
        //cin >> n >> m >> MOD;
        scanf("%d%d%I64d", &n, &m, &MOD);
        FOR(j, 0, m) {
                int x, y; scanf("%d%d", &x, &y); //cin >> x >> y;
                ae(x, y);
        }

        FOE(i, 1, n) {
                if (back[i].size()==0) a[na++] = i;
                if (adj[i].size() ==0) b[nb++] = i;
        }

        memset(dp, -1, sizeof(dp));
        FOR(i, 0, na) FOR(j, 0, nb) go(a[i], b[j]);

        LL mat[na][nb];
        FOR(i, 0, na) FOR(j, 0, nb) {
                mat[i][j] = dp[ a[i] ][ b[j] ];
        }

        int sgn = 1;
        FOR(i, 0, na) {
                int r = i;
                while (r < na && mat[r][i] == 0) ++r;
                if (r == na) { cout << 0 << endl; return 0; }
                if (r != i) {
                        sgn *= -1;
                        FOR(j, i, nb) swap(mat[r][j], mat[i][j]);
                }
                LL iv = Inv(mat[i][i], MOD);
                FOR(k, i+1, na) {
                        LL mul = ModMul(iv, mat[k][i]);
                        FOR(j, i, nb) mat[k][j] = ModSub(mat[k][j], ModMul(mat[i][j], mul));
                }
        }

        LL res = ModNor(sgn);
        FOR(i, 0, na) res = ModMul(res, mat[i][i]);

        cout << res << endl;

        return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cctype>
#include <numeric>
#include <queue>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#define FOR(i,s,e) for(int i=(s);i<(int)(e);i++)
#define FOE(i,s,e) for(int i=(s);i<=(int)(e);i++)
#define ALL(x) (x).begin(), (x).end()
#define CLR(s) memset(s,0,sizeof(s))
#define PB push_back
#define ITER(v)      __typeof((v).begin())
#define FOREACH(i,v) for(ITER(v) i=(v).begin();i!=(v).end();i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef map<int,int> mii;
typedef vector<int> vi;
#define x first
#define y second

////////////////////////////////////////////////
// Modular Arithmetic (fixed MOD)

//const LL  MOD = 1000000009;
LL MOD;

LL Egcd(LL a, LL b, LL &x, LL &y){      // g = ax + by
        LL d;
        if(b==0){x=1;y=0;return a;}
        d=Egcd(b,a%b,y,x);
        y-=a/b*x; return d;
}

LL Inv(LL u, LL MOD) {  // u^-1 (mod MOD)
        LL x, y, g=Egcd(u,MOD,x,y);
        if (g!=1) return -1;    // no inverse
        return (x%MOD+MOD)%MOD;
}

// UPD: 2011-09-28 - add some practical speedup
inline LL ModNor(LL x){ if(x<0) x=(x%MOD+MOD); return x>=MOD?x%MOD:x; }
inline LL ModAdd(LL x,LL y){ return ModNor(ModNor(x)+ModNor(y)); }
inline LL ModSub(LL x,LL y){ return ModAdd(x,-y); }
inline LL ModMul(LL x,LL y){ LL res=ModNor(x)*ModNor(y); if(res>=MOD) res%=MOD; return res; }

LL ModPow(LL a, LL n) {
        LL z=1, m=a;
        for (;n;n>>=1,m=m*m%MOD)
                if (n&1) z=z*m%MOD;
        return z;
}

/////////////////////////////////////////////////////
// GCD and LCM

LL Gcd(LL x, LL y) { return x ? Gcd(y%x, x) : y; }
LL Lcm(LL x, LL y) { return x / Gcd(x,y) * y; }

////////////////////////////////////////////////
// 2011-08-14 - avoid overflow

LL ModMul2(LL x, LL y) {
        LL ans = 0;
        for(; y; y>>=1, x<<=1, x%=MOD)
                if (y&1)
                        ans = ModAdd(ans, x);
        return ans;
}

////////////////////////////////////////////////

const int N = 666;
vector<LL> adj[N], back[N];
int n, m;

void ae(int x, int y) {
        adj[x].PB(y);
        back[y].PB(x);
}

LL dp[N][N];
int a[N], b[N]; // src, sink
int na = 0, nb = 0;
mii ma, mb;

LL go(int x, int y) {
        LL &res = dp[x][y];
        if (res != -1) return res;
        if(x==y) return res = 1LL;
        res = 0;
        FOREACH(it, back[y])
                res = ModAdd(res, go(x, *it));
        return res;
}

int main() {
        //cin >> n >> m >> MOD;
        scanf("%d%d%I64d", &n, &m, &MOD);
        FOR(j, 0, m) {
                int x, y; scanf("%d%d", &x, &y); //cin >> x >> y;
                ae(x, y);
        }

        FOE(i, 1, n) {
                if (back[i].size()==0) a[na++] = i;
                if (adj[i].size() ==0) b[nb++] = i;
        }

        memset(dp, -1, sizeof(dp));
        FOR(i, 0, na) FOR(j, 0, nb) go(a[i], b[j]);

        LL mat[na][nb];
        FOR(i, 0, na) FOR(j, 0, nb) {
                mat[i][j] = dp[ a[i] ][ b[j] ];
        }

        int sgn = 1;
        FOR(i, 0, na) {
                int r = i;
                while (r < na && mat[r][i] == 0) ++r;
                if (r == na) { cout << 0 << endl; return 0; }
                if (r != i) {
                        sgn *= -1;
                        FOR(j, i, nb) swap(mat[r][j], mat[i][j]);
                }
                LL iv = Inv(mat[i][i], MOD);
                FOR(k, i+1, na) {
                        LL mul = ModMul(iv, mat[k][i]);
if (!mul) continue;
                        FOR(j, i, nb) mat[k][j] = ModSub(mat[k][j], ModMul(mat[i][j], mul));
                }
        }

        LL res = ModNor(sgn);
        FOR(i, 0, na) res = ModMul(res, mat[i][i]);

        cout << res << endl;

        return 0;
}


#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <cctype>
#include <numeric>
#include <queue>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <iterator>
#define FOR(i,s,e) for(int i=(s);i<(int)(e);i++)
#define FOE(i,s,e) for(int i=(s);i<=(int)(e);i++)
#define ALL(x) (x).begin(), (x).end()
#define CLR(s) memset(s,0,sizeof(s))
#define PB push_back
#define ITER(v)      __typeof((v).begin())
#define FOREACH(i,v) for(ITER(v) i=(v).begin();i!=(v).end();i++)
using namespace std;
typedef long long LL;
typedef pair<int,int> pii;
typedef map<int,int> mii;
typedef vector<int> vi;
#define x first
#define y second

////////////////////////////////////////////////
// Modular Arithmetic (fixed MOD)

//const LL  MOD = 1000000009;
LL MOD;

LL Egcd(LL a, LL b, LL &x, LL &y){      // g = ax + by
        LL d;
        if(b==0){x=1;y=0;return a;}
        d=Egcd(b,a%b,y,x);
        y-=a/b*x; return d;
}

LL Inv(LL u, LL MOD) {  // u^-1 (mod MOD)
        LL x, y, g=Egcd(u,MOD,x,y);
        if (g!=1) return -1;    // no inverse
        return (x%MOD+MOD)%MOD;
}

// UPD: 2011-09-28 - add some practical speedup
LL ModNor(LL x){ if(x<0) x=(x%MOD+MOD); return x>=MOD?x%MOD:x; }
LL ModAdd(LL x,LL y){ return ModNor(ModNor(x)+ModNor(y)); }
LL ModSub(LL x,LL y){ return ModAdd(x,-y); }
LL ModMul(LL x,LL y){ LL res=ModNor(x)*ModNor(y); if(res>=MOD) res%=MOD; return res; }

LL ModPow(LL a, LL n) {
        LL z=1, m=a;
        for (;n;n>>=1,m=m*m%MOD)
                if (n&1) z=z*m%MOD;
        return z;
}

/////////////////////////////////////////////////////
// GCD and LCM

LL Gcd(LL x, LL y) { return x ? Gcd(y%x, x) : y; }
LL Lcm(LL x, LL y) { return x / Gcd(x,y) * y; }

////////////////////////////////////////////////
// 2011-08-14 - avoid overflow

LL ModMul2(LL x, LL y) {
        LL ans = 0;
        for(; y; y>>=1, x<<=1, x%=MOD)
                if (y&1)
                        ans = ModAdd(ans, x);
        return ans;
}

////////////////////////////////////////////////

const int N = 666;
vector<LL> adj[N], back[N];
int n, m;

void ae(int x, int y) {
        adj[x].PB(y);
        back[y].PB(x);
}

LL dp[N][N];
int a[N], b[N]; // src, sink
int na = 0, nb = 0;
mii ma, mb;

LL go(int x, int y) {
        LL &res = dp[x][y];
        if (res != -1) return res;
        if(x==y) return res = 1LL;
        res = 0;
        FOREACH(it, back[y])
                res = ModAdd(res, go(x, *it));
        return res;
}

int main() {
        //cin >> n >> m >> MOD;
        scanf("%d%d%I64d", &n, &m, &MOD);
        FOR(j, 0, m) {
                int x, y; scanf("%d%d", &x, &y); //cin >> x >> y;
                ae(x, y);
        }

        FOE(i, 1, n) {
                if (back[i].size()==0) a[na++] = i;
                if (adj[i].size() ==0) b[nb++] = i;
        }

        memset(dp, -1, sizeof(dp));
        FOR(i, 0, na) FOR(j, 0, nb) go(a[i], b[j]);

        LL mat[na][nb];
        FOR(i, 0, na) FOR(j, 0, nb) {
                mat[i][j] = dp[ a[i] ][ b[j] ];
        }

        int sgn = 1;
        FOR(i, 0, na) {
                int r = i;
                while (r < na && mat[r][i] == 0) ++r;
                if (r == na) { cout << 0 << endl; return 0; }
                if (r != i) {
                        sgn *= -1;
                        FOR(j, i, nb) swap(mat[r][j], mat[i][j]);
                }
                LL iv = Inv(mat[i][i], MOD);
                FOR(k, i+1, na) {
                        LL mul = ModMul(iv, mat[k][i]);
if (!mul) continue;
                        FOR(j, i, nb) mat[k][j] = ModSub(mat[k][j], ModMul(mat[i][j], mul));
                }
        }

        LL res = ModNor(sgn);
        FOR(i, 0, na) res = ModMul(res, mat[i][i]);

        cout << res << endl;

        return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int64;
struct Tgraph{
	static const int maxn=610,maxm=200010;
	struct Tedge{
		int son; Tedge *pre;
		void add(int s_,Tedge *p_){ son=s_,pre=p_; }
	}edge[maxm],*pos[maxn];
	int tot;
	void add(int a,int b){ edge[++tot].add(b,pos[a]),pos[a]=edge+tot; }
	void clear(){ tot=0; memset(pos,0,sizeof(pos)); }
}g;
const int maxn=610;
int ind[maxn],outd[maxn];
int s[maxn],t[maxn],o[maxn];
int real_w[maxn][maxn],*w[maxn];
int n,m,k,mod;

int64 mypow(int64 x,int n){
	int64 res=1;
	for(int i=n;i;i>>=1,x=x*x%mod)
		if(i&1) res=res*x%mod;
	return res;
}

void init(){
	scanf("%d%d%d",&n,&m,&mod),g.clear();
	memset(ind,0,sizeof(ind));
	memset(outd,0,sizeof(outd));
	for(int i=1,a,b;i<=m;++i){
		scanf("%d%d",&a,&b),g.add(a,b);
		++ind[b],++outd[a];
	}
	k=0;
	for(int i=1;i<=n;++i)
		if(!ind[i]) s[++k]=i;
	k=0;
	for(int i=1;i<=n;++i)
		if(!outd[i]) t[++k]=i;
}

void topsort(){
	int top=0;
	for(int i=1;i<=k;++i)
		o[++top]=s[i];
	for(int p=1;p<=top;++p)
		for(Tgraph::Tedge *i=g.pos[o[p]];i;i=i->pre)
			if(!--ind[i->son]) o[++top]=i->son;
}

void dp(){
	static int f[maxn];
	for(int i=1;i<=k;++i)
		w[i]=real_w[i];
	for(int u=1,x;u<=k;++u){
		x=s[u],memset(f,0,sizeof(f)),f[x]=1;
		for(int v=1;v<=n;++v)
			for(Tgraph::Tedge *i=g.pos[o[v]];i;i=i->pre)
				f[i->son]+=f[o[v]],f[i->son]%=mod;
		for(int v=1;v<=k;++v)
			w[u][v]=f[t[v]];
	}
}

void solve(){
	int64 s=1; int n=k;
	for(int k=1;k<=n;++k){
		int p=-1;
		for(int i=k;i<=n;++i)
			if(w[i][k]){ p=i; break; }
		if(p==-1){ puts("0"); return; }
		if(p!=k) swap(w[k],w[p]),s*=-1;
		int64 inv=mypow(w[k][k],mod-2);
		for(int i=k+1;i<=n;++i){
			int64 t=w[i][k]*inv%mod;
			for(int j=k;j<=n;++j)
				w[i][j]-=w[k][j]*t%mod,w[i][j]%=mod;
		}
	}
	for(int i=1;i<=n;++i)
		s=s*w[i][i]%mod;
	if(s<0) s+=mod; printf("%I64d\n",s);
}

int main(){
	init();
	topsort();
	dp();
	solve();
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int64;
struct Tgraph{
	static const int maxn=610,maxm=200010;
	struct Tedge{
		int son; Tedge *pre;
		void add(int s_,Tedge *p_){ son=s_,pre=p_; }
	}edge[maxm],*pos[maxn];
	int tot;
	void add(int a,int b){ edge[++tot].add(b,pos[a]),pos[a]=edge+tot; }
	void clear(){ tot=0; memset(pos,0,sizeof(pos)); }
}g;
const int maxn=610;
int ind[maxn],outd[maxn];
int s[maxn],t[maxn],o[maxn];
int real_w[maxn][maxn],*w[maxn];
int n,m,k,mod;

int64 mypow(int64 x,int n){
	int64 res=1;
	for(int i=n;i;i>>=1,x=x*x%mod)
		if(i&1) res=res*x%mod;
	return res;
}

void init(){
	scanf("%d%d%d",&n,&m,&mod),g.clear();
	memset(ind,0,sizeof(ind));
	memset(outd,0,sizeof(outd));
	for(int i=1,a,b;i<=m;++i){
		scanf("%d%d",&a,&b),g.add(a,b);
		++ind[b],++outd[a];
	}
	k=0;
	for(int i=1;i<=n;++i)
		if(!ind[i]) s[++k]=i;
	k=0;
	for(int i=1;i<=n;++i)
		if(!outd[i]) t[++k]=i;
}

void topsort(){
	int top=0;
	for(int i=1;i<=k;++i)
		o[++top]=s[i];
	for(int p=1;p<=top;++p)
		for(Tgraph::Tedge *i=g.pos[o[p]];i;i=i->pre)
			if(!--ind[i->son]) o[++top]=i->son;
}

void dp(){
	static int f[maxn];
	for(int i=1;i<=k;++i)
		w[i]=real_w[i];
	for(int u=1,x;u<=k;++u){
		x=s[u],memset(f,0,sizeof(f)),f[x]=1;
		for(int v=1;v<=n;++v)
			for(Tgraph::Tedge *i=g.pos[o[v]];i;i=i->pre)
				f[i->son]+=f[o[v]],f[i->son]%=mod;
		for(int v=1;v<=k;++v)
			w[u][v]=f[t[v]];
	}
/*	for(int i=1;i<=k;++i,cout<<endl)
		for(int j=1;j<=k;++j)
			cout<<w[i][j]<<' ';*/
}

void solve(){
	int64 s=1; int n=k;
	for(int k=1;k<=n;++k){
		int p=-1;
		for(int i=1;i<=n;++i)
			if(w[i][k]){ p=i; break; }
		if(p==-1){ puts("0"); return; }
		if(p!=k) swap(w[k],w[p]),s*=-1;
		int64 inv=mypow(w[k][k],mod-2);
		for(int i=k+1;i<=n;++i){
			int64 t=w[i][k]*inv%mod;
			for(int j=k;j<=n;++j)
				w[i][j]-=w[k][j]*t%mod,w[i][j]%=mod;
		}
	}
	for(int i=1;i<=n;++i)
		s=s*w[i][i]%mod;
	if(s<0) s+=mod; printf("%I64d\n",s);
}

int main(){
	init();
	topsort();
	dp();
	solve();
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define drep(i,r,l) for(int i=r;i>=l;i--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define LL long long
#define travel(u) for(int i = start[u], v; v = e[i].a, i; i = e[i].next)
#define pb push_back
#define sqr(x) ((x)*(x))

const int maxn = 200008;
int n, m, pp;
int start[maxn], tot;
int in[maxn], ou[maxn], a[608][608];
int be[608][608], h[maxn], cnt = 0, cnt1 = 0;;
struct arr
{
	int a, next;
}e[maxn<<1];

void Add(int x, int y)
{
	e[++tot].a = y; e[tot].next = start[x]; start[x] = tot;
}

void Init()
{
	scanf("%d%d%d", &n, &m, &pp);
	int x, y;
	rep(i,1,m)
	{
		scanf("%d%d", &x, &y);
		Add(y, x); ou[x]++; in[y]++;
	}
}

int power(int x, int n)
{
	int tmp = x, ans = 1;
	while (n)
	{
		if (n & 1) ans = (LL) ans * tmp % pp;
		tmp = (LL)tmp * tmp % pp;
		n >>= 1;
	}
	return ans;
}

void Diao_Si()
{
	n = cnt;
	LL sum = 1;
	rep(i,1,n)
	{
		rep(j,i,n)
			if (a[j][i])
			{
				rep(k,1,n)
					swap(a[j][k], a[i][k]);
				if (j != i) sum *= -1;
				goto sd;
			}
		printf("%d\n", 0); return;
		sd:;
		rep(j,i+1,n)
			if (a[j][i])
			{
				LL t1 = a[j][i], t2 = a[i][i];
				sum = sum * -power(t2, pp - 2) % pp;
				rep(k,i,n)
				{
					a[j][k] = (a[i][k] * t1 - a[j][k] * t2) % pp;
					if (a[j][k] < 0) a[j][k] += pp;
				}
			}
	}
	rep(i,1,n)
		sum = sum * a[i][i] % pp;
	if (sum < 0) sum += pp;
	printf("%I64d\n", sum);
}

void Work()
{
	int l = 1, r = 0;
	rep(i,1,n)
		if (!ou[i])
		{
			h[++r] = i; cnt++;
			be[i][cnt] = 1;
		}
	while (l <= r)
	{
		int u = h[l++];
		travel(u)
		{
			ou[v]--;
			rep(i,1,cnt)
			{
				be[v][i] += be[u][i];
				if (be[v][i] >= pp) be[v][i] -= pp;
			}
			if (!ou[v]) h[++r] = v;
		}
	}
	rep(i,1,n)
		if (!in[i])
		{
			++cnt1;
			rep(j,1,cnt)
				a[cnt1][j] = be[i][j];
		}
}

int main()
{
	Init();
	Work();
	Diao_Si();
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define drep(i,r,l) for(int i=r;i>=l;i--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define LL long long
#define travel(u) for(int i = start[u], v; v = e[i].a, i; i = e[i].next)
#define pb push_back
#define sqr(x) ((x)*(x))

const int maxn = 200008;
int n, m, pp;
int start[maxn], tot;
int in[maxn], ou[maxn], a[608][608];
int be[608][608], h[maxn], cnt = 0, cnt1 = 0;;
struct arr
{
	int a, next;
}e[maxn<<1];

void Add(int x, int y)
{
	e[++tot].a = y; e[tot].next = start[x]; start[x] = tot;
}

void Init()
{
	scanf("%d%d%d", &n, &m, &pp);
	int x, y;
	rep(i,1,m)
	{
		scanf("%d%d", &x, &y);
		Add(y, x); ou[x]++; in[y]++;
	}
}

int power(int x, int n)
{
	int tmp = x, ans = 1;
	while (n)
	{
		if (n & 1) ans = (LL) ans * tmp % pp;
		tmp = (LL)tmp * tmp % pp;
		n >>= 1;
	}
	return ans;
}

void Diao_Si()
{
	n = cnt;
	LL sum = 1;
	rep(i,1,n)
	{
		rep(j,i,n)
			if (a[j][i])
			{
				rep(k,1,n)
					swap(a[j][k], a[i][k]);
				if (j != i) sum *= -1;
				goto sd;
			}
		printf("%d\n", 0); return;
		sd:;
		rep(j,i+1,n)
			if (a[j][i])
			{
				LL t1 = a[j][i], t2 = a[i][i];
				sum = sum * -power(t2, pp - 2) % pp;
				rep(k,i,n)
				{
					a[j][k] = a[i][k] * t1 - a[j][k] * t2;
					a[j][k] %= pp; if (a[j][k] < 0) a[j][k] += pp;
				}
			}
	}
	rep(i,1,n)
		sum = sum * a[i][i] % pp;
	if (sum < 0) sum += pp;
	printf("%I64d\n", sum);
}

void Work()
{
	int l = 1, r = 0;
	rep(i,1,n)
		if (!ou[i])
		{
			h[++r] = i; cnt++;
			be[i][cnt] = 1;
		}
	while (l <= r)
	{
		int u = h[l++];
		travel(u)
		{
			ou[v]--;
			rep(i,1,cnt)
			{
				be[v][i] += be[u][i];
				if (be[v][i] >= pp) be[v][i] -= pp;
			}
			if (!ou[v]) h[++r] = v;
		}
	}
	rep(i,1,n)
		if (!in[i])
		{
			++cnt1;
			rep(j,1,cnt)
				a[cnt1][j] = be[i][j];
		}
}

int main()
{
	Init();
	Work();
	Diao_Si();
	return 0;
}


#include <cstdlib>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <fstream>
#include <numeric>
#include <iomanip>
#include <bitset>
#include <list>
#include <stdexcept>
#include <functional>
#include <utility>
#include <ctime>
using namespace std;
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define drep(i,r,l) for(int i=r;i>=l;i--)
#define min(a,b) (a<b?a:b)
#define max(a,b) (a>b?a:b)
#define LL long long
#define travel(u) for(int i = start[u], v; v = e[i].a, i; i = e[i].next)
#define pb push_back
#define sqr(x) ((x)*(x))

const int maxn = 200008;
int n, m, pp;
int start[maxn], tot;
int in[maxn], ou[maxn], a[608][608];
int be[608][608], h[maxn], cnt = 0, cnt1 = 0;;
struct arr
{
	int a, next;
}e[maxn<<1];

void Add(int x, int y)
{
	e[++tot].a = y; e[tot].next = start[x]; start[x] = tot;
}

void Init()
{
	scanf("%d%d%d", &n, &m, &pp);
	int x, y;
	rep(i,1,m)
	{
		scanf("%d%d", &x, &y);
		Add(y, x); ou[x]++; in[y]++;
	}
}

void Diao_Si()
{
	n = cnt;
	LL sum = 1;
	rep(i,1,n)
	{
		rep(j,i,n)
			if (a[j][i])
			{
				rep(k,1,n)
					swap(a[j][k], a[i][k]);
				if (j != i) sum *= -1;
				goto sd;
			}
		printf("%d\n", 0); return;
		sd:;
		rep(j,i+1,n)
			if (a[j][i])
			{
				LL t1 = a[j][i], t2 = a[i][i];
				sum = sum * -t2 % pp;
				rep(k,i,n)
				{
					a[j][k] = a[i][k] * t1 - a[j][k] * t2;
					a[j][k] %= pp; if (a[j][k] < 0) a[j][k] += pp;
				}
			}
	}
	rep(i,1,n)
		sum = sum * a[i][i] % pp;
	if (sum < 0) sum += pp;
	printf("%I64d\n", sum);
}

void Work()
{
	int l = 1, r = 0;
	rep(i,1,n)
		if (!ou[i])
		{
			h[++r] = i; cnt++;
			be[i][cnt] = 1;
		}
	while (l <= r)
	{
		int u = h[l++];
		travel(u)
		{
			ou[v]--;
			rep(i,1,cnt)
			{
				be[v][i] += be[u][i];
				if (be[v][i] >= pp) be[v][i] -= pp;
			}
			if (!ou[v]) h[++r] = v;
		}
	}
	rep(i,1,n)
		if (!in[i])
		{
			++cnt1;
			rep(j,1,cnt)
				a[cnt1][j] = be[i][j];
		}
	Diao_Si();
}

int main()
{
	Init();
	Work();
	return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>

using namespace std;

typedef long long LL;

#define N 611

vector <int> g[N];
int hash[N],degin[N],degou[N],snake,top[N],f[N],n,m,p,j,k;

LL a[N][N];

typedef vector <int> :: iterator its;

LL mi(LL a,LL b,LL p)
{
    if(!b)  return 1;
    LL ans=mi(a,b>>1,p);
    ans=ans*ans%p;
    if(b&1)
        ans=ans*a%p;
    return ans;
}

int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1;i<=m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        degou[a]++,degin[b]++;
        g[a].push_back(b);
    }
    queue <int> fb;
    int i2=0;
    for(int i=1;i<=n;++i)
        if(!degin[i])
        {
            fb.push(i);
            i2++;
        }
    for(int i=1;!fb.empty();++i)
    {
        int now=fb.front();
        fb.pop();
        top[i]=now;
        for(its j=g[now].begin();j!=g[now].end();++j)
            if(!--degin[*j])
                fb.push(*j);
    }
    for(int i=1;i<=i2;++i)
    {
        for(j=i;j<=n;++j)
            f[top[j]]=0;
        f[top[i]]=1;
        for(j=i;j<=n;++j)
        {
            int now=top[j];
            for(its k=g[now].begin();k!=g[now].end();++k)
                f[*k]=(f[*k]+f[now])%p;
        }
        for(j=1,k=1;j<=n;++j)
            if(!degou[j])
                a[i][k++]=f[j];
    }
    n=i2;
    LL ans=1;
    for(int i=1;i<=n;++i)
    {
        for(j=i;j<=n;++j)
            if(a[j][i])
                break;
        if(i!=j)
        {
            for(k=i;k<=n;++k)
                swap(a[i][k],a[j][k]);
            ans=-ans;
        }
        LL ni=mi(a[i][i],p-2,p);
        for(int j=i+1;j<=n;++j)
            if(a[j][i])
            {
                LL x=ni*(p-a[j][i]);
                for(int k=i;k<=n;++k)
                    a[j][k]=(a[j][k]+a[i][k]*x);
            }
    }
    for(int i=1;i<=n;++i)
        ans=ans*a[i][i]%p;
    if(ans<0)
        ans+=p;
    printf("%I64d\n",ans);
    return 0;
}


#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>

using namespace std;

typedef long long LL;

#define N 611

vector <int> g[N];
int hash[N],degin[N],degou[N],snake,top[N],f[N],n,m,p,j,k;

LL a[N][N];

typedef vector <int> :: iterator its;

LL mi(LL a,LL b,LL p)
{
    if(!b)  return 1;
    LL ans=mi(a,b>>1,p);
    ans=ans*ans%p;
    if(b&1)
        ans=ans*a%p;
    return ans;
}

int main()
{
    scanf("%d%d%d",&n,&m,&p);
    for(int i=1;i<=m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        degou[a]++,degin[b]++;
        g[a].push_back(b);
    }
    queue <int> fb;
    int i2=0;
    for(int i=1;i<=n;++i)
        if(!degin[i])
        {
            fb.push(i);
            i2++;
        }
    for(int i=1;!fb.empty();++i)
    {
        int now=fb.front();
        fb.pop();
        top[i]=now;
        for(its j=g[now].begin();j!=g[now].end();++j)
            if(!--degin[*j])
                fb.push(*j);
    }
    for(int i=1;i<=i2;++i)
    {
        for(j=i;j<=n;++j)
            f[top[j]]=0;
        f[top[i]]=1;
        for(j=i;j<=n;++j)
        {
            int now=top[j];
            for(its k=g[now].begin();k!=g[now].end();++k)
                f[*k]=(f[*k]+f[now])%p;
        }
        for(j=1,k=1;j<=n;++j)
            if(!degou[j])
                a[i][k++]=f[j];
    }
    n=i2;
    LL ans=1;
    for(int i=1;i<=n;++i)
    {
        for(j=i;j<=n;++j)
            if(a[j][i])
                break;
        if(i!=j)
        {
            for(k=i;k<=n;++k)
                swap(a[i][k],a[j][k]);
            ans=-ans;
        }
        LL ni=mi(a[i][i],p-2,p);
        for(int j=i+1;j<=n;++j)
            if(a[j][i])
            {
                LL x=ni*(p-a[j][i])%p;
                for(int k=i;k<=n;++k)
                    a[j][k]=(a[j][k]+a[i][k]*x)%p;
            }
    }
    for(int i=1;i<=n;++i)
        ans=ans*a[i][i]%p;
    if(ans<0)
        ans+=p;
    printf("%I64d\n",ans);
    return 0;
}


#include<iostream>
#include<string>
#include<ctime>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
#include<cstdio>
#include<map>
#include<string.h>
using namespace std;
long long ed[800],de[800];long long m[605][605];
vector<long long> so,si;long long n,ma;
long long dp[800];long long a[800][800];long long Mod;
void dfs(long long x)
{
	if(dp[x]) return ;
	for(long long i=1;i<=n;i++)
	{
		if(m[i][x]==1)
		{
			dfs(i);dp[x]+=dp[i];dp[x]%=Mod;
		}
	}
}long long anti=0;
long long rev(long long x)
{
	long long r=1;long long p=Mod-2;
	while(p>0)
	{
		if(p%2==1) r=r*x%Mod;x=x*x%Mod;p/=2;
	}return r;
}
void gauss()
{
//
	for(long long i=0;i<so.size();i++)
	{
		if(a[i][i]==0)
		{
			long long cy=1;
			for(long long j=i+1;j<so.size();j++) if(a[j][i]==1)
			{
				swap(a[i],a[j]),anti++;cy=0;
				break;
			}
			if(cy) continue;
		}
		for(long long j=i+1;j<so.size();j++)
		{
			long long p=a[j][i];if(p==0) continue;long long u=a[i][i];long long o=rev(u);
			for(long long k=0;k<so.size();k++)
			{
				a[j][k]-=p*o%Mod*a[i][k]%Mod;a[j][k]%=Mod;
			}
		}
	}
}
void solve()
{//for(int i=0;i<so.size();i++)for(int j=0;j<so.size();j++) cout<<a[i][j];
	gauss();
	long long ans=1;for(long long i=0;i<so.size();i++) ans=ans*a[i][i]%Mod;anti=anti%2;if(anti==1) ans=-ans;
	if(ans<0) ans+=Mod;cout<<ans%Mod;
}
int main()
{
	cin>>n>>ma>>Mod;
	for(long long i=0;i<ma;i++)
	{
		long long af,b;cin>>af>>b;
		ed[af]++;de[b]++;m[af][b]=1;
	}
	for(long long i=1;i<=n;i++)
	{
		if(ed[i]==0) si.push_back(i);if(de[i]==0) so.push_back(i);
	}
	for(long long j=0;j<so.size();j++)
	{
		memset(dp,0,sizeof(dp));
		dp[so[j]]=1;
		for(long long i=0;i<si.size();i++)
		{
			dfs(si[i]);a[i][j]=dp[si[i]];
		}
	}
	solve();
	return 0;
}


#include<iostream>
#include<string>
#include<ctime>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
#include<cstdio>
#include<map>
#include<string.h>
using namespace std;
long long ed[800],de[800];long long m[605][605];
vector<long long> so,si;long long n,ma;
long long dp[800];long long a[800][800];long long Mod;long long vis[800];
void dfs(long long x)
{
	if(vis[x]>0) return ;
	for(long long i=1;i<=n;i++)
	{
		if(m[i][x]>0)
		{
			dfs(i);dp[x]+=(dp[i])*m[i][x]%Mod;dp[x]%=Mod;
		}
	}
vis[x]=1;
}long long anti=0;
long long rev(long long x)
{
	long long r=1;long long p=Mod-2;
	while(p>0)
	{
		if(p%2==1) r=r*x%Mod;x=x*x%Mod;p/=2;
	}return r;
}
void gauss()
{
	for(long long i=0;i<so.size();i++)
	{
		if(a[i][i]==0)
		{
			long long cy=1;
			for(long long j=i+1;j<so.size();j++) if(a[j][i]!=0)
			{
				swap(a[i],a[j]),anti++;cy=0;
				break;
			}
			if(cy) continue;
		}long long o=rev(a[i][i]);
		for(long long j=i+1;j<so.size();j++)
		{
			long long p=a[j][i];if(p==0) continue;
			for(long long k=0;k<so.size();k++)
			{
				a[j][k]-=p*o%Mod*a[i][k]%Mod;a[j][k]%=Mod;
			}
		}
	}
}
void solve()
{
//	for(int i=0;i<so.size();i++){for(int j=0;j<so.size();j++) cout<<a[i][j]<<" ";cout<<endl;}
	gauss();
	long long ans=1;for(long long i=0;i<so.size();i++) ans=ans*a[i][i]%Mod;anti=anti%2;if(anti==1) ans=-ans;
	if(ans<0) ans+=Mod;cout<<ans%Mod;
}
int main()
{
	cin>>n>>ma>>Mod;
	for(long long i=0;i<ma;i++)
	{
		long long af,b;scanf("%I64d%I64d",&af,&b);
		ed[af]++;de[b]++;m[af][b]++;;
	}
	for(long long i=1;i<=n;i++)
	{
		if(ed[i]==0) si.push_back(i);if(de[i]==0) so.push_back(i);
	}
	for(long long j=0;j<so.size();j++)
	{
		memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));
		dp[so[j]]=1;vis[so[j]]=1;
		for(long long i=0;i<si.size();i++)
		{
			dfs(si[i]);a[j][i]=dp[si[i]];
		}
	}
	solve();
	return 0;
}


#include<iostream>
#include<string>
#include<ctime>
#include<algorithm>
#include<set>
#include<vector>
#include<queue>
#include<cmath>
#include<cstdio>
#include<map>
#include<string.h>
using namespace std;
long long ed[800],de[800];long long m[605][605];
vector<long long> so,si;long long n,ma;
long long dp[800];long long a[800][800];long long Mod;long long vis[800];
void dfs(long long x)
{
	if(vis[x]>0) return ;
	for(long long i=1;i<=n;i++)
	{
		if(m[i][x]>0)
		{
			dfs(i);dp[x]+=(dp[i])*m[i][x]%Mod;dp[x]%=Mod;
		}
	}
vis[x]=1;
}long long anti=0;
long long rev(long long x)
{
	long long r=1;long long p=Mod-2;
	while(p>0)
	{
		if(p%2==1) r=r*x%Mod;x=x*x%Mod;p/=2;
	}return r;
}
void gauss()
{
	for(long long i=0;i<so.size();i++)
	{
		if(a[i][i]==0)
		{
			long long cy=1;
			for(long long j=i+1;j<so.size();j++) if(a[j][i]!=0)
			{
				swap(a[i],a[j]),anti++;cy=0;
				break;
			}
			if(cy) continue;
		}long long o=rev(a[i][i]);
		for(long long j=i+1;j<so.size();j++)
		{
			long long p=a[j][i];if(p==0) continue;
			for(long long k=0;k<so.size();k++)
			{
				a[j][k]-=p*o%Mod*a[i][k]%Mod;a[j][k]%=Mod;
			}
		}
	}
}
void solve()
{
//	for(int i=0;i<so.size();i++){for(int j=0;j<so.size();j++) cout<<a[i][j]<<" ";cout<<endl;}
	gauss();
	long long ans=1;for(long long i=0;i<so.size();i++) ans=ans*a[i][i]%Mod;anti=anti%2;if(anti==1) ans=-ans;
	if(ans<0) ans+=Mod;cout<<ans%Mod;
}
int main()
{
	cin>>n>>ma>>Mod;
	for(long long i=0;i<ma;i++)
	{
		long long af,b;cin>>af>>b;
		ed[af]++;de[b]++;m[af][b]++;;
	}
	for(long long i=1;i<=n;i++)
	{
		if(ed[i]==0) si.push_back(i);if(de[i]==0) so.push_back(i);
	}
	for(long long j=0;j<so.size();j++)
	{
		memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));
		dp[so[j]]=1;vis[so[j]]=1;
		for(long long i=0;i<si.size();i++)
		{
			dfs(si[i]);a[j][i]=dp[si[i]];
		}
	}
	solve();
	return 0;
}


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

struct edge
{int u,v,next;
};
struct edge e[200010];

int n,m,num,mod,t,w,s1,s2,flag=1,ans;
int head[610],q[610],f[610][610],c[610][610],in[610],out[610],a[610],b[610];

int fpow(int i,int j)
{int ret=1;
 while(j)
 {	if(j&1) ret=(long long)ret*i%mod;
 	i=(long long)i*i%mod;
 	j/=2;
 }
 return ret;
}

void add(int u,int v)
{e[num].u=u;
 e[num].v=v;
 e[num].next=head[u];
 head[u]=num;
 num++;
}

void work()
{int i,j;

 while(t<=w)
 {	j=head[q[t]];
 	while(j!=-1)
 	{	for(i=1;i<=s1;i++)
 			f[e[j].v][i]=(f[e[j].v][i]+f[q[t]][i])%mod;
 		out[e[j].v]--;
 		if(!out[e[j].v])
		{	q[++w]=e[j].v;
			out[e[j].v]=1; // a flag shows that it isn't belong to t
		}
		j=e[j].next;
	}
 	t++;
 }
}

void gauss()
{int i,j,k,inv,p;

 for(i=1;i<=s1;i++)
 {	j=i;
 	while(j<=s1 && c[j][i]%mod==0) j++;
 	if(j<=s1)
 	{	if(i!=j)
	 	{	swap(c[i],c[j]);
	 		flag=-flag;
	 	}
 		inv=fpow(c[i][i],mod-2);
 		for(j=i+1;j<=s1;j++)
 		{	p=(long long)inv*c[j][i]%mod;
		 	for(k=i;k<=s1;k++)
 				c[j][k]=(c[j][k]-(long long)c[i][k]*p%mod)%mod;
 		}
 	}
 }
}

int main()
{int i,j,x,y;

 scanf("%d%d%d",&n,&m,&mod);
 memset(head,-1,sizeof(head));
 for(i=1;i<=m;i++)
 {	scanf("%d%d",&x,&y);
 	in[y]++;
 	out[x]++;
 	add(y,x);
 }
 for(i=1;i<=n;i++)
 {	if(!in[i] && out[i]) a[i]=++s1;
 	if(!out[i] && in[i]) b[i]=++s2;
 }
 for(i=1;i<=n;i++)
 	if(!out[i])
 	{	w++;
 		q[w]=i;
 		f[i][b[i]]=1;
 	}
 work();
 for(i=1;i<=n;i++)
 	if(a[i])
 	{	for(j=1;j<=s1;j++)
 			c[a[i]][j]=f[i][j];
 	}
 ans=1;
 for(i=1;i<=n;i++)
 	if(!in[i] && !out[i])
 	{	for(j=i+1;j<=n;j++)
 			if(a[j] || b[j]) ans=-ans;
 	}
 gauss();
 for(i=1;i<=s1;i++)
 	ans=(long long)ans*c[i][i]%mod;
 printf("%d\n",(ans*flag+mod)%mod);
 return 0;
}


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

struct edge
{int u,v,next;
};
struct edge e[200010];

int n,m,num,mod,t,w,s1,s2,flag=1,ans;
int head[610],q[610],f[610][610],c[610][610],in[610],out[610],a[610],b[610];

int fpow(int i,int j)
{int ret=1;
 while(j)
 {  if(j&1) ret=(long long)ret*i%mod;
    i=(long long)i*i%mod;
    j/=2;
 }
 return ret;
}

void add(int u,int v)
{e[num].u=u;
 e[num].v=v;
 e[num].next=head[u];
 head[u]=num;
 num++;
}

void work()
{int i,j;

 while(t<=w)
 {  j=head[q[t]];
    while(j!=-1)
    {   for(i=1;i<=n;i++)
            f[e[j].v][i]=(f[e[j].v][i]+f[q[t]][i])%mod;
        out[e[j].v]--;
        if(!out[e[j].v]) q[++w]=e[j].v;
        j=e[j].next;
    }
    t++;
 }
}

void gauss()
{int i,j,k,inv,p;

 for(i=1;i<=s1;i++)
 {  j=i;
    while(j<=s1 && c[j][i]%mod==0) j++;
    if(j<=s1)
    {   if(i!=j)
        {   swap(c[i],c[j]);
            flag=-flag;
        }
        inv=fpow(c[i][i],mod-2);
        for(j=i+1;j<=s1;j++)
        {   p=(long long)inv*c[j][i]%mod;
            for(k=i;k<=s1;k++)
                c[j][k]=(c[j][k]-(long long)c[i][k]*p%mod)%mod;
        }
    }
 }
}

int main()
{int i,j,x,y;

 scanf("%d%d%d",&n,&m,&mod);
 memset(head,-1,sizeof(head));
 for(i=1;i<=m;i++)
 {  scanf("%d%d",&x,&y);
    in[y]++;
    out[x]++;
    add(y,x);
 }
 for(i=1;i<=n;i++)
 {  if(in[i]==0) a[i]=++s1;
    if(out[i]==0) b[i]=++s2;
 }
 for(i=1;i<=n;i++)
    if(!out[i])
    {   w++;
        q[w]=i;
        f[i][i]=1;
    }
 work();
 for(i=1;i<=n;i++)
    if(a[i])
    {   for(j=1;j<=n;j++)
            if(b[j]) c[a[i]][b[j]]=f[i][j];
    }
 gauss();
 ans=1;
 for(i=1;i<=s1;i++)
    ans=(long long)ans*c[i][i]%mod;
 printf("%d\n",(ans*flag+mod)%mod);
 return 0;
}


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

struct edge
{int u,v,next;
};
struct edge e[200010];

int n,m,num,mod,t,w,s1,s2,flag=1,ans;
int head[610],q[610],f[610][610],c[610][610],in[610],out[610],a[610],b[610];

int fpow(int i,int j)
{int ret=1;
 while(j)
 {  if(j&1) ret=(long long)ret*i%mod;
    i=(long long)i*i%mod;
    j/=2;
 }
 return ret;
}

void add(int u,int v)
{e[num].u=u;
 e[num].v=v;
 e[num].next=head[u];
 head[u]=num;
 num++;
}

void work()
{int i,j;

 while(t<=w)
 {  j=head[q[t]];
    while(j!=-1)
    {   for(i=1;i<=n;i++)
            f[e[j].v][i]+=f[q[t]][i];
        out[e[j].v]--;
        if(!out[e[j].v]) q[++w]=e[j].v;
        j=e[j].next;
    }
    t++;
 }
}

void gauss()
{int i,j,k,inv,p;

 for(i=1;i<=s1;i++)
 {  j=i;
    while(j<=s1 && c[j][i]%mod==0) j++;
    if(j<=s1)
    {   if(i!=j)
        {   swap(c[i],c[j]);
            flag=-flag;
        }
        inv=fpow(c[i][i],mod-2);
        for(j=i+1;j<=s1;j++)
        {   p=(long long)inv*c[j][i]%mod;
            for(k=i;k<=s1;k++)
                c[j][k]=c[j][k]-(long long)c[i][k]*p%mod;
        }
    }
 }
}

int main()
{int i,j,x,y;

 scanf("%d%d%d",&n,&m,&mod);
 memset(head,-1,sizeof(head));
 for(i=1;i<=m;i++)
 {  scanf("%d%d",&x,&y);
    in[y]++;
    out[x]++;
    add(y,x);
 }
 for(i=1;i<=n;i++)
 {  if(in[i]==0) a[i]=++s1;
    if(out[i]==0) b[i]=++s2;
 }
 for(i=1;i<=n;i++)
    if(!out[i])
    {   w++;
        q[w]=i;
        f[i][i]=1;
    }
 work();
 for(i=1;i<=n;i++)
    if(a[i])
    {   for(j=1;j<=n;j++)
            if(b[j]) c[a[i]][b[j]]=f[i][j];
    }
 gauss();
 ans=1;
 for(i=1;i<=s1;i++)
    ans=(long long)ans*c[i][i]%mod;
 printf("%d\n",(ans*flag+mod)%mod);
 return 0;
}


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

struct edge
{int u,v,next;
};
struct edge e[200010];

int n,m,num,mod,t,w,s1,s2,flag=1,ans;
int head[610],q[610],f[610][610],c[610][610],in[610],out[610],a[610],b[610];

int fpow(int i,int j)
{int ret=1;
 while(j)
 {  if(j&1) ret=(long long)ret*i%mod;
    i=(long long)i*i%mod;
    j/=2;
 }
 return ret;
}

void add(int u,int v)
{e[num].u=u;
 e[num].v=v;
 e[num].next=head[u];
 head[u]=num;
 num++;
}

void work()
{int i,j;

 while(t<=w)
 {  j=head[q[t]];
    while(j!=-1)
    {   for(i=1;i<=s1;i++)
            f[e[j].v][i]=(f[e[j].v][i]+f[q[t]][i])%mod;
        out[e[j].v]--;
        if(!out[e[j].v]) q[++w]=e[j].v;
        j=e[j].next;
    }
    t++;
 }
}

void gauss()
{int i,j,k,inv,p;

 for(i=1;i<=s1;i++)
 {  j=i;
    while(j<=s1 && c[j][i]%mod==0) j++;
    if(j<=s1)
    {   if(i!=j)
        {   swap(c[i],c[j]);
            flag=-flag;
        }
        inv=fpow(c[i][i],mod-2);
        for(j=i+1;j<=s1;j++)
        {   p=(long long)inv*c[j][i]%mod;
            for(k=i;k<=s1;k++)
                c[j][k]=(c[j][k]-(long long)c[i][k]*p%mod)%mod;
        }
    }
 }
}

int main()
{int i,j,x,y;

 scanf("%d%d%d",&n,&m,&mod);
 memset(head,-1,sizeof(head));
 for(i=1;i<=m;i++)
 {  scanf("%d%d",&x,&y);
    in[y]++;
    out[x]++;
    add(y,x);
 }
 for(i=1;i<=n;i++)
 {  if(in[i]==0) a[i]=++s1;
    if(out[i]==0) b[i]=++s2;
 }
 for(i=1;i<=n;i++)
    if(!out[i])
    {   w++;
        q[w]=i;
        f[i][b[i]]=1;
    }
 work();
 for(i=1;i<=n;i++)
    if(a[i])
    {   for(j=1;j<=s1;j++)
            c[a[i]][j]=f[i][j];
    }
 gauss();
 ans=1;
 for(i=1;i<=s1;i++)
    ans=(long long)ans*c[i][i]%mod;
 printf("%d\n",(ans*flag+mod)%mod);
 return 0;
}


#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;

long long mi(long long a,long long b,long long p)
{
    if(!b)  return 1;
    long long ans=mi(a,b>>1,p);
    ans=ans*ans%p;
    if(b&1)
        ans=ans*a%p;
    return ans;
}
vector <int> g[611];
int hash[611],degin[611],degou[611],snake,top[611],f[611];
long long a[611][611];
typedef vector <int> :: iterator its;
int main()
{
    int n,m,p,i,i2,j,k;
    scanf("%d%d%d",&n,&m,&p);
    for(i=1;i<=m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        degou[a]++,degin[b]++;
        g[a].push_back(b);
    }

    queue <int> fb;
    for(i=1,i2=0;i<=n;++i)
        if(!degin[i])
        {
            fb.push(i);
            i2++;
        }
    for(i=1;!fb.empty();++i)
    {
        int now=fb.front();
        fb.pop();
        top[i]=now;
        for(its j=g[now].begin();j!=g[now].end();++j)
            if(!--degin[*j])
                fb.push(*j);
    }

    for(i=1;i<=i2;++i)
    {
        for(j=i;j<=n;++j)
            f[top[j]]=0;
        f[top[i]]=1;
        for(j=i;j<=n;++j)
        {
            int now=top[j];
            for(its k=g[now].begin();k!=g[now].end();++k)
                f[*k]=(f[*k]+f[now])%p;
        }

        for(j=1,k=1;j<=n;++j)
            if(!degou[j])
                a[i][k++]=f[j];
    }

    n=i2;
    long long ans=1;
    for(i=1;i<=n;++i)
    {
        for(j=i;j<=n;++j)
            if(a[j][i])
                break;
        if(i!=j)
        {
            for(k=i;k<=n;++k)
                swap(a[i][k],a[j][k]);
            ans=-ans;
        }

        long long ni=mi(a[i][i],p-2,p);
        for(j=i+1;j<=n;++j)
            if(a[j][i])
            {
                long long x=ni*(p-a[j][i])%p;
                for(k=i;k<=n;++k)
                    a[j][k]=(a[j][k]+a[i][k]*x)%p;
            }
    }
    for(i=1;i<=n;++i)
        ans=ans*a[i][i]%p;
    if(ans<0)   ans+=p;
    printf("%I64d\n",ans);
    return 0;
}


#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;

long long mi(long long a,long long b,long long p)
{
    if(!b)  return 1;
    long long ans=mi(a,b>>1,p);
    ans=ans*ans%p;
    if(b&1)
        ans=ans*a%p;
    return ans;
}
int g[611][611],hash[611],degin[611],degou[611],snake,top[611],f[611];
long long a[311][311];
int main()
{
    int n,m,p,i,i2,j,k;
    scanf("%d%d%d",&n,&m,&p);
    for(i=1;i<=m;++i)
    {
        int a,b;
        scanf("%d%d",&b,&a);
        degou[a]++,degin[b]++;
        g[a][++g[a][0]]=b;
    }

    queue <int> fb;
    for(i=1,i2=0;i<=n;++i)
        if(!degin[i])
        {
            fb.push(i);
            i2++;
        }
    for(i=1;!fb.empty();++i)
    {
        int now=fb.front();
        fb.pop();
        top[i]=now;
        for(j=1;j<=g[now][0];++j)
            if(!--degin[g[now][j]])
                fb.push(g[now][j]);
    }

    for(i=1;i<=i2;++i)
    {
        for(j=i;j<=n;++j)
            f[top[j]]=0;
        f[top[i]]=1;
        for(j=i;j<=n;++j)
        {
            int now=top[j];
            for(k=1;k<=g[now][0];++k)
                f[g[now][k]]=(f[g[now][k]]+f[now])%p;
        }

        for(j=1,k=1;j<=n;++j)
            if(!degou[j])
                a[i][k++]=f[j];
    }

    n=i2;
    long long ans=1;
    for(i=1;i<=n;++i)
    {
        for(j=i;j<=n;++j)
            if(a[j][i])
                break;
        if(i!=j)
        {
            for(k=i;k<=n;++k)
                swap(a[i][k],a[j][k]);
            ans=-ans;
        }

        long long ni=mi(a[i][i],p-2,p);
        for(j=i+1;j<=n;++j)
            if(a[j][i])
            {
                long long x=ni*(p-a[j][i])%p;
                for(k=i;k<=n;++k)
                    a[j][k]=(a[j][k]+a[i][k]*x)%p;
            }
    }
    for(i=1;i<=n;++i)
        ans=ans*a[i][i]%p;
    if(ans<0)   ans+=p;
    for(i=1;i<=10000;++i)
        printf("1");
    printf("%I64d\n",ans);
    return 0;
}


#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;

long long mi(long long a,long long b,long long p)
{
    if(!b)  return 1;
    long long ans=mi(a,b>>1,p);
    ans=ans*ans%p;
    if(b&1)
        ans=ans*a%p;
    return ans;
}
vector <int> g[611];
int hash[611],degin[611],degou[611],snake,top[611],f[611];
long long a[311][311];
typedef vector <int> :: iterator its;
int main()
{
    int n,m,p,i,i2,j,k;
    scanf("%d%d%d",&n,&m,&p);
    for(i=1;i<=m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        degou[a]++,degin[b]++;
        g[a].push_back(b);
    }

    queue <int> fb;
    for(i=1,i2=0;i<=n;++i)
        if(!degin[i])
        {
            fb.push(i);
            i2++;
        }
    for(i=1;!fb.empty();++i)
    {
        int now=fb.front();
        fb.pop();
        top[i]=now;
        for(its j=g[now].begin();j!=g[now].end();++j)
            if(!--degin[*j])
                fb.push(*j);
    }

    for(i=1;i<=i2;++i)
    {
        for(j=i;j<=n;++j)
            f[top[j]]=0;
        f[top[i]]=1;
        for(j=i;j<=n;++j)
        {
            int now=top[j];
            for(its k=g[now].begin();k!=g[now].end();++k)
                f[*k]=(f[*k]+f[now])%p;
        }

        for(j=1,k=1;j<=n;++j)
            if(!degou[j])
                a[i][k++]=f[j];
    }

    n=i2;
    long long ans=1;
    for(i=1;i<=n;++i)
    {
        for(j=i;j<=n;++j)
            if(a[j][i])
                break;
        if(i!=j)
        {
            for(k=i;k<=n;++k)
                swap(a[i][k],a[j][k]);
            ans=-ans;
        }

        long long ni=mi(a[i][i],p-2,p);
        for(j=i+1;j<=n;++j)
            if(a[j][i])
            {
                long long x=ni*(p-a[j][i])%p;
                for(k=i;k<=n;++k)
                    a[j][k]=(a[j][k]+a[i][k]*x)%p;
            }
    }
    for(i=1;i<=n;++i)
        ans=ans*a[i][i]%p;
    if(ans<0)   ans+=p;
    printf("%I64d\n",ans);
    return 0;
}


#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;

long long mi(long long a,long long b,long long p)
{
    if(!b)  return 1;
    long long ans=mi(a,b>>1,p);
    ans=ans*ans%p;
    if(b&1)
        ans=ans*a%p;
    return ans;
}
int g[611][611],hash[611],degin[611],degou[611],snake,top[611],f[611];
long long a[311][311];
int main()
{
    int n,m,p,i,i2,j,k;
    scanf("%d%d%d",&n,&m,&p);
    for(i=1;i<=m;++i)
    {
        int a,b;
        scanf("%d%d",&b,&a);
        degou[a]++,degin[b]++;
        g[a][++g[a][0]]=b;
    }

    queue <int> fb;
    for(i=1,i2=0;i<=n;++i)
        if(!degin[i])
        {
            fb.push(i);
            i2++;
        }
    for(i=1;!fb.empty();++i)
    {
        int now=fb.front();
        fb.pop();
        top[i]=now;
        for(j=1;j<=g[now][0];++j)
            if(!--degin[g[now][j]])
                fb.push(g[now][j]);
    }

    for(i=1;i<=i2;++i)
    {
        for(j=i;j<=n;++j)
            f[top[j]]=0;
        f[top[i]]=1;
        for(j=i;j<=n;++j)
        {
            int now=top[j];
            for(k=1;k<=g[now][0];++k)
                f[g[now][k]]=(f[g[now][k]]+f[now])%p;
        }

        for(j=1,k=1;j<=n;++j)
            if(!degou[j])
                a[i][k++]=f[j];
    }

    n=i2;
    long long ans=1;
    for(i=1;i<=n;++i)
    {
        for(j=i;j<=n;++j)
            if(a[j][i])
                break;
        if(i!=j)
        {
            for(k=i;k<=n;++k)
                swap(a[i][k],a[j][k]);
            ans=-ans;
        }

        long long ni=mi(a[i][i],p-2,p);
        for(j=i+1;j<=n;++j)
            if(a[j][i])
            {
                long long x=ni*(p-a[j][i])%p;
                for(k=i;k<=n;++k)
                    a[j][k]=(a[j][k]+a[i][k]*x)%p;
            }
    }
    for(i=1;i<=n;++i)
        ans=ans*a[i][i]%p;
    if(ans<0)   ans+=p;
    printf("%I64d\n",ans);
    return 0;
}


#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;

long long mi(long long a,long long b,long long p)
{
    if(!b)  return 1;
    long long ans=mi(a,b>>1,p);
    ans=ans*ans%p;
    if(b&1)
        ans=ans*a%p;
    return ans;
}
int g[611][611],hash[611],degin[611],degou[611],snake,top[611],f[611];
long long a[311][311];
int main()
{
    int n,m,p,i,i2,j,k;
    scanf("%d%d%d",&n,&m,&p);
    for(i=1;i<=m;++i)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        degou[a]++,degin[b]++;
        g[a][++g[a][0]]=b;
    }

    queue <int> fb;
    for(i=1,i2=0;i<=n;++i)
        if(!degin[i])
        {
            fb.push(i);
            i2++;
        }
    for(i=1;!fb.empty();++i)
    {
        int now=fb.front();
        fb.pop();
        top[i]=now;
        for(j=1;j<=g[now][0];++j)
            if(!--degin[g[now][j]])
                fb.push(g[now][j]);
    }

    for(i=1;i<=i2;++i)
    {
        for(j=i;j<=n;++j)
            f[top[j]]=0;
        f[top[i]]=1;
        for(j=i;j<=n;++j)
        {
            int now=top[j];
            for(k=1;k<=g[now][0];++k)
                f[g[now][k]]=(f[g[now][k]]+f[now])%p;
        }

        for(j=1,k=1;j<=n;++j)
            if(!degou[j])
                a[i][k++]=f[j];
    }

    n=i2;
    long long ans=1;
    for(i=1;i<=n;++i)
    {
        for(j=i;j<=n;++j)
            if(a[j][i])
                break;
        if(i!=j)
        {
            for(k=i;k<=n;++k)
                swap(a[i][k],a[j][k]);
            ans=-ans;
        }

        long long ni=mi(a[i][i],p-2,p);
        for(j=i+1;j<=n;++j)
            if(a[j][i])
            {
                long long x=ni*(p-a[j][i])%p;
                for(k=i;k<=n;++k)
                    a[j][k]=(a[j][k]+a[i][k]*x)%p;
            }
    }
    for(i=1;i<=n;++i)
        ans=ans*a[i][i]%p;
    if(ans<0)   ans+=p;
    printf("%I64d\n",ans);
    return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
int n,m,Mod;
vector<int> G[605];
int num;
int dp[605];
int a[605][605];
int In[605],Out[605];
vector<int>source,sink;
int dfs(int x){
	if (dp[x]!=-1){
		return dp[x];
	}
	int ans=0;
	for (int i=0;i<G[x].size();i++){
		ans+=dfs(G[x][i]);
		ans%=Mod;
	}
	return ans;
}
long long power(long long a,long long b){
	if (b==0){
		return 1;
	}
	if (b%2==0){
		return power(a*a%Mod,b/2)%Mod;
	}
	else{
		return a*power(a*a%Mod,b/2)%Mod;
	}
}
long long solve(){
	int inv=0;
	for (int i=1;i<=num;i++){
		if (a[i][i]==0){
			inv++;
		    for (int j=i+1;j<=num;j++){
		    	if (a[j][i]!=0){
		    		for (int k=1;k<=num;k++){
		    			swap(a[i][k],a[j][k]);
		    		}
		    		break;
		    	}
		    }
		}
		if (a[i][i]==0){
			return 0ll;
		}
		for (int j=i+1;j<=num;j++){
			if (a[j][i]==0){
				continue;
			}
			long long ceof=(Mod-a[j][i])*power(a[i][i],Mod-2)%Mod;
			for (int k=i;k<=num;k++){
				a[j][k]=(a[j][k]+a[i][k]*ceof)%Mod;
			}
		}
	}
	long long ans=1;
	for (int i=1;i<=num;i++){
		ans*=a[i][i];
		ans%=Mod;
	}
	if (inv%2){
		ans=Mod-ans;
	}
	return ans;
}
int main(){
	scanf("%d%d%d",&n,&m,&Mod);
	for (int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		In[y]++;
		Out[x]++;
	}
	for (int i=1;i<=n;i++){
		if (In[i]==0){
			source.push_back(i);
		}
		if (Out[i]==0){
			sink.push_back(i);
		}
	}
	num=sink.size();
	for (int i=1;i<=num;i++){
		for (int j=1;j<=n;j++){
			dp[j]=-1;
		}
		dp[sink[i-1]]=1;
		for (int j=1;j<=num;j++){
			a[j][i]=dfs(source[j-1]);
		}
	}
	long long ans=solve();
	printf("%d",ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
int n,m,Mod;
vector<int> G[605];
int num;
int dp[605];
int a[605][605];
int In[605],Out[605];
vector<int>source,sink;
int dfs(int x){
	if (dp[x]!=-1){
		return dp[x];
	}
	int ans=0;
	for (int i=0;i<G[x].size();i++){
		ans+=dfs(G[x][i]);
		if (ans>=Mod){
			ans-=Mod;
		}
	}
	return ans;
}
long long power(long long a,long long b){
	if (b==0){
		return 1;
	}
	if (b%2==0){
		return power(a*a%Mod,b/2)%Mod;
	}
	else{
		return a*power(a*a%Mod,b/2)%Mod;
	}
}
long long solve(){
	int inv=0;
	for (int i=1;i<=num;i++){
		if (a[i][i]==0){
			inv++;
		    for (int j=i+1;j<=num;j++){
		    	if (a[j][i]!=0){
		    		for (int k=1;k<=num;k++){
		    			swap(a[i][k],a[j][k]);
		    		}
		    		break;
		    	}
		    }
		}
		if (a[i][i]==0){
			return 0ll;
		}
		for (int j=i+1;j<=num;j++){
			if (a[j][i]==0){
				continue;
			}
			long long ceof=(Mod-a[j][i])*power(a[i][i],Mod-2)%Mod;
			for (int k=i;k<=num;k++){
				a[j][k]=(a[j][k]+a[i][k]*ceof)%Mod;
			}
		}
	}
	long long ans=1;
	for (int i=1;i<=num;i++){
		ans*=a[i][i];
		if (ans>=Mod){
			ans-=Mod;
		}
	}
	if (inv%2){
		ans=Mod-ans;
	}
	return ans;
}
int main(){
	scanf("%d%d%d",&n,&m,&Mod);
	for (int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		In[y]++;
		Out[x]++;
	}
	for (int i=1;i<=n;i++){
		if (In[i]==0){
			source.push_back(i);
		}
		if (Out[i]==0){
			sink.push_back(i);
		}
	}
	num=sink.size();
	for (int i=1;i<=num;i++){
		for (int j=1;j<=n;j++){
			dp[j]=-1;
		}
		dp[sink[i-1]]=1;
		for (int j=1;j<=num;j++){
			a[j][i]=dfs(source[j-1]);
		}
	}
	long long ans=solve();
	printf("%d",ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
int a[605][605];
int from[605],to[605];
int n,m,Mod;
vector<int> G[605];
int ans=1;
int cntsi,cntso;
map<int,int> mpsource,mpsink;
bool vis[605];
void dfs(int sor,int x){
//	cout<<"x="<<x<<endl;
//	cout<<from[x]<<endl;
	if (from[x]==0){
//		cout<<sor<<" "<<x<<endl;
		a[mpsource[sor]][mpsink[x]]++;
		return;
	}
//	cout<<G[x].size()<<endl;
	for (int i=0;i<G[x].size();i++){
		if (vis[G[x][i]]){
			continue;
		}
		vis[G[x][i]]=true;
		dfs(sor,G[x][i]);
	}
}
void sol(){
	for (int i=1;i<=n;i++){
		if (to[i]==0){
			memset(vis,0,sizeof(vis));
			vis[i]=true;
			dfs(i,i);
		}
	}
	/*for (int i=1;i<=cntsi;i++){
		for (int j=1;j<=cntsi;j++){
			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}*/
	for (int i=1;i<=cntsi;i++){
		if (a[i][i]==0){
			ans=-ans;
			for (int j=i+1;j<=cntsi;j++){
				if (a[j][i]!=0){
					//cout<<"i="<<i<<" "<<"j="<<j<<endl;
					for (int k=1;k<=cntsi;k++){
						swap(a[i][k],a[j][k]);
					}
					break;
				}
			}
		}
		ans*=a[i][i];
		ans=(ans+Mod)%Mod;
		for (int j=i+1;j<=cntsi;j++){
			if (a[j][i]==0){
				continue;
			}
			int t1=a[i][i];
			int t2=a[j][i];
			for (int k=i;k<=cntsi;k++){
				a[j][k]*=t1;
				a[j][k]-=t2*a[i][k];
				a[j][k]/=t1;
			}
		}
	}
	/*for (int i=1;i<=cntsi;i++){
		for (int j=1;j<=cntsi;j++){
			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}*/
	cout<<ans;
}
int main(){
	scanf("%d%d%d",&n,&m,&Mod);
	for (int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		from[x]++;
		to[y]++;
	}
	for (int i=1;i<=n;i++){
		if (from[i]==0){
			cntsi++;
			mpsink[i]=cntsi;
		}
	}
	for (int i=1;i<=n;i++){
		if (to[i]==0){
			cntso++;
			mpsource[i]=cntso;
		}
	}
//	cout<<" "<<cntso<<" "<<cntsi<<endl;
	sol();
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
int n,m,Mod;
vector<int> G[605];
int num;
int dp[605];
int a[605][605];
int In[605],Out[605];
vector<int>source,sink;
int dfs(int x){
	if (dp[x]!=-1){
		return dp[x];
	}
	int ans=0;
	for (int i=0;i<G[x].size();i++){
		ans+=dfs(G[x][i]);
		if (ans>=Mod){
			ans-=Mod;
		}
	}
	return dp[x]=ans;
}
long long power(long long a,long long b){
	if (b==0){
		return 1;
	}
	long long t=power(a,b/2);
	t=t*t%Mod;
	if (b%2){
		t=t*a%Mod;
	}
	return t;
}
long long solve(){
	int inv=0;
	for (int i=1;i<=num;i++){
		if (a[i][i]==0){
			inv++;
		    for (int j=i+1;j<=num;j++){
		    	if (a[j][i]!=0){
		    		for (int k=1;k<=num;k++){
		    			swap(a[i][k],a[j][k]);
		    		}
		    		break;
		    	}
		    }
		}
		if (a[i][i]==0){
			return 0ll;
		}
		for (int j=i+1;j<=num;j++){
			if (a[j][i]==0){
				continue;
			}
			long long ceof=(Mod-a[j][i])*power(a[i][i],Mod-2)%Mod;
			for (int k=i;k<=num;k++){
				a[j][k]=(a[j][k]+a[i][k]*ceof)%Mod;
			}
		}
	}
	long long ans=1;
	for (int i=1;i<=num;i++){
		ans*=a[i][i];
		ans%=Mod;
	}
	if (inv%2){
		ans=Mod-ans;
	}
	return ans;
}
int main(){
	scanf("%d%d%d",&n,&m,&Mod);
	for (int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		In[y]++;
		Out[x]++;
	}
	for (int i=1;i<=n;i++){
		if (In[i]==0){
			source.push_back(i);
		}
		if (Out[i]==0){
			sink.push_back(i);
		}
	}
	num=sink.size();
	for (int i=1;i<=num;i++){
		for (int j=1;j<=n;j++){
			dp[j]=-1;
		}
		dp[sink[i-1]]=1;
		for (int j=1;j<=num;j++){
			a[j][i]=dfs(source[j-1]);
		}
	}
	long long ans=solve();
	printf("%d",ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
int n,m,Mod;
vector<int> G[605];
int num;
int dp[605];
int a[605][605];
int In[605],Out[605];
vector<int>source,sink;
int dfs(int x){
	if (dp[x]!=-1){
		return dp[x];
	}
	int ans=0;
	for (int i=0;i<G[x].size();i++){
		ans+=dfs(G[x][i]);
		if (ans>=Mod){
			ans-=Mod;
		}
	}
	return ans;
}
long long power(long long a,long long b){
	if (b==0){
		return 1;
	}
	if (b%2==0){
		return power(a*a%Mod,b/2)%Mod;
	}
	else{
		return a*power(a*a%Mod,b/2)%Mod;
	}
}
long long solve(){
	int inv=0;
	for (int i=1;i<=num;i++){
		if (a[i][i]==0){
			inv++;
		    for (int j=i+1;j<=num;j++){
		    	if (a[j][i]!=0){
		    		for (int k=1;k<=num;k++){
		    			swap(a[i][k],a[j][k]);
		    		}
		    		break;
		    	}
		    }
		}
		if (a[i][i]==0){
			return 0ll;
		}
		for (int j=i+1;j<=num;j++){
			if (a[j][i]==0){
				continue;
			}
			long long ceof=(Mod-a[j][i])*power(a[i][i],Mod-2)%Mod;
			for (int k=i;k<=num;k++){
				a[j][k]=(a[j][k]+a[i][k]*ceof)%Mod;
			}
		}
	}
	long long ans=1;
	for (int i=1;i<=num;i++){
		ans*=a[i][i];
		ans%=Mod;
	}
	if (inv%2){
		ans=Mod-ans;
	}
	return ans;
}
int main(){
	scanf("%d%d%d",&n,&m,&Mod);
	for (int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		In[y]++;
		Out[x]++;
	}
	for (int i=1;i<=n;i++){
		if (In[i]==0){
			source.push_back(i);
		}
		if (Out[i]==0){
			sink.push_back(i);
		}
	}
	num=sink.size();
	for (int i=1;i<=num;i++){
		for (int j=1;j<=n;j++){
			dp[j]=-1;
		}
		dp[sink[i-1]]=1;
		for (int j=1;j<=num;j++){
			a[j][i]=dfs(source[j-1]);
		}
	}
	long long ans=solve();
	printf("%d",ans);
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <map>
using namespace std;
int n,m,Mod;
vector<int> G[605];
int num;
int dp[605];
int a[605][605];
int In[605],Out[605];
vector<int>source,sink;
int dfs(int x){
	if (dp[x]!=-1){
		return dp[x];
	}
	int ans=0;
	for (int i=0;i<G[x].size();i++){
		ans+=dfs(G[x][i]);
		if (ans>=Mod){
			ans-=Mod;
		}
	}
	return ans;
}
long long power(long long a,long long b){
	if (b==0){
		return 1;
	}
	long long t=power(a,b/2);
	t=t*t%Mod;
	if (b%2){
		t=t*a%Mod;
	}
	return t;
}
long long solve(){
	int inv=0;
	for (int i=1;i<=num;i++){
		if (a[i][i]==0){
			inv++;
		    for (int j=i+1;j<=num;j++){
		    	if (a[j][i]!=0){
		    		for (int k=1;k<=num;k++){
		    			swap(a[i][k],a[j][k]);
		    		}
		    		break;
		    	}
		    }
		}
		if (a[i][i]==0){
			return 0ll;
		}
		for (int j=i+1;j<=num;j++){
			if (a[j][i]==0){
				continue;
			}
			long long ceof=(Mod-a[j][i])*power(a[i][i],Mod-2)%Mod;
			for (int k=i;k<=num;k++){
				a[j][k]=(a[j][k]+a[i][k]*ceof)%Mod;
			}
		}
	}
	long long ans=1;
	for (int i=1;i<=num;i++){
		ans*=a[i][i];
		ans%=Mod;
	}
	if (inv%2){
		ans=Mod-ans;
	}
	return ans;
}
int main(){
	scanf("%d%d%d",&n,&m,&Mod);
	for (int i=1;i<=m;i++){
		int x,y;
		scanf("%d%d",&x,&y);
		G[x].push_back(y);
		In[y]++;
		Out[x]++;
	}
	for (int i=1;i<=n;i++){
		if (In[i]==0){
			source.push_back(i);
		}
		if (Out[i]==0){
			sink.push_back(i);
		}
	}
	num=sink.size();
	for (int i=1;i<=num;i++){
		for (int j=1;j<=n;j++){
			dp[j]=-1;
		}
		dp[sink[i-1]]=1;
		for (int j=1;j<=num;j++){
			a[j][i]=dfs(source[j-1]);
		}
	}
	long long ans=solve();
	printf("%d",ans);
	return 0;
}


/*
	Author : ChnLich
*/
#include<cstdio>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<sstream>
#include<fstream>
#include<algorithm>
#include<vector>
#include<list>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<map>
#include<string>
#include<bitset>
#include<functional>
#include<utility>

using namespace std;

typedef long long llint;
typedef pair<int,int> ipair;
#define pb push_back
#define fi first
#define se second
#define mp make_pair

const int dx[]={0,1,0,-1},dy[]={1,0,-1,0};
const double eps=1e-8;

void read(int &k)
{
	k=0; char x=getchar();
	while(x<'0'||x>'9') x=getchar();
	while(x>='0'&&x<='9') { k=k*10-48+x; x=getchar(); }
}

int n,m,p,x,y,in[610],out[610],MOD,l[610];
int a[610][610],ans,lis[610],tmp[610],K,dp[610][610];

llint powe(llint a,llint b)
{
	llint ret=1;
	for(;b;b>>=1,a=a*a%MOD) if (b&1) ret*=a;
	return ret;
}

struct graph
{
	int a[610],b[200010],c[200010],p;
	int dd[610],ll,rr;
	void addedge(int x,int y)
	{
		c[++p]=a[x]; a[x]=p; b[p]=y;
	}
	void tppx()
	{
		memcpy(l,in,sizeof l);
		ll=1; rr=0;
		for(int i=1;i<=n;i++) if (!in[i]) dd[++rr]=i,lis[rr]=i;
		for(;ll<=rr;ll++)
			for(int i=a[dd[ll]];i;i=c[i])
			{
				l[b[i]]--;
				if (!l[b[i]]) dd[++rr]=b[i];
			}
		K=0;
		for(int i=1;i<=n;i++) if (!out[i]) tmp[++K]=i;
		for(int i=1;i<=K;i++) dp[tmp[i]][i]=1;
		for(int i=rr;i;i--) if (out[dd[i]])
			for(int j=a[dd[i]];j;j=c[j])
				for(int k=1;k<=K;k++)
					dp[dd[i]][k]=(dp[dd[i]][k]+dp[b[j]][k])%MOD;
		for(int i=1;i<=K;i++)
			for(int j=1;j<=K;j++) ::a[i][j]=dp[lis[i]][j];
	}
} A;

int main()
{
	scanf("%d%d%d",&n,&m,&p);
	MOD=p;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d",&x,&y);
		in[y]++; out[x]++;
		A.addedge(x,y);
	}
	A.tppx();
	ans=1;
	for(int i=1,j,k;i<=K;i++)
	{
		for(j=i;j<=K;j++) if (a[j][i]) break;
		if (j>K)
		{
			ans=0;
			break;
		}
		if (j!=i)
		{
			ans=MOD-ans;
			memcpy(a[0],a[j],sizeof a[0]);
			memcpy(a[j],a[i],sizeof a[0]);
			memcpy(a[i],a[0],sizeof a[0]);
		}
		int tmp=powe(a[i][i],MOD-2);
		for(j=i+1;j<=K;j++)
			for(k=K;k>=i;k--) a[j][k]=(a[j][k]-1ll*a[i][k]*a[j][i]%MOD*tmp%MOD+MOD)%MOD;
	}
	for(int i=1;i<=K;i++) ans=1ll*ans*a[i][i]%MOD;
	cout<<ans<<endl;

	return 0;
}


#include <iostream>
#include <algorithm>
using namespace std;

long long n,m,i,j,k,l;
main()
{

 cin>>n>>k;
  if ( (n*(n-1))/2<k) cout<<"no solution"<<endl; else
   {

     for (i=1;i<=n;i++)
      {
       l+=100;
       cout<<0<<" "<<l<<endl;
      }

   }

 //system ("pause");

}


#include <iostream>
#include <algorithm>
using namespace std;

long n,m,i,j,k,l,a[1000];
main()
{

 cin>>n>>k;
  if ( (n*(n-1))/2<k) cout<<"no solution"<<endl; else
   {

     for (i=1;i<=n;i++)
      {
       l+=100;
       cout<<0<<" "<<l<<endl;
      }

   }

 //system ("pause");

}


#include <iostream>
#include <algorithm>
using namespace std;

long long n,m,i,j,k,l;
main()
{

 cin>>n>>k;
  if ( (n*(n-1))/2<k) cout<<"no solution"<<endl; else
   {

     for (i=1;i<=n;i++)
      {
       l+=1000;
       cout<<0<<" "<<l<<endl;
      }

   }

 //system ("pause");

}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef pair<int,int> ii;
typedef vector<ii> vii;
long long arr[100009],has[100009],cnt=0;
int r[]={0,-1,-1,-1,0,1,1,1},c[]={1,1,0,-1,-1,-1,0,1};

#define mp make_pair
#define pb push_back
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define inf LONG_LONG_MAX
#define MOD 1000000007

ll gcd(ll a ,ll b)
{
	if(b%a==0) return a;
	else return gcd(b%a,a);
}
int main()
{
	ll d,n,i,j,k,a=0,b,idx,val;
	//freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
	cin>>n>>k;
	if(k>(n*(n-1))/2)
	{
		cout<<"no solution";return 0;
	}
	for(i=0;i<n;i++)
	{
		cout<<"0 "<<i<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef pair<int,int> ii;
typedef vector<ii> vii;
long long arr[100009],has[100009],cnt=0;
int r[]={0,-1,-1,-1,0,1,1,1},c[]={1,1,0,-1,-1,-1,0,1};

#define mp make_pair
#define pb push_back
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define inf LONG_LONG_MAX
#define MOD 1000000007

ll gcd(ll a ,ll b)
{
	if(b%a==0) return a;
	else return gcd(b%a,a);
}
int main()
{
	ll d,n,i,j,k,a=0,b,idx,val;
	//freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
	cin>>n>>k;
	if(k>(n*(n-1))/2)
	{
		cout<<"-1";return 0;
	}
	for(i=0;i<n;i++)
	{
		cout<<"0 "<<i<<endl;
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef pair<int,int> ii;
typedef vector<ii> vii;
long long arr[100009],has[100009],cnt=0;
int r[]={0,-1,-1,-1,0,1,1,1},c[]={1,1,0,-1,-1,-1,0,1};

#define mp make_pair
#define pb push_back
#define MAX(a,b) (((a)>(b))?(a):(b))
#define MIN(a,b) (((a)<(b))?(a):(b))
#define inf LONG_LONG_MAX
#define MOD 1000000007

ll gcd(ll a ,ll b)
{
	if(b%a==0) return a;
	else return gcd(b%a,a);
}
int main()
{
	ll d,n,i,j,k,a=0,b,idx,val;
	//freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
	cin>>n>>k;
	if(k<((n*(n-1))/2))
	{
		for(i=0;i<n;i++)
		{
			cout<<"0 "<<i<<endl;
		}
	}
	else
	{
		cout<<"no solution";
	}
	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <fstream>
#include <complex>

#define ub(vector, i) upper_bound(vector.begin(), vector.end(), i)
#define lb(vector, i) lower_bound(vector.begin(), vector.end(), i)
#define pb push_back
#define pf push_front
#define mp make_pair
#define REP(i, a, b)     for (int i = int(a); i <= int(b); i++)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define EPS 1e-9
#define PI acos(-1.0)
#define MEM(array) memset((array), 0, sizeof(array))
#define SORT(vector) sort(vector.begin(), vector.end())
#define REV(vector) reverse((vector).begin(), (vector).end())

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;

int main() {
    int n, k;
    scanf ("%d %d", &n, &k);
    if (n*(n-1)/2<k) printf ("no solution");
    else REP (i, 1, n) printf ("0 %d\n", i);
    system ("pause");
    return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <fstream>
#include <complex>

#define ub(vector, i) upper_bound(vector.begin(), vector.end(), i)
#define lb(vector, i) lower_bound(vector.begin(), vector.end(), i)
#define pb push_back
#define pf push_front
#define mp make_pair
#define REP(i, a, b)     for (int i = int(a); i <= int(b); i++)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define EPS 1e-9
#define PI acos(-1.0)
#define MEM(array) memset((array), 0, sizeof(array))
#define SORT(vector) sort(vector.begin(), vector.end())
#define REV(vector) reverse((vector).begin(), (vector).end())

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;

int main() {
    int n, k;
    scanf ("%d %d", &n, &k);
    if (n*(n-1)/2<k) printf ("no solution");
    else REP (i, 1, n) printf ("0 %d\n", i);
    //system ("pause");
    return 0;
}
     //


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <fstream>
#include <complex>

#define ub(vector, i) upper_bound(vector.begin(), vector.end(), i)
#define lb(vector, i) lower_bound(vector.begin(), vector.end(), i)
#define pb push_back
#define pf push_front
#define mp make_pair
#define REP(i, a, b)     for (int i = int(a); i <= int(b); i++)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define EPS 1e-9
#define PI acos(-1.0)
#define MEM(array) memset((array), 0, sizeof(array))
#define SORT(vector) sort(vector.begin(), vector.end())
#define REV(vector) reverse((vector).begin(), (vector).end())

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;

int main() {
    int n, k;
    scanf ("%d %d", &n, &k);
    if (n*(n-1)/2<k) printf ("no solution");
    else REP (i, 1, n) printf ("0 %d\n", i);
    system ("pause");
    return 0;
}
     //


#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <fstream>
#include <complex>

#define ub(vector, i) upper_bound(vector.begin(), vector.end(), i)
#define lb(vector, i) lower_bound(vector.begin(), vector.end(), i)
#define pb push_back
#define pf push_front
#define mp make_pair
#define REP(i, a, b)     for (int i = int(a); i <= int(b); i++)
#define INF 1000000000
#define LINF 1000000000000000000LL
#define EPS 1e-9
#define PI acos(-1.0)
#define MEM(array) memset((array), 0, sizeof(array))
#define SORT(vector) sort(vector.begin(), vector.end())
#define REV(vector) reverse((vector).begin(), (vector).end())

using namespace std;

typedef long long ll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
typedef vector<int> vi;

int main() {
    int n, k;
    scanf ("%d %d", &n, &k);
    if (n*(n-1)/2<=k) printf ("no solution");
    else REP (i, 1, n) printf ("0 %d\n", i);
    //system ("pause");
    return 0;
}
     //


#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;

#define s(n) scanf("%d",&n)

int main()
{
    int i,n,k,j;
    s(n);s(k);

    double num,d;
    d=sqrt(1+8*k);
    num=(1+d)/2;
    if(n<(int)num)
    printf("no solution\n");
    else if(n==(int)num && (n)*(n-1)<2*k)
    printf("no solution\n");
    else
    {
        for(i=0;i<n;i++)
        printf("0 %d\n",i);
    }
    return(0);
}


#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;

#define s(n) scanf("%d",&n)

int main()
{
    int i,n,k,j;
    s(n);s(k);

    double num,d;
    d=sqrt(1+8*k);
    num=(1+d)/2;
    if(n<(int)num)
    printf("no solution\n");
    else if(n==(int)num && (n)*(n-1)<=2*k)
    printf("no solution\n");
    else
    {
        for(i=0;i<n;i++)
        printf("0 %d\n",i);
    }
    return(0);
}


#include<iostream>
#include<cstdio>
#include<cmath>

using namespace std;

#define s(n) scanf("%d",&n)

int main()
{
    int i,n,k,j;
    s(n);s(k);

    double num,d;
    d=sqrt(1+8*(long long int)k);
    num=(1+d)/2;
    if(n<(int)num)
    printf("no solution\n");
    else if(n==(int)num && (n)*(n-1)<=2*k)
    printf("no solution\n");
    else
    {
        for(i=0;i<n;i++)
        printf("0 %d\n",i);
    }
    return(0);
}


#include<bits/stdc++.h>
using namespace std;
using std::string;
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mod 1000000007
#define pb push_back
#define pf push_front
#define ins insert
#define mp make_pair
#define bitcount __builtin_popcount
#define all(v) v.begin(),v.end()
#define mem(n,m) memset(n,m,sizeof(n))
#define pii pair<int,int>
#define pll pair<long long,long long>
#define sii set<int>
#define sll set<long long>
#define vii vector<int>
#define vll vector<long long>
#define mii map<int,int>
#define mll map<long long, long long>
#define lob lower_bound
#define upb upper_bound
#define EPSILON 1e-9
#define MAX 100002
#define PI 3.1415926535897932384626433832795028841971693993751
typedef long long  ll;
typedef unsigned long long llu;
typedef long double  ldb;
typedef double  db ;

int main()
{
  //  freopen("in.txt","r",stdin);
    int n,k;
    cin>>n>>k;
    if(n*(n-1)/2>k)
    {
        int i=0,j=0;
        while(n--)
        {
            cout<<i<<" "<<j++<<endl;
        }
    }
    else
        cout<<"no solution";
}


#include<bits/stdc++.h>
using namespace std;
using std::string;
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mod 1000000007
#define pb push_back
#define pf push_front
#define ins insert
#define mp make_pair
#define bitcount __builtin_popcount
#define all(v) v.begin(),v.end()
#define mem(n,m) memset(n,m,sizeof(n))
#define pii pair<int,int>
#define pll pair<long long,long long>
#define sii set<int>
#define sll set<long long>
#define vii vector<int>
#define vll vector<long long>
#define mii map<int,int>
#define mll map<long long, long long>
#define lob lower_bound
#define upb upper_bound
#define EPSILON 1e-9
#define MAX 100002
#define PI 3.1415926535897932384626433832795028841971693993751
typedef long long  ll;
typedef unsigned long long llu;
typedef long double  ldb;
typedef double  db ;

int main()
{
   // freopen("in.txt","r",stdin);
    int n,k;
    cin>>n>>k;
    if(2*n-1>=k)
    {
        int i=0,j=0;
        while(n--)
        {
            cout<<i++<<" "<<j++<<endl;
        }
    }
    else
        cout<<"no solution";
}


#include<bits/stdc++.h>
using namespace std;
using std::string;
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mod 1000000007
#define pb push_back
#define pf push_front
#define ins insert
#define mp make_pair
#define bitcount __builtin_popcount
#define all(v) v.begin(),v.end()
#define mem(n,m) memset(n,m,sizeof(n))
#define pii pair<int,int>
#define pll pair<long long,long long>
#define sii set<int>
#define sll set<long long>
#define vii vector<int>
#define vll vector<long long>
#define mii map<int,int>
#define mll map<long long, long long>
#define lob lower_bound
#define upb upper_bound
#define EPSILON 1e-9
#define MAX 100002
#define PI 3.1415926535897932384626433832795028841971693993751
typedef long long  ll;
typedef unsigned long long llu;
typedef long double  ldb;
typedef double  db ;

int main()
{
   // freopen("in.txt","r",stdin);
    int n,k;
    cin>>n>>k;
    if(n*n/2>=k)
    {
        int i=0,j=0;
        while(n--)
        {
            cout<<i<<" "<<j++<<endl;
        }
    }
    else
        cout<<"no solution";
}


#ifndef __MYLIB_H
#define __MYLIB_H

#include<iostream>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#include<utility>  // pair, make_pair
#include<cstdio>
#include<cmath>
#include<cstring>
#include<climits>
#include<list>
using namespace std;
#endif

int main() {

	int n, k;
	cin >> n >> k;

	if((n*n) <= k) {
		cout << "no solution" << endl;
		return 0;
	}

	vector<pair<int, int> > ret(n);

	ret[0] = make_pair(0, 0);
	bool flag = true;
	for(int i = 1; i < n; i++) {
		if(flag) ret[i] = make_pair(ret[i-1].first, ret[i-1].second+1);
		else ret[i] = make_pair(ret[i-1].first, ret[i-1].second+1);

		flag = !flag;
	}

	for(int i = 0; i < n; i++) cout << ret[i].first << " " << ret[i].second << endl;
}


#ifndef __MYLIB_H
#define __MYLIB_H

#include<iostream>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#include<utility>  // pair, make_pair
#include<cstdio>
#include<cmath>
#include<cstring>
#include<climits>
#include<list>
using namespace std;
#endif

int main() {

	int n, k;
	cin >> n >> k;

	if((n*(n-1))/2 <= k) {
		cout << "no solution" << endl;
		return 0;
	}

	vector<pair<int, int> > ret(n);

	ret[0] = make_pair(0, 0);
	bool flag = true;
	for(int i = 1; i < n; i++) {
		if(flag) ret[i] = make_pair(ret[i-1].first, ret[i-1].second+1);
		else ret[i] = make_pair(ret[i-1].first, ret[i-1].second+1);

		flag = !flag;
	}

	for(int i = 0; i < n; i++) cout << ret[i].first << " " << ret[i].second << endl;
}


#ifndef __MYLIB_H
#define __MYLIB_H

#include<iostream>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#include<utility>  // pair, make_pair
#include<cstdio>
#include<cmath>
#include<cstring>
#include<climits>
#include<list>
using namespace std;
#endif

int main() {

	int n, k;
	cin >> n >> k;

	if(n <= k) {
		cout << "no solution" << endl;
		return 0;
	}

	vector<pair<int, int> > ret(n);

	ret[0] = make_pair(0, 0);
	bool flag = true;
	for(int i = 1; i < n; i++) {
		if(flag) ret[i] = make_pair(ret[i-1].first+1, ret[i-1].second);
		else ret[i] = make_pair(ret[i-1].first, ret[i-1].second);

		flag = !flag;
	}

	for(int i = 0; i < n; i++) cout << ret[i].first << " " << ret[i].second << endl;
}


#ifndef __MYLIB_H
#define __MYLIB_H

#include<iostream>
#include<sstream>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<algorithm>
#include<map>
#include<utility>  // pair, make_pair
#include<cstdio>
#include<cmath>
#include<cstring>
#include<climits>
#include<list>
using namespace std;
#endif

int main() {

	int n, k;
	cin >> n >> k;

	if(n <= k) {
		cout << "no solution" << endl;
		return 0;
	}

	vector<pair<int, int> > ret(n);

	ret[0] = make_pair(0, 0);
	bool flag = true;
	for(int i = 1; i < n; i++) {
		if(flag) ret[i] = make_pair(ret[i-1].first+1, ret[i-1].second);
		else ret[i] = make_pair(ret[i-1].first, ret[i-1].second+1);

		flag = !flag;
	}

	for(int i = 0; i < n; i++) cout << ret[i].first << " " << ret[i].second << endl;
}


#include <iostream>
using namespace std;

int main() {
	int n,k;
	cin >> n >> k;
	if ( k > (n*(n-1))/2 ) {
		cout << "no solution" << endl;
		return 0;
	}
	int x = (int)(1e9)*-1;
	FOR(i,0,n) cerr << 0 << " " << x++ << endl;
	return 0;
}


#include <iostream>
using namespace std;

#define FOR(i,a,b) for(int i = (int)a; i <(int)b; i++ )

int main() {
	int n,k;
	cin >> n >> k;
	if ( k > (n*(n-1))/2 ) {
		cout << "no solution" << endl;
		return 0;
	}
	int x = (int)(1e9)*-1;
	FOR(i,0,n) cerr << 0 << " " << x++ << endl;
	return 0;
}


#include <iostream>
using namespace std;

#define FOR(i,a,b) for(int i = (int)a; i <(int)b; i++ )

int main() {
	int n,k;
	cin >> n >> k;
	if ( k > (n*(n-1))/2 ) {
		cout << "no solution" << endl;
		return 0;
	}
	int x = 1000*1000*1000*-1 + 1;
	FOR(i,0,n) cout << 0 << " " << x++ << endl;
	return 0;
}


#include <iostream>
using namespace std;

#define FOR(i,a,b) for(int i = (int)a; i <(int)b; i++ )

int main() {
	int n,k;
	cin >> n >> k;
	if ( k >= (n*(n-1))/2 ) {
		cout << "no solution" << endl;
		return 0;
	}
	int x = 1000*1000*1000*-1 + 1;
	FOR(i,0,n) cout << 0 << " " << x++ << endl;
	return 0;
}


#include <iostream>
using namespace std;

#define FOR(i,a,b) for(int i = (int)a; i <(int)b; i++ )

int main() {
	int n,k;
	cin >> n >> k;
	if ( k > (n*(n-1))/2 ) {
		cout << "no solution" << endl;
		return 0;
	}
	int x = 1000*1000*1000*-1 + 1;
	FOR(i,0,n) cerr << 0 << " " << x++ << endl;
	return 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
#include<math.h>
#include<vector>
#define LL long long
#define oo 1000000000
using namespace std;
int main(){
	int  n,K,i,j;
	while(scanf("%d %d",&n,&K)!=EOF){
		int tot=0;
		for(i=1;i<=n;i++){
			for(j=i+1;j<=n;j++)
				tot++;
		}
		if(tot<=K)puts("no solution");
		else{
			for(i=0;i<n;i++)
				printf("%d %d\n",i,(i+1)*100);
		}
	}
	return 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
#include<math.h>
#include<vector>
#define LL long long
#define oo 1000000000
using namespace std;
int main(){
    int  n,K,i,j;
    while(scanf("%d %d",&n,&K)!=EOF){
        int tot=0;
        for(i=1;i<=n;i++){
            for(j=i+1;j<=n;j++)
                tot++;
        }
        if(tot<=K)puts("no solution");
        else{
            for(i=0;i<n;i++)
                printf("%d %d\n",i,(i+1)*100);
        }
    }
    return 0;
}


#include<stdio.h>
int main(){
    int n,k;
    scanf("%d %d",&n,&k);
    if(k>n*(n-1)/2)puts("no solution");
    else{
        for(int i=0;i<n;i++)
            printf("%d %d\n",0,i*100);
    }
    return 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<string>
#include<iostream>
#include<algorithm>
#include<set>
#include<queue>
#include<map>
#include<math.h>
#include<vector>
#define LL long long
#define oo 1000000000
using namespace std;
int main(){
    int  n,K,i,j;
    while(scanf("%d %d",&n,&K)!=EOF){
        int tot=0;
        for(i=1;i<=n;i++){
            for(j=i+1;j<=n;j++)
                tot++;
        }
        if(tot<=K)puts("no solution");
        else{
            for(i=0;i<n;i++)
                printf("%d %d\n",0,(i+1)*100);
        }
    }
    return 0;
}


#include <iostream>
using namespace std;

int main ( )
{
	int n, k;
	scanf ( "%d%d", &n, &k );

	if ( (n*(n-1))/2 < k )
		printf ( "no solution\n" );
	else {
		for ( int i = 0; i < n; ++i )
			printf ( "0 %d\n", i );
	}

	return 0;
}


#include <stdio.h>
#include <iostream>
using namespace std;

int main ( )
{
	int n, k;
	scanf ( "%d%d", &n, &k );

	if ( (n*(n-1))/2 < k )
		printf ( "no solution\n" );
	else {
		for ( int i = 0; i < n; ++i )
			printf ( "0 %d\n", i );
	}

	return 0;
}


#include <stdio.h>
#include <iostream>
using namespace std;

int main ( )
{
	int n, k;
	scanf ( "%d%d", &n, &k );

	if ( (n*(n-1))/2 <= k )
		printf ( "no solution\n" );
	else {
		for ( int i = 0; i < n; ++i )
			printf ( "0 %d\n", i );
	}

	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#include <queue>
#include <cassert>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define in(n) scanf("%d",&n)
#define inl(n) scanf("%lld",&n)
#define out(n) printf("%d ",n)
#define outln(n) printf("%d\n",n)
#define outl(n) printf("%lld ",n)
#define outlln(n) printf("%lld\n",n)
#define LL long long
#define pb push_back
#define f first
#define s second
#define mp make_pair
#define sqr(x) ((x) * (x))
using namespace std;
int main()
{
	int n, k;
	in(n);in(k);
	int mmax =  n * (n - 1) / 2;
	if(k >= mmax) {
		puts("no solution");
		return 0;
	}
	int diff = n;
	int cx = 0, cy = 0;
	for(int i = 0; i < n; i++) {
		printf("%d %d\n", cx, cy);
		cx++;
		cy += (n + 2);
	}

	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#include <queue>
#include <cassert>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define in(n) scanf("%d",&n)
#define inl(n) scanf("%lld",&n)
#define out(n) printf("%d ",n)
#define outln(n) printf("%d\n",n)
#define outl(n) printf("%lld ",n)
#define outlln(n) printf("%lld\n",n)
#define LL long long
#define pb push_back
#define f first
#define s second
#define mp make_pair
#define sqr(x) ((x) * (x))
using namespace std;
int main()
{
	int n, k;
	in(n);in(k);
	int mmax =  n * (n - 1) / 2 - n;
	if(k > mmax) {
		puts("no solution");
		return 0;
	}
	int diff = n;
	int cx = 0, cy = 0;
	for(int i = 0; i < n; i++) {
		printf("%d %d\n", cx, cy);
		cx++;
		cy += (n + 2);
	}

	return 0;
}


#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <string>
#include <queue>
#include <cassert>
#define rep(i,a,n) for(int i=a;i<n;i++)
#define in(n) scanf("%d",&n)
#define inl(n) scanf("%lld",&n)
#define out(n) printf("%d ",n)
#define outln(n) printf("%d\n",n)
#define outl(n) printf("%lld ",n)
#define outlln(n) printf("%lld\n",n)
#define LL long long
#define pb push_back
#define f first
#define s second
#define mp make_pair
#define sqr(x) ((x) * (x))
using namespace std;
int main()
{
	int n, k;
	in(n);in(k);
	int mmax =  n * (n - 1) / 2;
	if(k > mmax) {
		puts("no solution");
		return 0;
	}
	int diff = n;
	int cx = 0, cy = 0;
	for(int i = 0; i < n; i++) {
		printf("%d %d\n", cx, cy);
		cx++;
		cy += (n + 2);
	}

	return 0;
}


#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <iostream>

#define ll long long
#define oo 1e18

const int N = 1e5 + 10;

using namespace std;

int n, k;

int main()
{
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin >> n >> k;
    if (n * (n - 1) / 2 <= k) cout << "no solution";
    else
    {
        for (int i = 0; i < n; i++)
            cout << "0 " << 1000 + i << endl;
    }
    return 0;
}


#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <iostream>

#define ll long long
#define oo 1e18

const int N = 1e5 + 10;

using namespace std;

int n, k;

int main()
{
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin >> n >> k;
    if (n * (n + 1) / 2 <= k) cout << "no solution";
    else
    {
        for (int i = 0; i < n; i++)
            cout << "0 " << 1000 + i << endl;
    }
    return 0;
}


#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <iostream>

#define ll long long
#define oo 1e18

const int N = 1e5 + 10;

using namespace std;

int n, k;

int main()
{
    //freopen("input.txt", "r", stdin);
    ios::sync_with_stdio(false);
    cin >> n >> k;
    if (n * (n + 1) / 2 < k) cout << "no solution";
    else
    {
        for (int i = 0; i < n; i++)
            cout << "0 " << 1000 + i << endl;
    }
    return 0;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman001 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
int main()
{
    abdelrahman001
    ll n,k,x = 0,y = 0;
    cin >> n >> k;
    if(n*(n-1)/2 < k)
        return cout << "no solution",0;
    for(int i = 0;i<n;i++)
        cout << x++ << " " << y++ << endl;
    return 0;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman001 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
int main()
{
    abdelrahman001
    ll n,k,x = 0,y = 0;
    cin >> n >> k;
    if(n*(n-1)/2 < k)
        return cout << "no solution",0;
    for(int i = 0;i<n;i++)
        cout << x << " " << y++ << endl;
    return 0;
}


#pragma GCC optimize ("O3")
#include <bits/stdc++.h>
#define abdelrahman001 ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
typedef long long ll;
using namespace std;
int main()
{
    abdelrahman001
    ll n,k,x = 0,y = 0;
    cin >> n >> k;
    if(n*(n-1)/2 <= k)
        return cout << "no solution",0;
    for(int i = 0;i<n;i++)
        cout << x << " " << y++ << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define fast                         ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define int                          long long int
#define double                       long double
#define ff                           first
#define ss                           second
#define pb                           push_back
#define eb                           emplace_back
#define all(x)                       (x).begin(), (x).end()
#define sz(x)                        ((int)(x).size())
#define len(x)                       ((int)(x).length())
#define pii                          pair<int,int>
#define vi                            vector<int>
#define vd                           vector<double>
#define vs                            vector<string>
#define mp                          map<int,int>
#define ms(x,y)                     memset(x,y,sizeof(x))
#define ump                         unordered_map<int,int>

#define lb                            lower_bound
#define ub                            upper_bound
#define nx                            cout<<"\n";
#define inf                           9223372036854775807
#define PI                            3.14159265

const int MOD = 1e9 + 7;

inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
inline int add(int a, int b) {    return ((a % MOD) + (b % MOD)) % MOD;}

inline int multi(int a, int b) {   return ((a % MOD) * (b % MOD)) % MOD;}

inline int sub(int a, int b) {       a %= MOD; b %= MOD; a -= b; if (a < 0) a += MOD; return a;}

inline int power(int a, int b) {       a %= MOD; int res = 1; while (b > 0) {if (b & 1) {res = multi(res, a);} a = multi(a, a); b >>= 1;}  return res;}

bool isPrime(int  x) {      if (x <= 4 || x % 2 == 0 || x % 3 == 0) {return x == 2 || x == 3;} for (int i = 5; i * i <= x; i += 6) {if (x % i == 0 || x % (i + 2) == 0) { return 0;}} return 1;}

int32_t main()
{
	fast ;
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, k; cin >> n >> k;
	std::vector<pii> v;
	for (int i = 0; i < n; i++) {
		v.pb({0, i});
	}
	int tot = (n * (n - 1)) / 2;
	if (tot <= k)cout << "no solution";
	else {
		for (pii p : v) {
			cout << p.ff << " " << p.ss << endl;
		}
	}

}


#include<bits/stdc++.h>
using namespace std;
#define fast                         ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define int                          long long int
#define double                       long double
#define ff                           first
#define ss                           second
#define pb                           push_back
#define eb                           emplace_back
#define all(x)                       (x).begin(), (x).end()
#define sz(x)                        ((int)(x).size())
#define len(x)                       ((int)(x).length())
#define pii                          pair<int,int>
#define vi                            vector<int>
#define vd                           vector<double>
#define vs                            vector<string>
#define mp                          map<int,int>
#define ms(x,y)                     memset(x,y,sizeof(x))
#define ump                         unordered_map<int,int>

#define lb                            lower_bound
#define ub                            upper_bound
#define nx                            cout<<"\n";
#define inf                           9223372036854775807
#define PI                            3.14159265

const int MOD = 1e9 + 7;

inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }
inline int add(int a, int b) {    return ((a % MOD) + (b % MOD)) % MOD;}

inline int multi(int a, int b) {   return ((a % MOD) * (b % MOD)) % MOD;}

inline int sub(int a, int b) {       a %= MOD; b %= MOD; a -= b; if (a < 0) a += MOD; return a;}

inline int power(int a, int b) {       a %= MOD; int res = 1; while (b > 0) {if (b & 1) {res = multi(res, a);} a = multi(a, a); b >>= 1;}  return res;}

bool isPrime(int  x) {      if (x <= 4 || x % 2 == 0 || x % 3 == 0) {return x == 2 || x == 3;} for (int i = 5; i * i <= x; i += 6) {if (x % i == 0 || x % (i + 2) == 0) { return 0;}} return 1;}

int32_t main()
{
	fast ;
#ifndef ONLINE_JUDGE
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
#endif
	int n, k; cin >> n >> k;
	std::vector<pii> v;
	for (int i = 0; i < n; i++) {
		if (i % 2 == 0)v.pb({i, 0});
		else v.pb({i, 1});
	}
	int tot = 2 * (n - 1);
	if (tot <= k)cout << "no solution";
	else {
		for (pii p : v) {
			cout << p.ff << " " << p.ss << endl;
		}
	}

}


#include <iostream>

using namespace std;

int main()
{
    int n,k;
    cin >> n >> k;
    if (n*(n - 1) <= 2*k) cout << "no solution"; else
        for (int i = 1; i <= n; ++i) cout << 0 << " " << i << endl;
    return 0;
}


#include <iostream>

using namespace std;

int main()
{
    int n,k;
    cin >> n >> k;
    if (n*(n + 1) <= k) cout << "no solution"; else
        for (int i = 1; i <= n; ++i) cout << 0 << " " << i << endl;
    return 0;
}


#include <iostream>

using namespace std;

int main()
{
    int n,k;
    cin >> n >> k;
    if (n*(n + 1) <= 2*k) cout << "no solution"; else
        for (int i = 1; i <= n; ++i) cout << 0 << " " << i << endl;
    return 0;
}