#include <bits/stdc++.h>
using namespace std;
int n, m;
const int MAXN = 100005;
typedef pair <int, int> pii;
vector <int> top;
vector <int> edges [MAXN];
int vis [MAXN];
void dfs (int no){vis[no] = 1;
    for (int g : edges[no]){
        if (vis[g]) continue; dfs (g);
    }
    top.push_back(no);
}
int main(){
    ios_base::sync_with_stdio(0);
    cin >> n >> m;
    map <pii, int> num;
    for (int g=1; g<=m; g++){
        int a, b; cin >> a >> b;
        edges[a].push_back(b);
        num[pii(a, b)] = g;
    }
    for (int g=1; g<=n; g++){
        if (vis[g]) continue; dfs (g);
    }
    reverse(top.begin(), top.end());
    if (top.size() != n){
        cout << -1; return 0;
    }
    int ans = 0;
    for (int g=0; g+1<top.size(); g++){
        pii z = pii(top[g], top[g+1]);
        if (num.count(z)) ans = max(ans, num[z]);
        else{
            cout << -1; return 0;
        }
    }
    cout << ans;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
int parent [MAXN];
int saw [MAXN];
int n, m;
int num;
int main(){
    ios_base::sync_with_stdio(0);
    cin >> n >> m;
    num = n;
    for (int g=1; g<=m; g++){
        int a, b; cin >> a >> b;
        if (!saw[b]){
            saw[b] = 1, num--;
        }
        if (num == 1){
            cout << g; return 0;
        }
    }
    cout << -1 ;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
int parent [MAXN];
int n, m;
int first [MAXN];
int last [MAXN];
int num;
int find (int no){
    if (parent[no] == 0) return no; return parent[no] = find(parent[no]);
}
void merge (int a, int b){
    int ff = find(a), ss = find(b);
    if (ff == ss) return;
    last[ff] = last[ss];
    parent[ss] = ff;
}
int main(){
    ios_base::sync_with_stdio(0);
    cin >> n >> m;
    for (int g=1; g<=n; g++) first[g] = last[g] = g;
    num = n;
    for (int g=1; g<=m; g++){
        int a, b; cin >> a >> b;
        if (a == last[find(a)] && b == first[find(b)]){
            merge (a, b);
            num--;
        }
        if (num == 1){
            cout << g; return 0;
        }
    }
    cout << -1 ;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
int parent [MAXN];
int n, m;
int first [MAXN];
int last [MAXN];
int num;
int find (int no){
    if (parent[no] == 0) return no; return parent[no] = find(parent[no]);
}
void merge (int a, int b){
    int ff = find(a), ss = find(b);
    if (ff == ss) return;
    last[ff] = last[ss];
    parent[ss] = ff;
}
int main(){
    ios_base::sync_with_stdio(0);
    cin >> n >> m;
    for (int g=1; g<=n; g++) first[g] = last[g] = g;
    num = n;
    for (int g=1; g<=m; g++){
        int a, b; cin >> a >> b;
        if (find(a) == find(b)) continue;
        if (a == last[find(a)] && b == first[find(b)]){
            merge (a, b);
            num--;
        }
        if (num == 1){
            cout << g; return 0;
        }
    }
    cout << -1 ;
    return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))

using namespace std;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<bool> vb;

const int INF=0x3f3f3f3f;
const int N=100000;

int dz;

int n, m, d[N], seen[N];

int main(void) {

	ios::sync_with_stdio(false);
    cin>>n>>m;
    dz=n;
    int na=0;
    for(int i=0;i<m;i++) {
        int u, v;cin>>u>>v;--u;--v;
        na+=!seen[u] + !seen[v];
        seen[u]=1;seen[v]=1;
        if(!d[v]) dz--;
        d[v]++;
        if(dz==1)
        {
            cout<<i+1<<"\n";
            return 0;
        }
    }
    cout<<"-1\n";

	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))

using namespace std;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<bool> vb;

const int INF=0x3f3f3f3f;
const int N=100000;

int dz;

int n, m;
vi adj[N];
ii ed[N];

bool f(int x) {
    vi d(n, 0);

    for(int i=0;i<x;i++) {
        d[ed[i].se]++;
    }
    queue<int> q;
    for(int i=0;i<n;i++)if(!d[i])
        q.push(i);

    if(q.size()!=1)return false;
    int c=0;
    while(!q.empty()) {
        if(q.size()!=1)return false;
        int u=q.front();q.pop();
        ++c;
        if(c==n)return true;
        for(int i=0;i<adj[u].size();i++)
        {
            int v=adj[u][i];
            if(v>=x)continue;
            v=ed[v].se;
            d[v]--;
            if(!d[v])q.push(v);
        }
    }
    return false;
}

int main(void) {

	ios::sync_with_stdio(false);
    cin>>n>>m;
    dz=n;
    int dou=n;
    int na=0;
    for(int i=0;i<m;i++) {
        int u, v;cin>>u>>v;--u;--v;
        adj[u].pb(i);
        //cout<<u<<" "<<i<<endl;
        ed[i]=ii(u,v);
    }
    int lo=0, hi=m+1;
    while(lo!=hi) {
        int mi=(lo+hi)/2;
        if(f(mi))
            hi=mi;
        else lo=mi+1;
    }
    if(lo<=m)
        cout<<lo<<endl;
    else
        cout<<"-1\n";

	return 0;
}


#include <bits/stdc++.h>
#define pb push_back
#define mk make_pair
#define fi first
#define se second
#define For(i,a,b) for(int (i)=(a);(i) < (b); ++(i))

using namespace std;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef long long ll;
typedef vector<bool> vb;

const int INF=0x3f3f3f3f;
const int N=100000;

int dz;

int n, m, d[N], seen[N];

int main(void) {

	ios::sync_with_stdio(false);
    cin>>n>>m;
    dz=n;
    int dou=n;
    int na=0;
    for(int i=0;i<m;i++) {
        int u, v;cin>>u>>v;--u;--v;
        if(!seen[u])
            dou--;
        seen[u]=1;
        if(!d[v]) dz--;

        d[v]++;
        if(dz==1 && dou==1)
        {
            cout<<i+1<<"\n";
            return 0;
        }
    }
    cout<<"-1\n";

	return 0;
}


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

const int N = 1e5 + 10;

int u[N], v[N], n, m, deg[N];
bool used[N];
vector <int> g[N];
vector <int> ord;

void dfs (int v) {
    used[v] = true;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to]) continue;
        dfs(to);
    }
    ord.push_back(v);
}

bool check (int sz) {
    for (int i = 0; i <= n; i++) g[i].clear(), deg[i] = 0, used[i] = false;
    set <pair<int, int> > edges;
    for (int i = 1; i <= sz; i++) {
        g[u[i]].push_back(v[i]);
        deg[v[i]]++;
        edges.insert(make_pair(u[i], v[i]));
    }

    int mx = 0, cnt = 0;
    for (int i = 1; i <= n; i++) {
        if (deg[i] == 0) {
            mx = i;
            cnt++;
        }
    }
    if (cnt != 1) return false;
    ord.clear();
    dfs(mx);
    for (int i = 1; i <= n; i++) {
        if (!used[i]) return false;
    }
    reverse(ord.begin(), ord.end());
    for (int i = 0; i + 1 < ord.size(); i++) {
        if (edges.find(make_pair(ord[i], ord[i + 1])) == edges.end()) return false;
    }
    return true;
}

int main() {

    cin >> n >> m;

    for (int i = 1; i <= m; i++) {
        cin >> u[i] >> v[i];
    }

    int l = 1, r = m, last = -1;
    while (l <= r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            last = mid;
            r = mid - 1;
        } else l = mid + 1;
    }

    cout << last;

    return 0;
}


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

const int N = 1e5 + 10;

int u[N], v[N], n, m, deg[N];
bool used[N];
vector <int> g[N];

void dfs (int v) {
    used[v] = true;
    for (int i = 0; i < g[v].size(); i++) {
        int to = g[v][i];
        if (used[to]) continue;
        dfs(to);
    }
}

bool check (int sz) {
    for (int i = 0; i <= n; i++) g[i].clear(), deg[i] = 0, used[i] = false;
    for (int i = 1; i <= sz; i++) {
        g[u[i]].push_back(v[i]);
        deg[v[i]]++;
    }

    int mx = 0, cnt = 0;
    for (int i = 1; i <= n; i++) {
        if (deg[i] == 0) {
            mx = i;
            cnt++;
        }
    }
    if (cnt != 1) return false;
    dfs(mx);
    for (int i = 1; i <= n; i++) {
        if (!used[i]) return false;
    }
    return true;
}

