#include <bits/stdc++.h>
using namespace std;
const int MAXN = 600;
const int MAXM = 100000;
const int INF = 0x3f3f3f3f;
template <class T>
void Read(T &x) {
  x = 0;
  char c = getchar();
  bool flag = 0;
  while (c < '0' || '9' < c) {
    if (c == '-') flag = 1;
    c = getchar();
  }
  while ('0' <= c && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  if (flag) x = -x;
}
struct node {
  int v;
  node *nxt;
} * adj[MAXN + 10], Edges[MAXM + 10], *New = Edges;
void addedge(int u, int v) {
  node *p = ++New;
  p->v = v;
  p->nxt = adj[u];
  adj[u] = p;
}
int n, m, p;
int A[MAXN + 10][MAXN + 10];
inline int adjust(int v) {
  if (v < 0)
    return v + p;
  else if (v >= p)
    return v - p;
  else
    return v;
}
inline int ksm(int a, int p, int mod) {
  int ret = 1;
  while (p) {
    if (p & 1) ret = 1ll * ret * a % mod;
    p >>= 1;
    a = 1ll * a * a % mod;
  }
  return ret;
}
int rd[MAXN + 10], cd[MAXN + 10];
int lf[MAXN + 10], cntl;
int rg[MAXN + 10], cntr;
int dp[MAXN + 10], d[MAXN + 10];
queue<int> que;
void make_dp(int s) {
  memset(dp, 0, sizeof(dp));
  memset(d, 0, sizeof(d));
  int now;
  while (!que.empty()) que.pop();
  que.push(s);
  while (!que.empty()) {
    now = que.front(), que.pop();
    for (node *p = adj[now]; p != NULL; p = p->nxt)
      if (!d[p->v]++) que.push(p->v);
  }
  while (!que.empty()) que.pop();
  dp[s] = 1;
  que.push(s);
  while (!que.empty()) {
    now = que.front(), que.pop();
    for (node *p = adj[now]; p != NULL; p = p->nxt) {
      dp[p->v] = adjust(dp[p->v] + dp[now]);
      if (!--d[p->v]) que.push(p->v);
    }
  }
}
int main() {
  Read(n), Read(m), Read(p);
  int a, b;
  for (int i = 1; i <= m; ++i) {
    Read(a), Read(b);
    addedge(a, b);
    ++cd[a], ++rd[b];
  }
  cntl = cntr = 0;
  for (int i = 1; i <= n; ++i) {
    if (!rd[i]) lf[++cntl] = i;
    if (!cd[i]) rg[++cntr] = i;
  }
  for (int i = 1; i <= cntl; ++i) {
    make_dp(lf[i]);
    for (int j = 1; j <= cntr; ++j) A[i][j] = dp[rg[j]];
  }
  bool flag = false;
  for (int i = 1; i <= cntl; ++i) {
    int pos = 0;
    for (int j = i; j <= cntl; ++j)
      if (A[j][i]) {
        pos = j;
        break;
      }
    if (pos != i) {
      flag ^= 1;
      for (int j = 1; j <= cntr; ++j) swap(A[i][j], A[pos][j]);
    }
    for (int j = i + 1; j <= cntl; ++j) {
      int t = p - 1ll * A[j][i] * ksm(A[i][i], p - 2, p) % p;
      for (int k = i; k <= cntr; ++k)
        A[j][k] = adjust(A[j][k] + 1ll * t * A[i][k] % p);
    }
  }
  int ans = 1;
  for (int i = 1; i <= cntl; ++i) ans = 1ll * ans * A[i][i] % p;
  if (flag) ans = adjust(-ans);
  printf("%d\n", ans);
}
