#include <bits/stdc++.h>
using namespace std;
inline int read() {
  int res = 0;
  char c;
  bool flag = false;
  c = getchar();
  while (!isdigit(c)) {
    flag = (c == '-');
    c = getchar();
  }
  while (isdigit(c)) {
    res = res * 10 + (c ^ 48);
    c = getchar();
  }
  return !flag ? res : -res;
}
const int Max_n = 605;
const int Max_m = 1e5 + 5;
int n, p, m, head[Max_n], tot, in[Max_n], get_in[Max_n], get_out[Max_n],
    tp_get_in, tp_get_out, out[Max_n];
int tmp_in[Max_n], f[Max_n];
struct node {
  int nex, to;
  node(int a, int b) { nex = a, to = b; }
  node() {}
} edge[Max_m];
inline void add_edge(int x, int y) {
  edge[++tot] = node(head[x], y);
  head[x] = tot;
}
long long ans[Max_n][Max_n];
inline int quickpow(long long x, long long y) {
  long long ret = 1;
  while (y) {
    if (y & 1) ret *= x, ret %= p;
    x *= x, x %= p;
    y >>= 1;
  }
  return ret;
}
inline int ni(int x) { return quickpow(x, p - 2); }
inline void topu(int beg) {
  memset(f, 0, sizeof(f));
  f[get_in[beg]] = 1;
  queue<int> q;
  for (int i = 1; i <= n; ++i)
    if (!in[i]) q.push(i);
  while (!q.empty()) {
    int now = q.front();
    q.pop();
    for (int i = head[now]; i; i = edge[i].nex) {
      int nex = edge[i].to;
      f[nex] += f[now], f[nex] %= p;
      --tmp_in[nex];
      if (!tmp_in[nex]) q.push(nex);
    }
  }
  for (int i = 1; i <= tp_get_out; ++i) ans[beg][i] = f[get_out[i]];
}
inline int Gauss() {
  long long ret = 1;
  int rnk = tp_get_out;
  for (int i = 1; i <= rnk; ++i) {
    if (!ans[i][i])
      for (int j = i + 1; j <= rnk; ++j)
        if (ans[j][i]) {
          ret = -ret;
          swap(ans[j], ans[i]);
          break;
        }
    int inv = ni(ans[i][i]);
    for (int j = i + 1; j <= rnk; ++j) {
      int ti = 1ll * ans[j][i] * inv % p;
      for (int l = i; l <= rnk; ++l)
        ans[j][l] -= 1ll * ans[i][l] * ti % p, ans[j][l] %= p;
    }
  }
  for (int i = 1; i <= rnk; ++i) ret *= ans[i][i], ret %= p;
  return (ret + p) % p;
}
signed main() {
  n = read(), m = read(), p = read();
  for (int i = 1; i <= m; ++i) {
    int ui = read(), vi = read();
    add_edge(ui, vi);
    ++in[vi], ++out[ui];
  }
  for (int i = 1; i <= n; ++i) {
    if (!in[i]) get_in[++tp_get_in] = i;
    if (!out[i]) get_out[++tp_get_out] = i;
  }
  for (int i = 1; i <= tp_get_in; ++i) {
    memcpy(tmp_in, in, sizeof(tmp_in));
    topu(i);
  }
  printf("%d\n", Gauss());
  return 0;
}