int main() {

    cin >> n >> m;

    for (int i = 1; i <= m; i++) {
        cin >> u[i] >> v[i];
    }

    int l = 1, r = m, last = -1;

    while (l <= r) {
        int mid = (l + r) >> 1;
        if (check(mid)) {
            last = mid;
            r = mid - 1;
        } else l = mid + 1;
    }

    cout << last;

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vii;

vi vis;
vii edgeList;

int cnt;

void visit(int i) {
	vis[i] = 1;
	cnt++;
	for(int j=0; j<edgeList[i].size(); j++) {
		int u = edgeList[i][j];
		if (vis[u]==0) visit(u);
	}
}

int main() {
	int n, m, k, S, a, b;
	vi cc;

	cin >> n >> m >> k;

	vis.assign(n + 1, 0);
	edgeList.assign(n + 1, vi());

	for(int i=0; i<m; i++) {
		scanf("%d %d", &a, &b);
		edgeList[a].push_back(b);
		edgeList[b].push_back(a);
	}

	for(int i=1; i<=n; i++) {
		if (vis[i]==0) {
			cnt = 0;
			visit(i);
			cc.push_back(cnt);
		}
	}

	if (cc.size() == 1) printf("1\n");
	else {
		int res = 1;
		for(int i=0; i<cc.size(); i++) {
			res = (res * cc[i]) % k;
		}
		for(int i=0; i<cc.size()-2; i++) {
			res = (res * n) % k;
		}
		printf("%d\n", res);
	}
}


#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vii;

vi vis;
vii edgeList;

int cnt;

void visit(int i) {
	vis[i] = 1;
	cnt++;
	for(int j=0; j<edgeList[i].size(); j++) {
		int u = edgeList[i][j];
		if (vis[u]==0) visit(u);
	}
}

int main() {
	int n, m, k, S, a, b;
	vi cc;

	cin >> n >> m >> k;

	vis.assign(n + 1, 0);
	edgeList.assign(n + 1, vi());

	for(int i=0; i<m; i++) {
		scanf("%d %d", &a, &b);
		edgeList[a].push_back(b);
		edgeList[b].push_back(a);
	}

	for(int i=1; i<=n; i++) {
		if (vis[i]==0) {
			cnt = 0;
			visit(i);
			cc.push_back(cnt);
		}
	}

	if (cc.size() == 1) printf("1\n");
	else {
		int res = (1%k);
		for(int i=0; i<cc.size(); i++) {
			res = (res * cc[i]) % k;
		}
		for(int i=0; i<cc.size()-2; i++) {
			res = (res * n) % k;
		}
		printf("%d\n", res);
	}
}


#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vii;

vi vis;
vii edgeList;

int cnt;

void visit(int i) {
	vis[i] = 1;
	cnt++;
	for(int j=0; j<edgeList[i].size(); j++) {
		int u = edgeList[i][j];
		if (vis[u]==0) visit(u);
	}
}

int main() {
	int n, m, k, S, a, b;
	vi cc;

	cin >> n >> m >> k;

	vis.assign(n + 1, 0);
	edgeList.assign(n + 1, vi());

	for(int i=0; i<m; i++) {
		scanf("%d %d", &a, &b);
		edgeList[a].push_back(b);
		edgeList[b].push_back(a);
	}

	for(int i=1; i<=n; i++) {
		if (vis[i]==0) {
			cnt = 0;
			visit(i);
			cc.push_back(cnt);
		}
	}

	int res = 1;

	if (cc.size() == 1) printf("%d\n", res%k);

	else {
		for(int i=0; i<cc.size(); i++) {
			res = (res * cc[i]) % k;
		}
		for(int i=0; i<cc.size()-2; i++) {
			res = (res * n) % k;
		}
		printf("%d\n", res);
	}

}


#include<bits/stdc++.h>

using namespace std;

typedef vector<int> vi;
typedef vector<vi> vii;

vi vis;
vii edgeList;

int cnt;

void visit(int i) {
	vis[i] = 1;
	cnt++;
	for(int j=0; j<edgeList[i].size(); j++) {
		int u = edgeList[i][j];
		if (vis[u]==0) visit(u);
	}
}

int main() {
	int n, m, k, S, a, b;
	vi cc;

	cin >> n >> m >> k;

	vis.assign(n + 1, 0);
	edgeList.assign(n + 1, vi());

	for(int i=0; i<m; i++) {
		scanf("%d %d", &a, &b);
		edgeList[a].push_back(b);
		edgeList[b].push_back(a);
	}

	for(int i=1; i<=n; i++) {
		if (vis[i]==0) {
			cnt = 0;
			visit(i);
			cc.push_back(cnt);
		}
	}

	long long res = 1;

	if (cc.size() == 1) cout << (res%k) << "\n";

	else {
		for(int i=0; i<cc.size(); i++) {
			res = (res * cc[i]) % k;
		}
		for(int i=0; i<cc.size()-2; i++) {
			res = (res * n) % k;
		}
		cout << res << "\n";
	}

}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long LL;
const int N = 100010;
int fa[N], n, m, P, size[N], rank[N];
int getfa(int x){return fa[x] == x ? x : fa[x] = getfa(fa[x]);}

LL Pow(LL a, int b){
	if (b < 0) return 1;
	LL r = 1;
	while(b){
		if (b & 1) r = (LL) r * a % P;
		a = (LL) a * a % P;
		b >>= 1;
	}
	return r;
}

int main(){
	scanf("%d%d%d", &n, &m, &P);
	for(int i = 1; i <= n; i ++) fa[i] = i, size[i] = 1;
	int x, y;
	int num = 0;
	bool sign = 0;
	for(int i = 1; i <= m; i ++){
		scanf("%d%d", &x, &y);
		int fx = getfa(x), fy = getfa(y);
		if (fx == fy) {
			sign = 1;
			continue;
		}
		fa[fx] = fy;
		size[fy] += size[fx];
		num ++;
	}
	int ans = Pow(n, n - num - 2);
	for(int i = 1; i <= n; i ++) if (fa[i] == i) ans = (LL)ans * size[i] % P;
	if (num == n - 1) ans = 1;
	printf("%d\n", ans % P);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long LL;
const int N = 100010;
int fa[N], n, m, P, size[N], rank[N];
int getfa(int x){return fa[x] == x ? x : fa[x] = getfa(fa[x]);}

LL Pow(LL a, int b){
	if (b < 0) return 1;
	LL r = 1;
	while(b){
		if (b & 1) r = (LL) r * a % P;
		a = (LL) a * a % P;
		b >>= 1;
	}
	return r;
}

int main(){
	scanf("%d%d%d", &n, &m, &P);
	for(int i = 1; i <= n; i ++) fa[i] = i, size[i] = 1;
	int x, y;
	int num = 0;
	bool sign = 0;
	for(int i = 1; i <= m; i ++){
		scanf("%d%d", &x, &y);
		int fx = getfa(x), fy = getfa(y);
		if (fx == fy) {
			sign = 1;
			continue;
		}
		fa[fx] = fy;
		size[fy] += size[fx];
		num ++;
	}
	int ans = Pow(n, n - num - 2);
	for(int i = 1; i <= n; i ++) if (fa[i] == i) ans = (LL)ans * size[i] % P;
	if (num == n - 1) ans = (n == 1) ? 0 : 1;
	printf("%d\n", ans % P);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long LL;
const int N = 100010;
int fa[N], n, m, P, size[N], rank[N];
int getfa(int x){return fa[x] == x ? x : fa[x] = getfa(fa[x]);}

int Pow(int a, int b){
	if (b < 0) return 1;
	int r = 1;
	while(b){
		if (b & 1) r = (LL) r * a % P;
		a = (LL) a * a % P;
		b >>= 1;
	}
	return r;
}

int main(){
	scanf("%d%d%d", &n, &m, &P);
	for(int i = 1; i <= n; i ++) fa[i] = i, size[i] = 1;
	int x, y;
	int num = 0;
	for(int i = 1; i <= m; i ++){
		scanf("%d%d", &x, &y);
		int fx = getfa(x), fy = getfa(y);
		if (fx == fy) continue;
		fa[fx] = fy;
		size[fy] += size[fx];
		num ++;
	}
	int ans = Pow(n, n - num - 2);
	for(int i = 1; i <= n; i ++) if (fa[i] == i) ans = (LL)ans * size[i] % P;
	printf("%d\n", ans);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long LL;
const int N = 100010;
int fa[N], n, m, P, size[N], rank[N];
int getfa(int x){return fa[x] == x ? x : fa[x] = getfa(fa[x]);}

LL Pow(LL a, int b){
	if (b < 0) return 1;
	LL r = 1;
	while(b){
		if (b & 1) r = (LL) r * a % P;
		a = (LL) a * a % P;
		b >>= 1;
	}
	return r;
}

int main(){
	scanf("%d%d%d", &n, &m, &P);
	for(int i = 1; i <= n; i ++) fa[i] = i, size[i] = 1;
	int x, y;
	int num = 0;
	bool sign = 0;
	for(int i = 1; i <= m; i ++){
		scanf("%d%d", &x, &y);
		int fx = getfa(x), fy = getfa(y);
		if (fx == fy) {
			sign = 1;
			continue;
		}
		fa[fx] = fy;
		size[fy] += size[fx];
		num ++;
	}
	int ans = Pow(n, n - num - 2);
	for(int i = 1; i <= n; i ++) if (fa[i] == i) ans = (LL)ans * size[i] % P;
	if (num == n - 1) ans = (n == 1) ? 0 : 1;
	printf("%d\n", ans);
	return 0;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#define maxn 100005
using namespace std;

vector<int> adj[maxn];
int n,m,k,total = 0;
bool check[maxn];

void DFS(int u) {
    if (check[u]) return;
    check[u] = true;
    total++;
    for (int i = 0; i < adj[u].size(); i++) DFS(adj[u][i]);
}

int main() {
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 0; i < m; i++) {
        int u,v;
        scanf("%d %d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    long long ret = 1,comp = 0;
    for (int i = 1; i <= n; i++) if (!check[i]) {
        total = 0;
        comp++;
        DFS(i);
        ret = (ret * total) % k;
    }
    if (comp == 1) printf("%d\n", 1 % k); else {
          for (int i = 1; i <= comp - 2; i++) ret = (ret * n) % k;
      cout << ret << endl;
    }
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#define maxn 100005
using namespace std;

vector<int> adj[maxn];
int n,m,k,total = 0;
bool check[maxn];

void DFS(int u) {
    if (check[u]) return;
    check[u] = true;
    total++;
    for (int i = 0; i < adj[u].size(); i++) DFS(adj[u][i]);
}

int main() {
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 0; i < m; i++) {
        int u,v;
        scanf("%d %d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    long long ret = 1,comp = 0;
    for (int i = 1; i <= n; i++) if (!check[i]) {
        total = 0;
        comp++;
        DFS(i);
        ret = (ret * total) % k;
    }
    for (int i = 1; i <= comp - 2; i++) ret = (ret * n) % k;
    cout << ret << endl;
}


#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#define maxn 100005
using namespace std;

vector<int> adj[maxn];
int n,m,k,total = 0;
bool check[maxn];

void DFS(int u) {
    if (check[u]) return;
    check[u] = true;
    total++;
    for (int i = 0; i < adj[u].size(); i++) DFS(adj[u][i]);
}

int main() {
    scanf("%d %d %d", &n, &m, &k);
    for (int i = 0; i < m; i++) {
        int u,v;
        scanf("%d %d", &u, &v);
        adj[u].push_back(v);
        adj[v].push_back(u);
    }

    long long ret = 1,comp = 0;
    for (int i = 1; i <= n; i++) if (!check[i]) {
        total = 0;
        comp++;
        DFS(i);
        ret = (ret * total) % k;
    }
    if (comp == 1) printf("%d\n", 1 % k);
    for (int i = 1; i <= comp - 2; i++) ret = (ret * n) % k;
    cout << k << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define fr(a,b,c) for (int a=b;a<=c;a++)
#define frr(a,b,c) for (int a=b;a>=c;a--)
#define rep(a,b) for (int a=0;a<b;a++)
#define repp(a,b) for (int a=b-1;a>=0;a--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define oo 1000111222
using namespace std;

int need,n,m,base,d[100100],cnt[100100];
long long ans;

int get(int x)
{
	if (d[x]!=x) d[x]=get(d[x]);
	return d[x];
}

int main()
{
	cin >> n >> m >> base;
	fr(i,1,n) d[i]=i;
	need=n-1;
	while (m--)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		x=get(x); y=get(y);
		if (x!=y) d[x]=y, need--;
	}
	fr(i,1,n) cnt[get(i)]++;

	ans=1%base;
	fr(i,1,n)
		if (cnt[i]) ans=ans*cnt[i]%base;

	while (--need) ans=ans*n%base;
	cout << ans << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define fr(a,b,c) for (int a=b;a<=c;a++)
#define frr(a,b,c) for (int a=b;a>=c;a--)
#define rep(a,b) for (int a=0;a<b;a++)
#define repp(a,b) for (int a=b-1;a>=0;a--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define oo 1000111222
using namespace std;

int need,n,m,base,d[100100],cnt[100100];
long long ans;

int get(int x)
{
	if (d[x]!=x) d[x]=get(d[x]);
	return d[x];
}

int main()
{
	cin >> n >> m >> base;
	fr(i,1,n) d[i]=i;
	need=n-1;
	while (m--)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		x=get(x); y=get(y);
		if (x!=y) d[x]=y, need--;
	}
	fr(i,1,n) cnt[get(i)]++;

	ans=1%base;

	if (need>1)
	{
		fr(i,1,n)
			if (cnt[i]) ans=ans*cnt[i]%base;
		rep(i,need-1) ans=ans*n%base;
	}
	cout << ans << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define fr(a,b,c) for (int a=b;a<=c;a++)
#define frr(a,b,c) for (int a=b;a>=c;a--)
#define rep(a,b) for (int a=0;a<b;a++)
#define repp(a,b) for (int a=b-1;a>=0;a--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define oo 1000111222
using namespace std;

int need,n,m,base,d[100100],cnt[100100];
long long ans;

int get(int x)
{
	if (d[x]!=x) d[x]=get(d[x]);
	return d[x];
}

int main()
{
	cin >> n >> m >> base;
	fr(i,1,n) d[i]=i;
	need=n-1;
	while (m--)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		x=get(x); y=get(y);
		if (x!=y) d[x]=y, need--;
	}
	fr(i,1,n) cnt[get(i)]++;

	ans=1%base;
	fr(i,1,n)
		if (cnt[i]) ans=ans*cnt[i]%base;

	rep(i,need-1) ans=ans*n%base;
	cout << ans << endl;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
#include <cstring>
#include <string>
#include <cmath>
#include <utility>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define fr(a,b,c) for (int a=b;a<=c;a++)
#define frr(a,b,c) for (int a=b;a>=c;a--)
#define rep(a,b) for (int a=0;a<b;a++)
#define repp(a,b) for (int a=b-1;a>=0;a--)
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define sz(a) int(a.size())
#define all(a) a.begin(),a.end()
#define pii pair<int,int>
#define oo 1000111222
using namespace std;

int need,n,m,base,d[100100],cnt[100100];
long long ans;

int get(int x)
{
	if (d[x]!=x) d[x]=get(d[x]);
	return d[x];
}

int main()
{
	cin >> n >> m >> base;
	fr(i,1,n) d[i]=i;
	need=n-1;
	while (m--)
	{
		int x,y;
		scanf("%d%d",&x,&y);
		x=get(x); y=get(y);
		if (x!=y) d[x]=y, need--;
	}
	fr(i,1,n) cnt[get(i)]++;

	ans=1%base;

	if (need)
	{
		fr(i,1,n)
			if (cnt[i]) ans=ans*cnt[i]%base;
		rep(i,need-1) ans=ans*n%base;
	}
	cout << ans << endl;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <map>
#include <string.h>

const long long N=100010;
const long long inf=0x3f3f3f3f;

using namespace std;

long long n,m,k;
long long p[N],cnt[N];

long long find(long long x)
{
	if(x!=p[x]) p[x]=find(p[x]);
	return p[x];
}

int main()
{
	scanf("%lld%lld%lld",&n,&m,&k);
	for(long long i=0;i<=n;i++)
		p[i]=i;
	for(long long i=0;i<m;i++)
	{
		long long a,b;
		scanf("%lld%lld",&a,&b);
		if(find(a)!=find(b))
			p[find(a)]=find(b);
	}
	for(long long i=1;i<=n;i++)
		cnt[find(i)]++;
	long long ret=1,c=0;
	for(long long i=1;i<=n;i++)
		if(cnt[i]) c++,ret*=cnt[i],ret%=k;
	for(long long i=2;i<c;i++)
		ret*=n,ret%=k;
	if(c>1)
		printf("%lld\n",ret%k);
	else
		printf("%lld\n",1%k);
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <map>
#include <string.h>

const int N=100010;
const int inf=0x3f3f3f3f;

using namespace std;

int n,m,k;
int p[N],cnt[N];

int find(int x)
{
	if(x!=p[x]) p[x]=find(p[x]);
	return p[x];
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<=n;i++)
		p[i]=i;
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		if(find(a)!=find(b))
			p[find(a)]=find(b);
	}
	for(int i=1;i<=n;i++)
		cnt[find(i)]++;
	int ret=1,c=0;
	for(int i=1;i<=n;i++)
		if(cnt[i]) c++,ret*=cnt[i],ret%=k;
	for(int i=2;i<c;i++)
		ret*=n,ret%=k;
	if(c>1)
		printf("%d\n",ret%k);
	else
		printf("%d\n",1%k);
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <queue>
#include <map>
#include <string.h>

const int N=100010;
const int inf=0x3f3f3f3f;

using namespace std;

int n,m,k;
int p[N],cnt[N];

int find(int x)
{
	if(x!=p[x]) p[x]=find(p[x]);
	return p[x];
}

int main()
{
	scanf("%d%d%d",&n,&m,&k);
	for(int i=0;i<=n;i++)
		p[i]=i;
	for(int i=0;i<m;i++)
	{
		int a,b;
		scanf("%d%d",&a,&b);
		if(find(a)!=find(b))
			p[find(a)]=find(b);
	}
	for(int i=1;i<=n;i++)
		cnt[find(i)]++;
	int ret=1,c=0;
	for(int i=1;i<=n;i++)
		if(cnt[i]) c++,ret*=cnt[i],ret%=k;
	for(int i=2;i<c;i++)
		ret*=n,ret%=k;
	if(c>1)
		printf("%d\n",ret);
	else
		printf("1\n");
	return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <complex>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <string>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>

#define all(x) (x).begin(), (x).end()
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); it++)

#ifdef KAZAR
    #define eprintf(...) fprintf(stderr,__VA_ARGS__)
#else
    #define eprintf(...) 0
#endif

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;}

typedef long long ll;
typedef pair<int, int> ii;

const int inf = 1e9 + 143;
const ll 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(){

#ifdef KAZAR
    freopen("f.input","r",stdin);
    freopen("f.output","w",stdout);
    freopen("error","w",stderr);
#endif

    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){
        puts("1");
        return 0;
    }

    int res = 1;
    for(int i = 1; i <= (int)trees.size() - 2; i++)
        res = (ll)res * n % mod;
    for(int i = 0; i < trees.size(); i++)
        res = (ll)res * trees[i] % mod;

    printf("%d\n", res);

    return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <complex>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <string>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>

#define all(x) (x).begin(), (x).end()
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); it++)

#ifdef KAZAR
    #define eprintf(...) fprintf(stderr,__VA_ARGS__)
#else
    #define eprintf(...) 0
#endif

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;}

typedef long long ll;
typedef pair<int, int> ii;

const int inf = 1e9 + 143;
const ll 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(){

#ifdef KAZAR
    freopen("f.input","r",stdin);
    freopen("f.output","w",stdout);
    freopen("error","w",stderr);
#endif

    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){
        puts("0");
        return 0;
    }

    int res = 1;
    for(int i = 1; i <= (int)trees.size() - 2; i++)
        res = (ll)res * n % mod;
    for(int i = 0; i < trees.size(); i++)
        res = (ll)res * trees[i] % mod;

    printf("%d\n", res);

    return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <complex>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <string>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>

#define all(x) (x).begin(), (x).end()
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); it++)

#ifdef KAZAR
    #define eprintf(...) fprintf(stderr,__VA_ARGS__)
#else
    #define eprintf(...) 0
#endif

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;}

typedef long long ll;
typedef pair<int, int> ii;

const int inf = 1e9 + 143;
const ll 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(){

#ifdef KAZAR
    freopen("f.input","r",stdin);
    freopen("f.output","w",stdout);
    freopen("error","w",stderr);
#endif

    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 = (ll)res * n % mod;
    for(int i = 0; i < trees.size(); i++)
        res = (ll)res * trees[i] % mod;

    printf("%d\n", res);

    return 0;
}


#include <algorithm>
#include <iostream>
#include <iomanip>
#include <cstring>
#include <complex>
#include <cassert>
#include <cstdlib>
#include <cstdio>
#include <bitset>
#include <vector>
#include <string>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>

#define all(x) (x).begin(), (x).end()
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); it++)

