#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void umax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline void umin(T &a, T b) {
  if (a > b) a = b;
}
template <class T>
inline T abs(T a) {
  return a > 0 ? a : -a;
}
template <class T>
inline T gcd(T a, T b) {
  return __gcd(a, b);
}
template <class T>
inline T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
const int inf = 1e9 + 143;
const long long longinf = 1e18 + 143;
inline int read() {
  int x;
  scanf(" %d", &x);
  return x;
}
const int N = 1e6 + 100;
int p[N], sz[N];
int get(int x) {
  if (x == p[x]) return x;
  return p[x] = get(p[x]);
}
int main() {
  int n = read();
  int m = read();
  int mod = read();
  for (int i = 1; i <= n; i++) p[i] = i;
  for (int i = 1; i <= m; i++) {
    int a = read();
    int b = read();
    a = get(a);
    b = get(b);
    if (a != b) {
      p[a] = b;
    }
  }
  vector<int> trees;
  for (int i = 1; i <= n; i++) {
    sz[get(i)] += 1;
  }
  for (int i = 1; i <= n; i++) {
    if (i == get(i)) {
      trees.push_back(sz[i]);
    }
  }
  if (trees.size() == 1) {
    printf("%d\n", 1 % mod);
    return 0;
  }
  int res = 1;
  for (int i = 1; i <= (int)trees.size() - 2; i++)
    res = (long long)res * n % mod;
  for (int i = 0; i < trees.size(); i++) res = (long long)res * trees[i] % mod;
  printf("%d\n", res);
  return 0;
}
