#include <bits/stdc++.h>
using namespace std;
int M[(int)605][(int)605];
struct Edge {
  int to, next;
} edges[(int)1e5 + 5 * 2];
int id[(int)605], od[(int)605], h[(int)605], head[(int)605], d[(int)605],
    t[(int)605], s[(int)605], dp[(int)605], q[(int)605];
int n, m, p, b_cnt;
inline void addedge(int u, int v) {
  edges[++b_cnt].to = v;
  edges[b_cnt].next = head[u];
  head[u] = b_cnt;
  id[v]++;
  od[u]++;
}
int cnt = 0;
int main() {
  int u;
  memset(head, -1, sizeof(head));
  cin >> n >> m >> p;
  for (int i = 1; i <= m; i++) {
    int x, y;
    cin >> x >> y;
    addedge(x, y);
  }
  for (int i = 1; i <= n; i++) d[i] = id[i];
  int r = 0;
  for (int i = 1; i <= n; i++)
    if (!d[i]) t[++r] = i;
  for (int l = 1; l <= r; l++) {
    for (int i = head[u = t[l]]; i != -1; i = edges[i].next) {
      int v = edges[i].to;
      if (!(--d[v])) t[++r] = v;
    }
  }
  int hcnt = 0;
  for (int i = 1; i <= n; i++)
    if (!id[i]) q[++cnt] = i;
  for (int i = 1; i <= n; i++) {
    if (!od[i]) {
      h[++hcnt] = i;
      memset(dp, 0, sizeof(dp));
      dp[i] = 1;
      for (int j = n; j; j--) {
        for (int x = head[u = t[j]]; x != -x; x = edges[x].next) {
          int v = edges[x].to;
          dp[u] = (dp[u] + dp[v]) % p;
        }
      }
      for (int j = 1; j <= cnt; j++) M[j][hcnt] = dp[q[j]];
    }
  }
  long long S = 1;
  for (int i = 1; i <= cnt; i++)
    for (int j = i + 1; j <= hcnt; j++) {
      while (M[j][i]) {
        long long tmp = M[i][i] / M[j][i];
        for (int k = i; k <= cnt; k++) M[i][k] = (M[i][k] - M[j][k] * tmp) % p;
        for (int k = 1; k <= cnt; k++) swap(M[i][k], M[j][k]);
        S = -S;
      }
    }
  for (int i = 1; i <= cnt; i++) S = (S * M[i][i]) % p;
  while (S < 0) S += p;
  cout << S << endl;
  return 0;
}