#ifdef KAZAR
    #define eprintf(...) fprintf(stderr,__VA_ARGS__)
#else
    #define eprintf(...) 0
#endif

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;}

typedef long long ll;
typedef pair<int, int> ii;

const int inf = 1e9 + 143;
const ll 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(){

#ifdef KAZAR
    freopen("f.input","r",stdin);
    freopen("f.output","w",stdout);
    freopen("error","w",stderr);
#endif

    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){
        return 1;
    }

    int res = 1;
    for(int i = 1; i <= trees.size() - 2; i++)
        res = (ll)res * n % mod;
    for(int i = 0; i < trees.size(); i++)
        res = (ll)res * trees[i] % mod;

    printf("%d\n", res);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <stack>
#include <cstring>
#include <iomanip>
#include <ctime>
using namespace std;
#define pb push_back
#define INF 1000000000
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mp make_pair
#define pii pair<int,int>
#define ll long long
#define vi vector<int>
#define SZ(x) ((int)(x.size()))
#define fi first
#define se second
#define wez(n) int (n); scanf("%d",&(n));
#define wez2(n,m) int (n),(m); scanf("%d %d",&(n),&(m));
#define wez3(n,m,k) int (n),(m),(k); scanf("%d %d %d",&(n),&(m),&(k));
inline void pisz(int n) { printf("%d\n",n); }
template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
template<typename T> ostream& operator<<(ostream &s,vector<T> t){FOR(i,SZ(t))s<<t[i]<<" ";return s; }
#define IN(x,y) ((y).find((x))!=(y).end())
#define DBG(vari) cerr<<#vari<<" = "<<(vari)<<endl;
#define ALL(t) t.begin(),t.end()
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define TESTS wez(testow)while(testow--)
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define REPD(i,a,b) for(int (i)=(a); (i)>=(b);--i)
#define REMAX(a,b) (a)=max((a),(b));
#define REMIN(a,b) (a)=min((a),(b));
#define IOS ios_base::sync_with_stdio(0);

vector<int> podziel_na_skladowe (int n, vi *adj) {
	vector<bool> vis(n+1,0);
	vector<int> wyn;
	FORI(i,n) {
		if (vis[i]) continue;
		int skladowa = 0;
		deque<int> q;
		q.pb(i);
		while (!q.empty()) {
			int v = q.front();
			q.pop_front();
			if (vis[v]) continue;
			vis[v]=1;
			skladowa++;
			FOR(j,SZ(adj[v])) q.pb(adj[v][j]);
		}
		wyn.pb(skladowa);
	}
	return wyn;
}

vi adj[100006];

int main () {
   wez3(n,m,mod)
   while(m--) {
      wez2(a,b)
      adj[a].pb(b);
      adj[b].pb(a);
   }
   vi skl = podziel_na_skladowe(n,adj);
   //DBG(skl)
   if (SZ(skl) == 1) {
      pisz(1);
   } else {
      ll res = 1;
      FOREACH(x,skl) res = (res * (*x)) % mod;
      int ile = SZ(skl) - 2;
      while (ile--) res = (res * n) % mod;
      if (res < 0) res += mod;
      pisz(res);
   }
}


#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <stack>
#include <cstring>
#include <iomanip>
#include <ctime>
using namespace std;
#define pb push_back
#define INF 1000000000
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mp make_pair
#define pii pair<int,int>
#define ll long long
#define vi vector<int>
#define SZ(x) ((int)(x.size()))
#define fi first
#define se second
#define wez(n) int (n); scanf("%d",&(n));
#define wez2(n,m) int (n),(m); scanf("%d %d",&(n),&(m));
#define wez3(n,m,k) int (n),(m),(k); scanf("%d %d %d",&(n),&(m),&(k));
inline void pisz(int n) { printf("%d\n",n); }
template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
template<typename T> ostream& operator<<(ostream &s,vector<T> t){FOR(i,SZ(t))s<<t[i]<<" ";return s; }
#define IN(x,y) ((y).find((x))!=(y).end())
#define DBG(vari) cerr<<#vari<<" = "<<(vari)<<endl;
#define ALL(t) t.begin(),t.end()
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define TESTS wez(testow)while(testow--)
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define REPD(i,a,b) for(int (i)=(a); (i)>=(b);--i)
#define REMAX(a,b) (a)=max((a),(b));
#define REMIN(a,b) (a)=min((a),(b));
#define IOS ios_base::sync_with_stdio(0);

// graf o wierzchołkach 1..n (0..n-1 -> zmienic FORI na FOR)

vector<int> podziel_na_skladowe (int n, vi *adj) {
	vector<bool> vis(n+1,0);
	vector<int> wyn;
	FORI(i,n) {
		if (vis[i]) continue;
		int skladowa = 0;
		deque<int> q;
		q.pb(i);
		while (!q.empty()) {
			int v = q.front();
			q.pop_front();
			if (vis[v]) continue;
			vis[v]=1;
			skladowa++;
			FOR(j,SZ(adj[v])) q.pb(adj[v][j]);
		}
		wyn.pb(skladowa);
	}
	return wyn;
}

vi adj[100006];

int main () {
   wez3(n,m,mod)
   while(m--) {
      wez2(a,b)
      adj[a].pb(b);
      adj[b].pb(a);
   }
   ll res = 1;
   vi skl = podziel_na_skladowe(n,adj);
   if (SZ(skl) == 1) {
      pisz(1);
   } else {
      FOREACH(x,skl) res = (res * (*x)) % mod;
      int ile = SZ(skl) - 2;
      while (ile--) res = (res * n) % mod;
      pisz(res);
   }
}


#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <stack>
#include <cstring>
#include <iomanip>
#include <ctime>
using namespace std;
#define pb push_back
#define INF 1000000000
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mp make_pair
#define pii pair<int,int>
#define ll long long
#define vi vector<int>
#define SZ(x) ((int)(x.size()))
#define fi first
#define se second
#define wez(n) int (n); scanf("%d",&(n));
#define wez2(n,m) int (n),(m); scanf("%d %d",&(n),&(m));
#define wez3(n,m,k) int (n),(m),(k); scanf("%d %d %d",&(n),&(m),&(k));
inline void pisz(int n) { printf("%d\n",n); }
template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
template<typename T> ostream& operator<<(ostream &s,vector<T> t){FOR(i,SZ(t))s<<t[i]<<" ";return s; }
#define IN(x,y) ((y).find((x))!=(y).end())
#define DBG(vari) cerr<<#vari<<" = "<<(vari)<<endl;
#define ALL(t) t.begin(),t.end()
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define TESTS wez(testow)while(testow--)
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define REPD(i,a,b) for(int (i)=(a); (i)>=(b);--i)
#define REMAX(a,b) (a)=max((a),(b));
#define REMIN(a,b) (a)=min((a),(b));
#define IOS ios_base::sync_with_stdio(0);

#define N 1000006
vi adj[N];
bool seen[N];

int main () {
   wez3(n,m,k)
   while (m--) {
      wez2(a,b)
      adj[a].pb(b);
      adj[b].pb(a);
   }
   FORI(i,n) seen[i] = 0;
   vi skl;
   FORI(i,n) {
      if (seen[i]) continue;
      int s = 0;
      deque<int> q;
      q.pb(i);
      while (!q.empty()) {
         int v = q.front();
         q.pop_front();
         if (seen[v]) continue;
         seen[v] = 1;
         s++;
         FOREACH(x,adj[v]) q.pb(*x);
      }
      skl.pb(s);
   }
   int sum = 0;
   FOREACH(x,skl) sum += *x;
   //DBG(n == sum)

   if (SZ(skl) == 1) {
      pisz(1);
   } else {
      int res = 1;
      FOREACH(x,skl) res = (((ll)res) * (*x)) % k;
      FOR(u,SZ(skl)-2) res = (((ll)res) * n) % k;
      if (res < 0) res += k;
      pisz(res);
   }
}


#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <stack>
#include <cstring>
#include <iomanip>
#include <ctime>
using namespace std;
#define pb push_back
#define INF 1000000000
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mp make_pair
#define pii pair<int,int>
#define ll long long
#define vi vector<int>
#define SZ(x) ((int)(x.size()))
#define fi first
#define se second
#define wez(n) int (n); scanf("%d",&(n));
#define wez2(n,m) int (n),(m); scanf("%d %d",&(n),&(m));
#define wez3(n,m,k) int (n),(m),(k); scanf("%d %d %d",&(n),&(m),&(k));
inline void pisz(int n) { printf("%d\n",n); }
template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
template<typename T> ostream& operator<<(ostream &s,vector<T> t){FOR(i,SZ(t))s<<t[i]<<" ";return s; }
#define IN(x,y) ((y).find((x))!=(y).end())
#define DBG(vari) cerr<<#vari<<" = "<<(vari)<<endl;
#define ALL(t) t.begin(),t.end()
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define TESTS wez(testow)while(testow--)
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define REPD(i,a,b) for(int (i)=(a); (i)>=(b);--i)
#define REMAX(a,b) (a)=max((a),(b));
#define REMIN(a,b) (a)=min((a),(b));
#define IOS ios_base::sync_with_stdio(0);

// graf o wierzchołkach 1..n (0..n-1 -> zmienic FORI na FOR)

vector<int> podziel_na_skladowe (int n, vi *adj) {
	vector<bool> vis(n+1,0);
	vector<int> wyn;
	FORI(i,n) {
		if (vis[i]) continue;
		int skladowa = 0;
		deque<int> q;
		q.pb(i);
		while (!q.empty()) {
			int v = q.front();
			q.pop_front();
			if (vis[v]) continue;
			vis[v]=1;
			skladowa++;
			FOR(j,SZ(adj[v])) q.pb(adj[v][j]);
		}
		wyn.pb(skladowa);
	}
	return wyn;
}

vi adj[100006];

int main () {
   wez3(n,m,mod)
   while(m--) {
      wez2(a,b)
      adj[a].pb(b);
      adj[b].pb(a);
   }
   ll res = 1;
   vi skl = podziel_na_skladowe(n,adj);
   if (SZ(skl) == 1) {
      pisz(1%mod);
   } else {
      FOREACH(x,skl) res = (res * (*x)) % mod;
      int ile = SZ(skl) - 2;
      while (ile--) res = (res * n) % mod;
      pisz(res);
   }
}


#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <cmath>
#include <algorithm>
#include <sstream>
#include <stack>
#include <cstring>
#include <iomanip>
#include <ctime>
using namespace std;
#define pb push_back
#define INF 1000000000
#define FOR(i,n) for(int (i)=0;(i)<(n);++(i))
#define FORI(i,n) for(int (i)=1;(i)<=(n);++(i))
#define mp make_pair
#define pii pair<int,int>
#define ll long long
#define vi vector<int>
#define SZ(x) ((int)(x.size()))
#define fi first
#define se second
#define wez(n) int (n); scanf("%d",&(n));
#define wez2(n,m) int (n),(m); scanf("%d %d",&(n),&(m));
#define wez3(n,m,k) int (n),(m),(k); scanf("%d %d %d",&(n),&(m),&(k));
inline void pisz(int n) { printf("%d\n",n); }
template<typename T,typename TT> ostream& operator<<(ostream &s,pair<T,TT> t) {return s<<"("<<t.first<<","<<t.second<<")";}
template<typename T> ostream& operator<<(ostream &s,vector<T> t){FOR(i,SZ(t))s<<t[i]<<" ";return s; }
#define IN(x,y) ((y).find((x))!=(y).end())
#define DBG(vari) cerr<<#vari<<" = "<<(vari)<<endl;
#define ALL(t) t.begin(),t.end()
#define FOREACH(i,t) for (typeof(t.begin()) i=t.begin(); i!=t.end(); i++)
#define TESTS wez(testow)while(testow--)
#define REP(i,a,b) for(int (i)=(a);(i)<=(b);++i)
#define REPD(i,a,b) for(int (i)=(a); (i)>=(b);--i)
#define REMAX(a,b) (a)=max((a),(b));
#define REMIN(a,b) (a)=min((a),(b));
#define IOS ios_base::sync_with_stdio(0);

// graf o wierzchołkach 1..n (0..n-1 -> zmienic FORI na FOR)

vector<int> podziel_na_skladowe (int n, vi *adj) {
	vector<bool> vis(n+1,0);
	vector<int> wyn;
	FORI(i,n) {
		if (vis[i]) continue;
		int skladowa = 0;
		deque<int> q;
		q.pb(i);
		while (!q.empty()) {
			int v = q.front();
			q.pop_front();
			if (vis[v]) continue;
			vis[v]=1;
			skladowa++;
			FOR(j,SZ(adj[v])) q.pb(adj[v][j]);
		}
		wyn.pb(skladowa);
	}
	return wyn;
}

vi adj[100006];

int main () {
   wez3(n,m,mod)
   DBG(mp(n,m))
   while(m--) {
      wez2(a,b)
      adj[a].pb(b);
      adj[b].pb(a);
   }
   ll res = 1;
   vi skl = podziel_na_skladowe(n,adj);
   if (SZ(skl) == 1) {
      pisz(1%mod);
   } else {
      FOREACH(x,skl) res = (res * (*x)) % mod;
      int ile = SZ(skl) - 2;
      while (ile--) res = (res * n) % mod;
      pisz(res);
   }
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long LL;

const int maxn = 100005;

int nbs[maxn] , next[maxn*2] , ev[maxn*2] , n , m , k , mod;
bool view[maxn];

void addedge( int x , int y )
{
	next[++k] = nbs[x];
	ev[k] = y;
	nbs[x] = k;
}

void init()
{
	scanf( "%d%d%d" , &n , &m , &mod );
	while (m--) {
		int x , y;
		scanf( "%d%d" , &x , &y );
		addedge(x,y);
		addedge(y,x);
	}
}

int dfs( int x )
{
	if ( view[x] ) return 0;
	view[x] = 1;
	int ret = 1;
	for ( int i = nbs[x]; i; i = next[i] ) ret += dfs(ev[i]);
	return ret;
}

void work()
{
	LL s = 1;
	int tot = 0;
	for ( int i = 1; i <= n; i++ ) {
		int t = dfs(i);
		if ( !t ) continue;
		s = ( s * t ) % mod;
		tot++;
	}
	for ( int i = 0; i < tot-2; i++ ) s = ( s * n ) % mod;
	cout << s << endl;
}

int main()
{
	init();
	work();
	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long LL;

const int maxn = 100005;

int nbs[maxn] , next[maxn*2] , ev[maxn*2] , n , m , k , mod;
bool view[maxn];

void addedge( int x , int y )
{
    next[++k] = nbs[x];
    ev[k] = y;
    nbs[x] = k;
}

void init()
{
    scanf( "%d%d%d" , &n , &m , &mod );
    while (m--) {
        int x , y;
        scanf( "%d%d" , &x , &y );
        addedge(x,y);
        addedge(y,x);
    }
}

int dfs( int x )
{
    if ( view[x] ) return 0;
    view[x] = 1;
    int ret = 1;
    for ( int i = nbs[x]; i; i = next[i] ) ret += dfs(ev[i]);
    return ret;
}

void work()
{
    LL s = 1;
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        int t = dfs(i);
        if ( !t ) continue;
        s = ( s * t ) % mod;
        tot++;
    }
    for ( int i = 0; i < tot-2; i++ ) s = ( s * n ) % mod;
    if ( tot == 1 ) s = 1 % mod;
    cout << s << endl;
}

int main()
{
    init();
    work();
    return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long LL;

const int maxn = 100005;

int nbs[maxn] , next[maxn*2] , ev[maxn*2] , n , m , k , mod;
bool view[maxn];

void addedge( int x , int y )
{
    next[++k] = nbs[x];
    ev[k] = y;
    nbs[x] = k;
}

void init()
{
    scanf( "%d%d%d" , &n , &m , &mod );
    while (m--) {
        int x , y;
        scanf( "%d%d" , &x , &y );
        addedge(x,y);
        addedge(y,x);
    }
}

int dfs( int x )
{
    if ( view[x] ) return 0;
    view[x] = 1;
    int ret = 1;
    for ( int i = nbs[x]; i; i = next[i] ) ret += dfs(ev[i]);
    return ret;
}

void work()
{
    LL s = 1;
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        int t = dfs(i);
        if ( !t ) continue;
        s = ( s * t ) % mod;
        tot++;
    }
    for ( int i = 0; i < tot-2; i++ ) s = ( s * n ) % mod;
    if ( n > 1 && tot == 1 ) s = 1 % mod;
    cout << s << endl;
}

int main()
{
    init();
    work();
    return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long LL;

const int maxn = 100005;

int nbs[maxn] , next[maxn*2] , ev[maxn*2] , n , m , k , mod;
bool view[maxn];

void addedge( int x , int y )
{
    next[++k] = nbs[x];
    ev[k] = y;
    nbs[x] = k;
}

void init()
{
    scanf( "%d%d%d" , &n , &m , &mod );
    while (m--) {
        int x , y;
        scanf( "%d%d" , &x , &y );
        addedge(x,y);
        addedge(y,x);
    }
}

int dfs( int x )
{
    if ( view[x] ) return 0;
    view[x] = 1;
    int ret = 1;
    for ( int i = nbs[x]; i; i = next[i] ) ret += dfs(ev[i]);
    return ret;
}

void work()
{
    LL s = 1;
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        int t = dfs(i);
        if ( !t ) continue;
        s = ( s * t ) % mod;
        tot++;
    }
    for ( int i = 0; i < tot-2; i++ ) s = ( s * n ) % mod;
    if ( tot == 1 ) s = 0;
    cout << s << endl;
}

int main()
{
    init();
    work();
    return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long LL;

const int maxn = 100005;

int nbs[maxn] , next[maxn*2] , ev[maxn*2] , n , m , k , mod;
bool view[maxn];

void addedge( int x , int y )
{
	next[++k] = nbs[x];
	ev[k] = y;
	nbs[x] = k;
}

void init()
{
	scanf( "%d%d%d" , &n , &m , &mod );
	while (m--) {
		int x , y;
		scanf( "%d%d" , &x , &y );
		addedge(x,y);
		addedge(y,x);
	}
}

int dfs( int x )
{
	if ( view[x] ) return 0;
	view[x] = 1;
	int ret = 1;
	for ( int i = nbs[x]; i; i = next[i] ) ret += dfs(ev[i]);
	return ret;
}

void work()
{
	LL s = 1;
	int tot = 0;
	for ( int i = 1; i <= n; i++ ) {
		int t = dfs(i);
		if ( !t ) continue;
		s = ( s * t ) % mod;
		tot++;
	}
	for ( int i = 0; i < tot-2; i++ ) s = ( s * n ) % mod;
	if ( tot == 1 ) s = 1;
	cout << s << endl;
}

int main()
{
	init();
	work();
	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

typedef long long LL;

const int maxn = 100005;

int nbs[maxn] , next[maxn*2] , ev[maxn*2] , n , m , k , mod;
bool view[maxn];

void addedge( int x , int y )
{
    next[++k] = nbs[x];
    ev[k] = y;
    nbs[x] = k;
}

void init()
{
    scanf( "%d%d%d" , &n , &m , &mod );
    while (m--) {
        int x , y;
        scanf( "%d%d" , &x , &y );
        addedge(x,y);
        addedge(y,x);
    }
}

int dfs( int x )
{
    if ( view[x] ) return 0;
    view[x] = 1;
    int ret = 1;
    for ( int i = nbs[x]; i; i = next[i] ) ret += dfs(ev[i]);
    return ret;
}

void work()
{
    LL s = 1;
    int tot = 0;
    for ( int i = 1; i <= n; i++ ) {
        int t = dfs(i);
        if ( !t ) continue;
        s = ( s * t ) % mod;
        tot++;
    }
    for ( int i = 0; i < tot-2; i++ ) s = ( s * n ) % mod;
    if ( n > 1 && tot == 1 ) s = 1;
    cout << s << endl;
}

int main()
{
    init();
    work();
    return 0;
}


#include <vector>
#include <iostream>
#include <stdint.h>

using namespace std;

const int MAX = 100005;
int m, n;
int64_t k;

vector<vector<int> > graph;
bool visited[MAX];
int64_t dfs(int node) {
  int64_t size = 1;
  visited[node] = true;
  for (int i = 0; i < graph[node].size(); i++) {
    if (!visited[graph[node][i]]) {
      size += dfs(graph[node][i]);
    }
  }
  return size;
}

int main(int argc, char ** argv) {
  cin >> n >> m >> k;

  vector<int> empty;
  for (int i = 0; i < n; i++) {
    graph.push_back(empty);
  }

  for (int i = 0; i < m; i++) {
    int b, e;
    cin >> b >> e;
    b--, e--;
    graph[b].push_back(e);
    graph[e].push_back(b);
  }

  vector<int64_t> comps;
  for (int i = 0; i < n; i++) {
    if (!visited[i]) {
      int64_t card = dfs(i);
      comps.push_back(card);
    }
  }

  int64_t sum = 0;
  int64_t prod = 1;
  for (int i = 0; i < comps.size(); ++i) {
    sum += comps[i]; sum %= k;
    prod *= comps[i]; prod %= k;
  }

  if (comps.size() == 1) {
    cout << (1 % k) << endl;
  } else {
    int64_t rez = 1;
    for (int i = 0; i + 2 < comps.size(); ++i) {
      rez *= sum; rez %= k;
    }
    rez *= prod; rez %= k;
    cout << rez << endl;
  }

  return 0;
}


#include <vector>
#include <iostream>
#include <stdint.h>

using namespace std;

const int MAX = 100005;
int m, n;
int64_t k;

vector<vector<int> > graph;
bool visited[MAX];
int64_t dfs(int node) {
  int64_t size = 1;
  visited[node] = true;
  for (int i = 0; i < graph[node].size(); i++) {
    if (!visited[graph[node][i]]) {
      size += dfs(graph[node][i]);
    }
  }
  return size;
}

int main(int argc, char ** argv) {
  cin >> n >> m >> k;

  vector<int> empty;
  for (int i = 0; i < n; i++) {
    graph.push_back(empty);
  }

  for (int i = 0; i < m; i++) {
    int b, e;
    cin >> b >> e;
    b--, e--;
    graph[b].push_back(e);
    graph[e].push_back(b);
  }

  vector<int64_t> comps;
  for (int i = 0; i < n; i++) {
    if (!visited[i]) {
      int64_t card = dfs(i);
      comps.push_back(card);
    }
  }

  int64_t sum = 0;
  int64_t prod = 1;
  for (int i = 0; i < comps.size(); ++i) {
    sum += comps[i]; sum %= k;
    prod *= comps[i]; prod %= k;
  }

  int64_t rez = 1;
  for (int i = 0; i < comps.size()-2; ++i) {
    rez *= sum; rez %= k;
  }
  rez *= prod; rez %= k;
  cout << rez << endl;

  return 0;
}


#include <vector>
#include <iostream>
#include <stdint.h>

using namespace std;

const int MAX = 100005;
int m, n;
int64_t k;

vector<vector<int> > graph;
bool visited[MAX];
int64_t dfs(int node) {
  int64_t size = 1;
  visited[node] = true;
  for (int i = 0; i < graph[node].size(); i++) {
    if (!visited[graph[node][i]]) {
      size += dfs(graph[node][i]);
    }
  }
  return size;
}

int main(int argc, char ** argv) {
  cin >> n >> m >> k;

  vector<int> empty;
  for (int i = 0; i < n; i++) {
    graph.push_back(empty);
  }

  for (int i = 0; i < m; i++) {
    int b, e;
    cin >> b >> e;
    b--, e--;
    graph[b].push_back(e);
    graph[e].push_back(b);
  }

  vector<int64_t> comps;
  for (int i = 0; i < n; i++) {
    if (!visited[i]) {
      int64_t card = dfs(i);
      comps.push_back(card);
    }
  }

  int64_t sum = 0;
  int64_t prod = 1;
  for (int i = 0; i < comps.size(); ++i) {
    sum += comps[i]; sum %= k;
    prod *= comps[i]; prod %= k;
  }

  if (comps.size() == 1) {
    cout << "1" << endl;
  } else {
    int64_t rez = 1;
    for (int i = 0; i + 2 < comps.size(); ++i) {
      rez *= sum; rez %= k;
    }
    rez *= prod; rez %= k;
    cout << rez << endl;
  }

  return 0;
}


#include <vector>
#include <iostream>
#include <stdint.h>

using namespace std;

const int MAX = 100005;
int m, n;
int64_t k;

vector<vector<int> > graph;
bool visited[MAX];
int64_t dfs(int node) {
  int64_t size = 1;
  visited[node] = true;
  for (int i = 0; i < graph[node].size(); i++) {
    if (!visited[graph[node][i]]) {
      size += dfs(graph[node][i]);
    }
  }
  return size;
}

int main(int argc, char ** argv) {
  cin >> n >> m >> k;

  vector<int> empty;
  for (int i = 0; i < n; i++) {
    graph.push_back(empty);
  }

  for (int i = 0; i < m; i++) {
    int b, e;
    cin >> b >> e;
    b--, e--;
    graph[b].push_back(e);
    graph[e].push_back(b);
  }

  vector<int64_t> comps;
  for (int i = 0; i < n; i++) {
    if (!visited[i]) {
      int64_t card = dfs(i);
      comps.push_back(card);
    }
  }

  int64_t sum = 0;
  int64_t prod = 1;
  for (int i = 0; i < comps.size(); ++i) {
    sum += comps[i]; sum %= k;
    prod *= comps[i]; prod %= k;
  }

  int64_t rez = 1;
  for (int i = 0; i + 2 < comps.size(); ++i) {
    rez *= sum; rez %= k;
  }
  rez *= prod; rez %= k;
  cout << rez << endl;

  return 0;
}


#pragma comment(linker, "/STACK:65777216")
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <queue>
#include <string>
#include <memory.h>
#include <iterator>
#define y1 trololoy1
#define y0 trololoy0
#define mem(A,X) memset(A,X,sizeof(A))
#define memo(A) memset(A,0,sizeof(A))
#define forn(I,B) for (int I=1;I<=(B);I++)
#define forg(H,V) for (int H=first[V];h;h=next[H])
#define rep(I,B) for (int I=0;I<(B);I++)
#define labs(X) (((X)>0)?(X):(-(X)))
#define ropen(X) freopen(X,"r",stdin)
#define wopen(X) freopen(X,"w",stdout)
#define rwopen(X) freopen(X".in","r",stdin);freopen(X".out","w",stdout)
#define pb push_back
#define mp make_pair
#define all(X) (X).begin(),(X).end()
#define sqr(X) ((X)*(X))

using namespace std;

typedef pair <int,int> pii;
typedef double ld;
typedef long long ll;
typedef pair <ll,ll> pll;
typedef vector<int> vi;
const int N=222222;
const int INF=111111111;
const double eps=1e-9;
const double pi=3.14159265358979;

int n,m,k,es[N],next[N],first[N],c,s[N],q;
bool b[N];
ll ans=1;

inline void add(int x,int y){
	next[++c]=first[x];first[x]=c;
	es[c]=y;
	swap(x,y);
	next[++c]=first[x];first[x]=c;
	es[c]=y;
}

void dfs(int v){
	b[v]=1;
	++s[q];
	forg(h,v) if (!b[es[h]]) dfs(es[h]);
}

int main(){
	scanf("%d%d%d",&n,&m,&k);
	forn(i,m){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
	}
	forn(i,n) if (!b[i]){
		dfs(i);
		ans=(ans*s[q])%k;
		++q;
	}
	forn(i,q-2) ans=(ans*n)%k;
	printf("%I64d\n",ans);
	return 0;
}


#pragma comment(linker, "/STACK:65777216")
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <queue>
#include <string>
#include <memory.h>
#include <iterator>
#define y1 trololoy1
#define y0 trololoy0
#define mem(A,X) memset(A,X,sizeof(A))
#define memo(A) memset(A,0,sizeof(A))
#define forn(I,B) for (int I=1;I<=(B);I++)
#define forg(H,V) for (int H=first[V];h;h=next[H])
#define rep(I,B) for (int I=0;I<(B);I++)
#define labs(X) (((X)>0)?(X):(-(X)))
#define ropen(X) freopen(X,"r",stdin)
#define wopen(X) freopen(X,"w",stdout)
#define rwopen(X) freopen(X".in","r",stdin);freopen(X".out","w",stdout)
#define pb push_back
#define mp make_pair
#define all(X) (X).begin(),(X).end()
#define sqr(X) ((X)*(X))

using namespace std;

typedef pair <int,int> pii;
typedef double ld;
typedef long long ll;
typedef pair <ll,ll> pll;
typedef vector<int> vi;
const int N=222222;
const int INF=111111111;
const double eps=1e-9;
const double pi=3.14159265358979;

int n,m,k,es[N],next[N],first[N],c,s[N],q;
bool b[N];
ll ans=1;

inline void add(int x,int y){
	next[++c]=first[x];first[x]=c;
	es[c]=y;
	swap(x,y);
	next[++c]=first[x];first[x]=c;
	es[c]=y;
}

void dfs(int v){
	b[v]=1;
	++s[q];
	forg(h,v) if (!b[es[h]]) dfs(es[h]);
}

int main(){
	scanf("%d%d%d",&n,&m,&k);
	forn(i,m){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
	}
	forn(i,n) if (!b[i]){
		dfs(i);
		ans=(ans*s[q])%k;
		++q;
	}
	forn(i,q-2) ans=(ans*n)%k;
	if (q==1) ans=1;
	printf("%I64d\n",ans);
	return 0;
}


#pragma comment(linker, "/STACK:65777216")
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <ctime>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <stack>
#include <map>
#include <queue>
#include <string>
#include <memory.h>
#include <iterator>
#define y1 trololoy1
#define y0 trololoy0
#define mem(A,X) memset(A,X,sizeof(A))
#define memo(A) memset(A,0,sizeof(A))
#define forn(I,B) for (int I=1;I<=(B);I++)
#define forg(H,V) for (int H=first[V];h;h=next[H])
#define rep(I,B) for (int I=0;I<(B);I++)
#define labs(X) (((X)>0)?(X):(-(X)))
#define ropen(X) freopen(X,"r",stdin)
#define wopen(X) freopen(X,"w",stdout)
#define rwopen(X) freopen(X".in","r",stdin);freopen(X".out","w",stdout)
#define pb push_back
#define mp make_pair
#define all(X) (X).begin(),(X).end()
#define sqr(X) ((X)*(X))

using namespace std;

typedef pair <int,int> pii;
typedef double ld;
typedef long long ll;
typedef pair <ll,ll> pll;
typedef vector<int> vi;
const int N=222222;
const int INF=111111111;
const double eps=1e-9;
const double pi=3.14159265358979;

int n,m,k,es[N],next[N],first[N],c,s[N],q;
bool b[N];
ll ans=1;

inline void add(int x,int y){
	next[++c]=first[x];first[x]=c;
	es[c]=y;
	swap(x,y);
	next[++c]=first[x];first[x]=c;
	es[c]=y;
}

void dfs(int v){
	b[v]=1;
	++s[q];
	forg(h,v) if (!b[es[h]]) dfs(es[h]);
}

int main(){
	scanf("%d%d%d",&n,&m,&k);
	forn(i,m){
		int x,y;
		scanf("%d%d",&x,&y);
		add(x,y);
	}
	forn(i,n) if (!b[i]){
		dfs(i);
		ans=(ans*s[q])%k;
		++q;
	}
	forn(i,q-2) ans=(ans*n)%k;
	if (q==1) ans=1%k;
	printf("%I64d\n",ans);
	return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <cstdio>
#include <algorithm>

#define pb push_back
#define mp make_pair
#define FOR(i,a,b) for (int i = (a); (i) <= (b); (i)++)
using namespace std;

int n,m;
long long ans,mod;
int p[100002],d[100002],tmp[100002];

inline int findset(int x)
{
    int cnt = 0;
    while (p[x] != x)
    {
        cnt++;
        tmp[cnt] = x;
        x = p[x];
    }
    FOR(i,1,cnt) p[tmp[i]] = x;
    return x;
}

inline void unite(int x, int y)
{
    x = findset(x);
    y = findset(y);
    if ((x+y)&1) p[x] = y;
        else p[y] = x;
}

int main()
{
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    cin >> n >> m >> mod;
    FOR(i,1,n) p[i] = i;
    FOR(i,1,m)
    {
        int x,y;
        cin >> x >> y;
        unite(x,y);
    }
    FOR(i,1,n)
    d[findset(i)]++;
    ans = 1;
    int kil = 0;
    FOR(i,1,n)
     if (d[i] !=0)
    {
        kil++;
        ans = ((long long )d[i]*ans) % mod;
    }
    FOR(i,1,kil-2)
    ans = (ans*(long long)n) % mod;
    if (kil == 1) ans = 1;
    cout << ans%mod << endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <cstdio>
#include <algorithm>

#define pb push_back
#define mp make_pair
#define FOR(i,a,b) for (int i = (a); (i) <= (b); (i)++)
using namespace std;

int n,m;
long long ans,mod;
int p[100002],d[100002];

inline int findset(int x)
{
    while (p[x] != x) x = p[x];
    return x;
}

inline void unite(int x, int y)
{
    x = findset(x);
    y = findset(y);
    if ((x+y)&1) p[x] = y;
        else p[y] = x;
}

int main()
{
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    cin >> n >> m >> mod;
    FOR(i,1,n) p[i] = i;
    FOR(i,1,m)
    {
        int x,y;
        cin >> x >> y;
        unite(x,y);
    }
    FOR(i,1,n)
    d[findset(i)]++;
    ans = 1;
    int kil = 0;
    FOR(i,1,n)
     if (d[i] !=0)
    {
        kil++;
        ans = ((long long )d[i]*ans) % mod;
    }
    FOR(i,1,kil-2)
    ans = (ans*(long long)n) % mod;
    cout << ans << endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <cstdio>
#include <algorithm>

#define pb push_back
#define mp make_pair
#define FOR(i,a,b) for (int i = (a); (i) <= (b); (i)++)
using namespace std;

int n,m;
long long ans,mod;
int p[100002],d[100002];

inline int findset(int x)
{
    while (p[x] != x) x = p[x];
    return x;
}

inline void unite(int x, int y)
{
    x = findset(x);
    y = findset(y);
    if ((x+y)&1) p[x] = y;
        else p[y] = x;
}

int main()
{
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    cin >> n >> m >> mod;
    FOR(i,1,n) p[i] = i;
    FOR(i,1,m)
    {
        int x,y;
        cin >> x >> y;
        unite(x,y);
    }
    FOR(i,1,n)
    d[findset(i)]++;
    ans = 1;
    int kil = 0;
    FOR(i,1,n)
     if (d[i] !=0)
    {
        kil++;
        ans = ((long long )d[i]*ans) % mod;
    }
    FOR(i,1,kil-2)
    ans = (ans*(long long)n) % mod;
    if (kil == 1) ans = 1;
    cout << ans%mod << endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <cmath>
#include <cstdio>
#include <algorithm>

#define pb push_back
#define mp make_pair
#define FOR(i,a,b) for (int i = (a); (i) <= (b); (i)++)
using namespace std;

int n,m;
long long ans,mod;
int p[100002],d[100002];

inline int findset(int x)
{
    while (p[x] != x) x = p[x];
    return x;
}

inline void unite(int x, int y)
{
    x = findset(x);
    y = findset(y);
    if ((x+y)&1) p[x] = y;
        else p[y] = x;
}

int main()
{
//  freopen("input.txt","r",stdin);
//  freopen("output.txt","w",stdout);
    cin >> n >> m >> mod;
    FOR(i,1,n) p[i] = i;
    FOR(i,1,m)
    {
        int x,y;
        cin >> x >> y;
        unite(x,y);
    }
    FOR(i,1,n)
    d[findset(i)]++;
    ans = 1;
    int kil = 0;
    FOR(i,1,n)
     if (d[i] !=0)
    {
        kil++;
        ans = ((long long )d[i]*ans) % mod;
    }
    FOR(i,1,kil-2)
    ans = (ans*(long long)n) % mod;
    if (kil == 1) ans = 1;
    cout << ans << endl;
    return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef Lightning
	#define debug(orz...) printf(orz)
	const int DEBUG = 1;
#else
	#define debug(...)
	const int DEBUG = 0;
#endif

#define file_able if (0)
#define setfile(pro_name) freopen(pro_name".in", "r", stdin), freopen(pro_name".out", "w", stdout)
#define closefile() fclose(stdin), fclose(stdout)

#define cmax(_x, _y) (_x < (_y) ? _x = _y : 0)
#define cmin(_x, _y) (_x > (_y) ? _x = _y : 0)
#define gmax(_x, _y) ((_x) > (_y) ? (_x) : (_y))
#define gmin(_x, _y) ((_x) < (_y) ? (_x) : (_y))

namespace defs
{
	#define getc() getchar()

	int read()
	{
		int aa, bb = 1, ch;
		while (ch = getc(), (ch < '0' || ch > '9') && ch != '-');
		ch == '-' ? aa = 0, bb = -1 : aa = ch - '0';
		while (ch = getc(), ch >= '0' && ch <= '9') aa = aa * 10 + ch - '0';
		return aa * bb;
	}

	const unsigned int rand_x = 1401010315;
	const unsigned int rand_y = 1000000019;

	unsigned int rand_cur;

	unsigned int rand_int()
	{
		return rand_cur = rand_cur * rand_x + rand_y;
	}

	const int inf = 1071026353;
	const int mod = 1000000007;
	const int modx = 998244353;

	const int maxn = 100010;
}

namespace lightningwork
{
	// my space

	using namespace defs;

	int n, m, p, fa[maxn], siz[maxn];

	int find(int x)
	{
		return fa[x] == x ? x : fa[x] = find(fa[x]);
	}

	void un(int a, int b)
	{
		a = find(a);
		b = find(b);
		if (a == b) return;
		siz[a] += siz[b];
		fa[b] = a;
	}

	int ppow(int a, int b, int p)
	{
		int tmp = a;
		if (b <= 0) return 1 % p;
		for (--b; b; b >>= 1)
		{
			if (b & 1) a = 1ll * a * tmp % p;
			tmp = 1ll * tmp * tmp % p;
		}
		return a;
	}

	void work()
	{
		n = read();
		m = read();
		p = read();
		for (int i = 1; i <= n; ++i)
		{
			fa[i] = i;
			siz[i] = 1;
		}
		for (int i = 1; i <= m; ++i)
		{
			int u = read(), v = read();
			un(u, v);
		}
		int tot = 0, ans = 1;
		for (int i = 1; i <= n; ++i)
		{
			if (fa[i] == i)
			{
				++tot;
				ans = 1ll * ans * siz[i] % p;
			}
		}
		if (tot == 1)
		{
			puts("1");
		} else
		{
			ans = 1ll * ans * ppow(n, tot - 2, p) % p;
			printf("%d\n", ans);
		}
	}
}

int main()
{
	file_able setfile("work");
	lightningwork::work();
	file_able closefile();
	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef Lightning
	#define debug(orz...) printf(orz)
	const int DEBUG = 1;
#else
	#define debug(...)
	const int DEBUG = 0;
#endif

#define file_able if (0)
#define setfile(pro_name) freopen(pro_name".in", "r", stdin), freopen(pro_name".out", "w", stdout)
#define closefile() fclose(stdin), fclose(stdout)

#define cmax(_x, _y) (_x < (_y) ? _x = _y : 0)
#define cmin(_x, _y) (_x > (_y) ? _x = _y : 0)
#define gmax(_x, _y) ((_x) > (_y) ? (_x) : (_y))
#define gmin(_x, _y) ((_x) < (_y) ? (_x) : (_y))

namespace defs
{
	#define getc() getchar()

	int read()
	{
		int aa, bb = 1, ch;
		while (ch = getc(), (ch < '0' || ch > '9') && ch != '-');
		ch == '-' ? aa = 0, bb = -1 : aa = ch - '0';
		while (ch = getc(), ch >= '0' && ch <= '9') aa = aa * 10 + ch - '0';
		return aa * bb;
	}

	const unsigned int rand_x = 1401010315;
	const unsigned int rand_y = 1000000019;

	unsigned int rand_cur;

	unsigned int rand_int()
	{
		return rand_cur = rand_cur * rand_x + rand_y;
	}

	const int inf = 1071026353;
	const int mod = 1000000007;
	const int modx = 998244353;

	const int maxn = 100010;
}

namespace lightningwork
{
	// my space

	using namespace defs;

	int n, m, p, fa[maxn], siz[maxn];

	int find(int x)
	{
		return fa[x] == x ? x : fa[x] = find(fa[x]);
	}

	void un(int a, int b)
	{
		a = find(a);
		b = find(b);
		if (a == b) return;
		siz[a] += siz[b];
		fa[b] = a;
	}

	int ppow(int a, int b, int p)
	{
		int tmp = a;
		if (b <= 0) return 1 % p;
		for (--b; b; b >>= 1)
		{
			if (b & 1) a = 1ll * a * tmp % p;
			tmp = 1ll * tmp * tmp % p;
		}
		return a;
	}

	void work()
	{
		n = read();
		m = read();
		p = read();
		for (int i = 1; i <= n; ++i)
		{
			fa[i] = i;
			siz[i] = 1;
		}
		for (int i = 1; i <= m; ++i)
		{
			int u = read(), v = read();
			un(u, v);
		}
		int tot = 0, ans = 1;
		for (int i = 1; i <= n; ++i)
		{
			if (fa[i] == i)
			{
				++tot;
				ans = 1ll * ans * siz[i] % p;
			}
		}
		ans = 1ll * ans * ppow(n, tot - 2, p) % p;
		printf("%d\n", ans);
	}
}

int main()
{
	file_able setfile("work");
	lightningwork::work();
	file_able closefile();
	return 0;
}


#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

#ifdef WIN32
	#define LL "%I64d"
#else
	#define LL "%lld"
#endif

#ifdef Lightning
	#define debug(orz...) printf(orz)
	const int DEBUG = 1;
#else
	#define debug(...)
	const int DEBUG = 0;
#endif

#define file_able if (0)
#define setfile(pro_name) freopen(pro_name".in", "r", stdin), freopen(pro_name".out", "w", stdout)
#define closefile() fclose(stdin), fclose(stdout)

#define cmax(_x, _y) (_x < (_y) ? _x = _y : 0)
#define cmin(_x, _y) (_x > (_y) ? _x = _y : 0)
#define gmax(_x, _y) ((_x) > (_y) ? (_x) : (_y))
#define gmin(_x, _y) ((_x) < (_y) ? (_x) : (_y))

namespace defs
{
	#define getc() getchar()

	int read()
	{
		int aa, bb = 1, ch;
		while (ch = getc(), (ch < '0' || ch > '9') && ch != '-');
		ch == '-' ? aa = 0, bb = -1 : aa = ch - '0';
		while (ch = getc(), ch >= '0' && ch <= '9') aa = aa * 10 + ch - '0';
		return aa * bb;
	}

	const unsigned int rand_x = 1401010315;
	const unsigned int rand_y = 1000000019;

	unsigned int rand_cur;

	unsigned int rand_int()
	{
		return rand_cur = rand_cur * rand_x + rand_y;
	}

	const int inf = 1071026353;
	const int mod = 1000000007;
	const int modx = 998244353;

	const int maxn = 100010;
}

namespace lightningwork
{
	// my space

	using namespace defs;

	int n, m, p, fa[maxn], siz[maxn];

	int find(int x)
	{
		return fa[x] == x ? x : fa[x] = find(fa[x]);
	}

	void un(int a, int b)
	{
		a = find(a);
		b = find(b);
		if (a == b) return;
		siz[a] += siz[b];
		fa[b] = a;
	}

	int ppow(int a, int b, int p)
	{
		int tmp = a;
		if (b <= 0) return 1 % p;
		for (--b; b; b >>= 1)
		{
			if (b & 1) a = 1ll * a * tmp % p;
			tmp = 1ll * tmp * tmp % p;
		}
		return a;
	}

	void work()
	{
		n = read();
		m = read();
		p = read();
		for (int i = 1; i <= n; ++i)
		{
			fa[i] = i;
			siz[i] = 1;
		}
		for (int i = 1; i <= m; ++i)
		{
			int u = read(), v = read();
			un(u, v);
		}
		int tot = 0, ans = 1;
		for (int i = 1; i <= n; ++i)
		{
			if (fa[i] == i)
			{
				++tot;
				ans = 1ll * ans * siz[i] % p;
			}
		}
		if (tot == 1)
		{
			printf("%d\n", 1 % p);
		} else
		{
			ans = 1ll * ans * ppow(n, tot - 2, p) % p;
			printf("%d\n", ans);
		}
	}
}

int main()
{
	file_able setfile("work");
	lightningwork::work();
	file_able closefile();
	return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 100100
typedef long long lint;

int n, m, k;
int anc[MAX], peso[MAX];

int find (int x) {
  if (anc[x] == x)
    return x;
  return anc[x] = find (anc[x]);
}

int main () {
  scanf ("%d %d %d", &n, &m, &k);
  for (int i = 0; i < n; i++) {
    peso[i] = 0;
    anc[i] = i;
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf ("%d %d", &a, &b);
    a--;
    b--;
    a = find (a);
    b = find (b);
    anc[a] = b;
  }
  for (int i = 0; i < n; i++) {
    peso[find (i)]++;
  }
  lint ret = 1;
  int count = 0;
  for (int i = 0; i < n; i++) {
    if (peso[i]) {
      ret = (ret*peso[i])%k;
      count++;
    }
  }
  if (count == 1) {
    printf ("0\n");
    return 0;
  }
  for (int i = 0; i < count - 2; i++)
    ret = (ret * n)%k;
  cout << ret << endl;
  return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 100100
typedef long long lint;

int n, m, k;
int anc[MAX], peso[MAX];

int find (int x) {
  if (anc[x] == x)
    return x;
  return anc[x] = find (anc[x]);
}

int main () {
  scanf ("%d %d %d", &n, &m, &k);
  for (int i = 0; i < n; i++) {
    peso[i] = 0;
    anc[i] = i;
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf ("%d %d", &a, &b);
    a--;
    b--;
    a = find (a);
    b = find (b);
    anc[a] = b;
  }
  for (int i = 0; i < n; i++) {
    peso[find (i)]++;
  }
  lint ret = 1;
  int count = 0;
  for (int i = 0; i < n; i++) {
    if (peso[i]) {
      ret = (ret*peso[i])%k;
      count++;
    }
  }
  if (count == 1) {
    printf ("%d\n", 1%k);
    return 0;
  }
  for (int i = 0; i < count - 2; i++)
    ret = (ret * n)%k;
  cout << ret << endl;
  return 0;
}


#include <stdio.h>
#include <iostream>
#include <algorithm>
using namespace std;
#define MAX 100100
typedef long long lint;

int n, m, k;
int anc[MAX], peso[MAX];

int find (int x) {
  if (anc[x] == x)
    return x;
  return anc[x] = find (anc[x]);
}

int main () {
  scanf ("%d %d %d", &n, &m, &k);
  for (int i = 0; i < n; i++) {
    peso[i] = 0;
    anc[i] = i;
  }
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf ("%d %d", &a, &b);
    a--;
    b--;
    a = find (a);
    b = find (b);
    anc[a] = b;
  }
  for (int i = 0; i < n; i++) {
    peso[find (i)]++;
  }
  lint ret = 1;
  int count = 0;
  for (int i = 0; i < n; i++) {
    if (peso[i]) {
      ret = (ret*peso[i])%k;
      count++;
    }
  }
  if (count == 1 && 0) {
    printf ("0\n");
    return 0;
  }
  for (int i = 0; i < count - 2; i++)
    ret = (ret * n)%k;
  cout << ret << endl;
  return 0;
}


#include<cstdio>
#include<iostream>

using namespace std;

const int MaxN=100010;

int n,m,num;
long long k;
int F[MaxN],p[MaxN],v[MaxN];

inline int father(const int &x)
{
    return (F[x]==x)?x:F[x]=father(F[x]);
}

inline long long power(long long x,int n)
{
    if (!n) return 1;
    long long tmp=power(x,n>>1);
    tmp*=tmp;
    tmp%=k;
    if (n&1)
    {
        tmp*=x;
        tmp%=k;
    }
    return tmp;
}

int main()
{
    cin>>n>>m>>k;
    for (int i=1;i<=n;++i)
        F[i]=i;
    for (int i=1;i<=m;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        F[father(x)]=father(y);
    }
    for (int i=1;i<=n;++i)
        ++p[father(i)];
    for (int i=1;i<=n;++i)
        if (p[i]) v[++num]=p[i];
    if (num==1)
        cout<<1%k<<endl;
    else
    {
        long long sum=0,ans=1;
        for (int i=1;i<=num;++i)
        {
            sum+=v[i];
            while (sum>=k) sum-=k;
            ans*=v[i];
            ans%=k;
        }
        ans*=power(sum,num-2);
        cout<<ans%k<<endl;
    }
    return 0;
}


#include<cstdio>
#include<iostream>

using namespace std;

const int MaxN=100010;

int n,m,num;
unsigned long long k;
int F[MaxN],p[MaxN],v[MaxN];

inline int father(const int &x)
{
    return (F[x]==x)?x:F[x]=father(F[x]);
}

inline unsigned long long power(unsigned long long x,int n)
{
    if (!n) return 1;
    unsigned long long tmp=power(x,n>>1);
    tmp*=tmp;
    tmp%=k;
    if (n&1)
    {
        tmp*=x;
        tmp%=k;
    }
    return tmp;
}

int main()
{
    cin>>n>>m>>k;
    for (int i=1;i<=n;++i)
        F[i]=i;
    for (int i=1;i<=m;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        F[father(x)]=father(y);
    }
    for (int i=1;i<=n;++i)
        ++p[father(i)];
    for (int i=1;i<=n;++i)
        if (p[i]) v[++num]=p[i];
    if (num==1)
        cout<<0<<endl;
    else
    {
        unsigned long long sum=0,ans=1;
        for (int i=1;i<=num;++i)
        {
            sum+=v[i];
            sum%=k;
            ans*=v[i];
            ans%=k;
        }
        ans*=power(sum,num-2);
        ans%=k;
        cout<<ans<<endl;
    }
    return 0;
}


#include<cstdio>
#include<iostream>

using namespace std;

const int MaxN=100010;

int n,m,num;
unsigned long long k;
int F[MaxN],p[MaxN],v[MaxN];

int father(int x)
{
    return (F[x]==x)?x:F[x]=father(F[x]);
}

unsigned long long power(unsigned long long x,int n)
{
    if (!n) return 1;
    unsigned long long tmp=power(x,n>>1);
    tmp*=tmp;
    tmp%=k;
    if (n&1)
    {
        tmp*=x;
        tmp%=k;
    }
    return tmp;
}

int main()
{
    cin>>n>>m>>k;
    for (int i=1;i<=n;++i)
        F[i]=i;
    for (int i=1;i<=m;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        F[father(x)]=father(y);
    }
    for (int i=1;i<=n;++i)
        ++p[father(i)];
    for (int i=1;i<=n;++i)
        if (p[i]) v[++num]=p[i];
    if (num==1)
        cout<<0<<endl;
    else
    {
        unsigned long long sum=0,ans=1;
        for (int i=1;i<=num;++i)
        {
            sum+=v[i];
            sum%=k;
            ans*=v[i];
            ans%=k;
        }
        if (sum)
        {
            ans*=power(sum,num-2);
            ans%=k;
        }
        else
            ans=0;
        cout<<ans<<endl;
    }
    return 0;
}


#include<cstdio>
#include<iostream>

using namespace std;

const int MaxN=100010;

int n,m,num;
unsigned long long k,v[MaxN];
int F[MaxN],p[MaxN];

int father(int x)
{
    return (F[x]==x)?x:F[x]=father(F[x]);
}

unsigned long long power(unsigned long long x,int n)
{
    if (!n) return 1;
    unsigned long long tmp=power(x,n>>1);
    tmp*=tmp;
    tmp%=k;
    if (n&1)
    {
        tmp*=x;
        tmp%=k;
    }
    return tmp;
}

int main()
{
    cin>>n>>m>>k;
    for (int i=1;i<=n;++i)
        F[i]=i;
    for (int i=1;i<=m;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        F[father(x)]=father(y);
    }
    for (int i=1;i<=n;++i)
        ++p[father(i)];
    for (int i=1;i<=n;++i)
        if (p[i]) v[++num]=p[i];
    if (num==1)
        cout<<0<<endl;
    else
    {
        unsigned long long sum=0,ans=1;
        for (int i=1;i<=num;++i)
        {
            sum+=v[i];
            sum%=k;
            ans*=v[i];
            ans%=k;
        }
        if (sum)
        {
            ans*=power(sum,num-2);
            ans%=k;
        }
        else
            ans=0;
        cout<<ans<<endl;
    }
    return 0;
}


#include<cstdio>
#include<iostream>

using namespace std;

const int MaxN=100010;

int n,m,num;
long long k;
int F[MaxN],p[MaxN],v[MaxN];

inline int father(const int &x)
{
    return (F[x]==x)?x:F[x]=father(F[x]);
}

inline long long power(long long x,int n)
{
    if (!n) return 1;
    long long tmp=power(x,n>>1);
    tmp*=tmp;
    tmp%=k;
    if (n&1)
    {
        tmp*=x;
        tmp%=k;
    }
    return tmp;
}

int main()
{
    cin>>n>>m>>k;
    for (int i=1;i<=n;++i)
        F[i]=i;
    for (int i=1;i<=m;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        F[father(x)]=father(y);
    }
    for (int i=1;i<=n;++i)
        ++p[father(i)];
    for (int i=1;i<=n;++i)
        if (p[i]) v[++num]=p[i];
    if (num==1)
        puts("0");
    else
    {
        long long sum=0,ans=1;
        for (int i=1;i<=num;++i)
        {
            sum+=v[i];
            while (sum>=k) sum-=k;
            ans*=v[i];
            ans%=k;
        }
        ans*=power(sum,num-2);
        cout<<ans%k<<endl;
    }
    return 0;
}


#include<cstdio>
#include<iostream>

using namespace std;

const int MaxN=100010;

int n,m,num;
unsigned long long k,v[MaxN];
int F[MaxN],p[MaxN];

int father(int x)
{
    return (F[x]==x)?x:F[x]=father(F[x]);
}

unsigned long long power(unsigned long long x,int n)
{
    if (n==1) return x;
    unsigned long long tmp=power(x,n/2);
    tmp=tmp*tmp%k;
    if (n%2==1)
        tmp=tmp*x%k;
    return tmp;
}

int main()
{
    cin>>n>>m>>k;
    for (int i=1;i<=n;++i)
        F[i]=i;
    for (int i=1;i<=m;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        F[father(x)]=father(y);
    }
    for (int i=1;i<=n;++i)
        ++p[father(i)];
    for (int i=1;i<=n;++i)
        if (p[i]) v[++num]=p[i];
    if (num==1)
        cout<<0<<endl;
    else if (num==2)
        cout<<v[1]*v[2]%k<<endl;
    else
    {
        unsigned long long sum=0,ans=1;
        for (int i=1;i<=num;++i)
        {
            sum=(sum+v[i])%k;
            ans=ans*v[i]%k;
        }
        ans=ans*power(sum,num-2)%k;
        cout<<ans<<endl;
    }
    return 0;
}


#include<cstdio>
#include<iostream>

using namespace std;

const int MaxN=1000010;

int n,m,num;
unsigned long long k,v[MaxN];
int F[MaxN],p[MaxN];

int father(int x)
{
    return (F[x]==x)?x:F[x]=father(F[x]);
}

int main()
{
    cin>>n>>m;
    cin>>k;
    for (int i=1;i<=n;++i)
        F[i]=i;
    for (int i=1;i<=m;++i)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        int fx=father(x),fy=father(y);
        if (fx!=fy) F[fx]=fy;
    }
    for (int i=1;i<=n;++i)
        ++p[father(i)];
    for (int i=1;i<=n;++i)
        if (p[i]) v[++num]=p[i];
    if (num==1)
        cout<<0<<endl;
    else if (num==2)
        cout<<v[1]*v[2]%k<<endl;
    else
    {
        unsigned long long sum=0,ans=1;
        for (int i=1;i<=num;++i)
        {
            sum=(sum+v[i])%k;
            ans=ans*v[i]%k;
        }
        unsigned long long tmp=sum;
        for (int i=2;i<=num-2;++i)
            tmp=tmp*sum%k;
        ans=ans*tmp%k;
        cout<<ans<<endl;
    }
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <cassert>
#include <ctime>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<ll> vll;
typedef vector<vll> vvll;

#define TASKNAME "text"
#define pb push_back
#define mp make_pair
#define EPS (1E-9)
#define INF ((int)1E9)
#define sqr(x) ((x) * (x))
#define eprintf(...) fprintf(stderr, __VA_ARGS__)

const int maxn = (int)1e5;
int pr[maxn], w[maxn];

inline int get(int x) {
    if (pr[x] == x)
        return x;
    return pr[x] = get(pr[x]);
}

#define union asdfjkasjdfkasdjfk
inline void union(int s, int t) {
    s = get(s), t = get(t);
    if (s == t)
        return;
    if (w[s] == w[t])
        w[s]++;
    if (w[s] > w[t])
        pr[t] = s;
    else
        pr[s] = t;
}

int cnt[maxn];

int main() {
    #ifdef DEBUG
        freopen(TASKNAME".in", "r", stdin);
        freopen(TASKNAME".out", "w", stdout);
    #endif

    int n, m, k;
    while(scanf("%d%d%d", &n, &m, &k) >= 1) {
        for (int i = 0; i < n; i++)
            pr[i] = i, w[i] = 0;
        for (int i = 0; i < m; i++) {
            int s, t;
            scanf("%d%d", &s, &t);
            s--, t--;
            union(s, t);
        }

        memset(cnt, 0, sizeof(cnt));
        int num = 0;
        for (int i = 0; i < n; i++) {
            cnt[get(i)]++;
            if (get(i) == i)
                num++;
        }

        ll ans = 1 % k;
        for (int i = 0; i < n; i++)
            if (cnt[i])
                ans = ans * cnt[i] % k;

        for (int i = 0; i < num - 2; i++)
            ans = ans * n % k;

        printf("%d\n", (int)ans);
    }
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <cassert>
#include <ctime>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<ll> vll;
typedef vector<vll> vvll;

#define TASKNAME "text"
#define pb push_back
#define mp make_pair
#define EPS (1E-9)
#define INF ((int)1E9)
#define sqr(x) ((x) * (x))
#define eprintf(...) fprintf(stderr, __VA_ARGS__)

const int maxn = (int)1e5;
int pr[maxn], w[maxn];

inline int get(int x) {
    if (pr[x] == x)
        return x;
    return pr[x] = get(pr[x]);
}

#define union asdfjkasjdfkasdjfk
inline void union(int s, int t) {
    s = get(s), t = get(t);
    if (s == t)
        return;
    if (w[s] == w[t])
        w[s]++;
    if (w[s] > w[t])
        pr[t] = s;
    else
        pr[s] = t;
}

int cnt[maxn];

int main() {
    #ifdef DEBUG
        freopen(TASKNAME".in", "r", stdin);
        freopen(TASKNAME".out", "w", stdout);
    #endif

    int n, m, k;
    while(scanf("%d%d%d", &n, &m, &k) >= 1) {
        for (int i = 0; i < n; i++)
            pr[i] = i, w[i] = 0;
        for (int i = 0; i < m; i++) {
            int s, t;
            scanf("%d%d", &s, &t);
            s--, t--;
            union(s, t);
        }

        memset(cnt, 0, sizeof(cnt));
        int num = 0;
        for (int i = 0; i < n; i++) {
            cnt[get(i)]++;
            if (get(i) == i)
                num++;
        }
        if (num == 1) {
            printf("1\n");
            continue;
        }

        ll ans = 1 % k;
        for (int i = 0; i < n; i++)
            if (cnt[i])
                ans = ans * cnt[i] % k;

        for (int i = 0; i < num - 2; i++)
            ans = ans * n % k;

        printf("%d\n", (int)ans);
    }
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <cassert>
#include <ctime>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<ll> vll;
typedef vector<vll> vvll;

#define TASKNAME "text"
#define pb push_back
#define mp make_pair
#define EPS (1E-9)
#define INF ((int)1E9)
#define sqr(x) ((x) * (x))
#define eprintf(...) fprintf(stderr, __VA_ARGS__)

const int maxn = (int)1e5;
int pr[maxn], w[maxn];

inline int get(int x) {
    if (pr[x] == x)
        return x;
    return pr[x] = get(pr[x]);
}

#define union asdfjkasjdfkasdjfk
inline void union(int s, int t) {
    s = get(s), t = get(t);
    if (s == t)
        return;
    if (w[s] == w[t])
        w[s]++;
    if (w[s] > w[t])
        pr[t] = s;
    else
        w[s] = t;
}

int cnt[maxn];

int main() {
    #ifdef DEBUG
        freopen(TASKNAME".in", "r", stdin);
        freopen(TASKNAME".out", "w", stdout);
    #endif

    int n, m, k;
    while(scanf("%d%d%d", &n, &m, &k) >= 1) {
        for (int i = 0; i < n; i++)
            pr[i] = i, w[i] = 0;
        for (int i = 0; i < m; i++) {
            int s, t;
            scanf("%d%d", &s, &t);
            s--, t--;
            union(s, t);
        }

        memset(cnt, 0, sizeof(cnt));
        int num = 0;
        for (int i = 0; i < n; i++) {
            cnt[get(i)]++;
            if (get(i) == i)
                num++;
        }

        ll ans = 1 % k;
        for (int i = 0; i < n; i++)
            if (cnt[i])
                ans = ans * cnt[i] % k;

        for (int i = 0; i < num - 2; i++)
            ans = ans * n % k;

        printf("%d\n", (int)ans);
    }
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <vector>
#include <string>
#include <cassert>
#include <ctime>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<ll> vll;
typedef vector<vll> vvll;

#define TASKNAME "text"
#define pb push_back
#define mp make_pair
#define EPS (1E-9)
#define INF ((int)1E9)
#define sqr(x) ((x) * (x))
#define eprintf(...) fprintf(stderr, __VA_ARGS__)

const int maxn = (int)1e5;
int pr[maxn], w[maxn];

inline int get(int x) {
    if (pr[x] == x)
        return x;
    return pr[x] = get(pr[x]);
}

#define union asdfjkasjdfkasdjfk
inline void union(int s, int t) {
    s = get(s), t = get(t);
    if (s == t)
        return;
    if (w[s] == w[t])
        w[s]++;
    if (w[s] > w[t])
        pr[t] = s;
    else
        pr[s] = t;
}

int cnt[maxn];

int main() {
    #ifdef DEBUG
        freopen(TASKNAME".in", "r", stdin);
        freopen(TASKNAME".out", "w", stdout);
    #endif

    int n, m, k;
    while(scanf("%d%d%d", &n, &m, &k) >= 1) {
        for (int i = 0; i < n; i++)
            pr[i] = i, w[i] = 0;
        for (int i = 0; i < m; i++) {
            int s, t;
            scanf("%d%d", &s, &t);
            s--, t--;
            union(s, t);
        }

        memset(cnt, 0, sizeof(cnt));
        int num = 0;
        for (int i = 0; i < n; i++) {
            cnt[get(i)]++;
            if (get(i) == i)
                num++;
        }
        if (num == 1) {
            printf("%d\n", 1 % k);
            continue;
        }

        ll ans = 1 % k;
        for (int i = 0; i < n; i++)
            if (cnt[i])
                ans = ans * cnt[i] % k;

        for (int i = 0; i < num - 2; i++)
            ans = ans * n % k;

        printf("%d\n", (int)ans);
    }
    return 0;
}


#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <ctime>
#include <cctype>

using namespace std;
typedef long long int64;
const int inf = 0x3f3f3f3f;
typedef double real;
const real eps = 1e-6;
typedef pair<int64,int> pip;
#define Eo(x) { cerr << #x << " = " << (x) << endl; }

template<typename T>
T gcd(const T& a, const T& b) {
  return a == 0 ? b : gcd(b%a,a);
}

template<typename T>
bool isprime(const T& k){
  for (T i = 2;i*i<=k;i++)if ((k%i)==0) return false;
  return true;
}

template<typename T>
T mabs(const T& x) {
  if (x>=0) return x;
  return -x;
}

#define PRIMES 0
#if PRIMES
vector<int> primes;
void factorize(int64 x, map<int64,int>& all){
  int i;
  for (i = 0;i<primes.size()&&int64(primes[i])*primes[i]<=x;i++)if (!(x%primes[i])){
    int q = 0;
    for (;!(x%primes[i]);x/=primes[i],q++);
    all[primes[i]]+=q;
  }
  assert(i<primes.size());
  if (x>1)all[x]++;
}
const int maxn = 1<<27;
char isp[maxn];
#endif

const int maxn = 1<<20;
int comp[maxn];
int getcomp(int x) {
  return comp[x] == x ? x : comp[x] = getcomp(comp[x]);
}
void merge(int x, int y) {
   x = getcomp(x);
   y = getcomp(y);
   if (x==y)return;
   if(rand()&1) comp[x]=y;
   else comp[y]=x;
}
int b[maxn];

int main(){
  int n,k,mod; cin >> n >> k >> mod;
  for (int i = 0; i < n; i++) comp[i]=i;
  for (int i = 0; i < k; i++) {
    int x,y; scanf("%d%d",&x,&y);
    x--;y--;
    merge(x,y);
  }
  map<int,int> all;
  for (int i = 0; i < n; i++) all[getcomp(i)]++;
  int cnt = 0;
  int64 res = 1%mod;
  for (map<int,int>::const_iterator it = all.begin(); it != all.end(); ++it) {
    res = (res*it->second)%mod;
  }
  if (all.size()==1){
    puts("0");
    return 0;
  }
  for (int i = 0; i < all.size()-2; i++) {
    res = (res*n)%mod;
  }
  cout << res << endl;
  return 0;
}


#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <ctime>
#include <cctype>

using namespace std;
typedef long long int64;
const int inf = 0x3f3f3f3f;
typedef double real;
const real eps = 1e-6;
typedef pair<int64,int> pip;
#define Eo(x) { cerr << #x << " = " << (x) << endl; }

template<typename T>
T gcd(const T& a, const T& b) {
  return a == 0 ? b : gcd(b%a,a);
}

template<typename T>
bool isprime(const T& k){
  for (T i = 2;i*i<=k;i++)if ((k%i)==0) return false;
  return true;
}

template<typename T>
T mabs(const T& x) {
  if (x>=0) return x;
  return -x;
}

#define PRIMES 0
#if PRIMES
vector<int> primes;
void factorize(int64 x, map<int64,int>& all){
  int i;
  for (i = 0;i<primes.size()&&int64(primes[i])*primes[i]<=x;i++)if (!(x%primes[i])){
    int q = 0;
    for (;!(x%primes[i]);x/=primes[i],q++);
    all[primes[i]]+=q;
  }
  assert(i<primes.size());
  if (x>1)all[x]++;
}
const int maxn = 1<<27;
char isp[maxn];
#endif

const int maxn = 1<<20;
int comp[maxn];
int getcomp(int x) {
  return comp[x] == x ? x : comp[x] = getcomp(comp[x]);
}
void merge(int x, int y) {
   x = getcomp(x);
   y = getcomp(y);
   if (x==y)return;
   if(rand()&1) comp[x]=y;
   else comp[y]=x;
}
int b[maxn];

int main(){
  int64 n,k,mod; cin >> n >> k >> mod;
  for (int i = 0; i < n; i++) comp[i]=i;
  for (int i = 0; i < k; i++) {
    int x,y; scanf("%d%d",&x,&y);
    x--;y--;
    merge(x,y);
  }
  map<int,int64> all;
  for (int i = 0; i < n; i++) all[getcomp(i)]++;
  int64 res = 1%mod;
  if(all.size()>1){
    for (map<int,int64>::const_iterator it = all.begin(); it != all.end(); ++it) {
      res = (res*it->second)%mod;
    }
  }
  for (int i = 0; i < int(all.size())-2; i++) {
    res = (res*n)%mod;
  }
  cout << res << endl;
  return 0;
}


#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <ctime>
#include <cctype>

using namespace std;
typedef long long int64;
const int inf = 0x3f3f3f3f;
typedef double real;
const real eps = 1e-6;
typedef pair<int64,int> pip;
#define Eo(x) { cerr << #x << " = " << (x) << endl; }

template<typename T>
T gcd(const T& a, const T& b) {
  return a == 0 ? b : gcd(b%a,a);
}

template<typename T>
bool isprime(const T& k){
  for (T i = 2;i*i<=k;i++)if ((k%i)==0) return false;
  return true;
}

template<typename T>
T mabs(const T& x) {
  if (x>=0) return x;
  return -x;
}

#define PRIMES 0
#if PRIMES
vector<int> primes;
void factorize(int64 x, map<int64,int>& all){
  int i;
  for (i = 0;i<primes.size()&&int64(primes[i])*primes[i]<=x;i++)if (!(x%primes[i])){
    int q = 0;
    for (;!(x%primes[i]);x/=primes[i],q++);
    all[primes[i]]+=q;
  }
  assert(i<primes.size());
  if (x>1)all[x]++;
}
const int maxn = 1<<27;
char isp[maxn];
#endif

const int maxn = 1<<20;
int comp[maxn];
int getcomp(int x) {
  return comp[x] == x ? x : comp[x] = getcomp(comp[x]);
}
void merge(int x, int y) {
   x = getcomp(x);
   y = getcomp(y);
   if (x==y)return;
   if(rand()&1) comp[x]=y;
   else comp[y]=x;
}
int b[maxn];

int main(){
  int64 n,k,mod; cin >> n >> k >> mod;
  for (int i = 0; i < n; i++) comp[i]=i;
  for (int i = 0; i < k; i++) {
    int x,y; scanf("%d%d",&x,&y);
    x--;y--;
    merge(x,y);
  }
  map<int,int64> all;
  for (int i = 0; i < n; i++) all[getcomp(i)]++;
  if (all.size()==1){
    puts("0");
    return 0;
  }
  int64 res = 1%mod;
  for (map<int,int64>::const_iterator it = all.begin(); it != all.end(); ++it) {
    res = (res*it->second)%mod;
  }
  for (int i = 0; i < all.size()-2; i++) {
    res = (res*n)%mod;
  }
  cout << res << endl;
  return 0;
}


#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <ctime>
#include <cctype>

using namespace std;
typedef long long int64;
const int inf = 0x3f3f3f3f;
typedef double real;
const real eps = 1e-6;
typedef pair<int64,int> pip;
#define Eo(x) { cerr << #x << " = " << (x) << endl; }

template<typename T>
T gcd(const T& a, const T& b) {
  return a == 0 ? b : gcd(b%a,a);
}

template<typename T>
bool isprime(const T& k){
  for (T i = 2;i*i<=k;i++)if ((k%i)==0) return false;
  return true;
}

template<typename T>
T mabs(const T& x) {
  if (x>=0) return x;
  return -x;
}

#define PRIMES 0
#if PRIMES
vector<int> primes;
void factorize(int64 x, map<int64,int>& all){
  int i;
  for (i = 0;i<primes.size()&&int64(primes[i])*primes[i]<=x;i++)if (!(x%primes[i])){
    int q = 0;
    for (;!(x%primes[i]);x/=primes[i],q++);
    all[primes[i]]+=q;
  }
  assert(i<primes.size());
  if (x>1)all[x]++;
}
const int maxn = 1<<27;
char isp[maxn];
#endif

const int maxn = 1<<20;
int comp[maxn];
int getcomp(int x) {
  return comp[x] == x ? x : comp[x] = getcomp(comp[x]);
}
void merge(int x, int y) {
   x = getcomp(x);
   y = getcomp(y);
   if (x==y)return;
   if(rand()&1) comp[x]=y;
   else comp[y]=x;
}
int b[maxn];

int main(){
  int64 n,k,mod; cin >> n >> k >> mod;
  for (int i = 0; i < n; i++) comp[i]=i;
  for (int i = 0; i < k; i++) {
    int x,y; scanf("%d%d",&x,&y);
    x--;y--;
    merge(x,y);
  }
  map<int,int64> all;
  for (int i = 0; i < n; i++) all[getcomp(i)]++;
  if (all.size()==1){
    puts("1");
    return 0;
  }
  int64 res = 1%mod;
  for (map<int,int64>::const_iterator it = all.begin(); it != all.end(); ++it) {
    res = (res*it->second)%mod;
  }
  for (int i = 0; i < all.size()-2; i++) {
    res = (res*n)%mod;
  }
  cout << res << endl;
  return 0;
}


#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <algorithm>
#include <string>
#include <sstream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cassert>
#include <ctime>
#include <cctype>

using namespace std;
typedef long long int64;
const int inf = 0x3f3f3f3f;
typedef double real;
const real eps = 1e-6;
typedef pair<int64,int> pip;
#define Eo(x) { cerr << #x << " = " << (x) << endl; }

template<typename T>
T gcd(const T& a, const T& b) {
  return a == 0 ? b : gcd(b%a,a);
}

template<typename T>
bool isprime(const T& k){
  for (T i = 2;i*i<=k;i++)if ((k%i)==0) return false;
  return true;
}

template<typename T>
T mabs(const T& x) {
  if (x>=0) return x;
  return -x;
}

#define PRIMES 0
#if PRIMES
vector<int> primes;
void factorize(int64 x, map<int64,int>& all){
  int i;
  for (i = 0;i<primes.size()&&int64(primes[i])*primes[i]<=x;i++)if (!(x%primes[i])){
    int q = 0;
    for (;!(x%primes[i]);x/=primes[i],q++);
    all[primes[i]]+=q;
  }
  assert(i<primes.size());
  if (x>1)all[x]++;
}
const int maxn = 1<<27;
char isp[maxn];
#endif

const int maxn = 1<<20;
int comp[maxn];
int getcomp(int x) {
  return comp[x] == x ? x : comp[x] = getcomp(comp[x]);
}
void merge(int x, int y) {
   x = getcomp(x);
   y = getcomp(y);
   if (x==y)return;
   if(rand()&1) comp[x]=y;
   else comp[y]=x;
}
int b[maxn];

int main(){
  int64 n,k,mod; cin >> n >> k >> mod;
  for (int i = 0; i < n; i++) comp[i]=i;
  for (int i = 0; i < k; i++) {
    int x,y; scanf("%d%d",&x,&y);
    x--;y--;
    merge(x,y);
  }
  map<int,int64> all;
  for (int i = 0; i < n; i++) all[getcomp(i)]++;
  int64 res = 1%mod;
  if(all.size()>1){
    for (map<int,int64>::const_iterator it = all.begin(); it != all.end(); ++it) {
      res = (res*it->second)%mod;
    }
  }
  for (int i = 0; i < all.size()-2; i++) {
    res = (res*n)%mod;
  }
  cout << res << endl;
  return 0;
}