#P8345. [2023广东省队集训]染色

[2023广东省队集训]染色

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

typedef pair<int, int> pii;
typedef long long ll;
template<class T> using V = vector<T>;
template<class T> using VV = V<V<T>>;

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i,n) rep2(i,0,n)
#define rep2(i,m,n) for(int i=m;i<(n);i++)
#define ALL(c) (c).begin(),(c).end()
#define dump(x) cout << #x << " = " << (x) << endl
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n-1); }

template<class T, class U> void chmin(T& t, const U& u) { if (t > u) t = u; }
template<class T, class U> void chmax(T& t, const U& u) { if (t < u) t = u; }

template<class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
	os<<"("<<p.first<<","<<p.second<<")";
	return os;
}

template<class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
	os<<"{";
	rep(i, v.size()) {
		if (i) os<<",";
		os<<v[i];
	}
	os<<"}";
	return os;
}

const ll MOD = TEN(9) + 7;
const int maxn = 100010;

int N, M, K;
V<int> g[maxn];

int col[maxn];
ll dp[maxn][3]; //diff
ll dpc[maxn][2]; //same
ll ans;

void add(int num, const V<pair<pii,int>>& es) {
	ll u = 1;

	for (auto e : es) {
		int a = e.fi.fi, b = e.fi.se, len = e.se;
		if (len == 0) {
			if (col[a] == col[b]) {
				return ;
			}
		} else {
			if (col[a] == col[b]) {
				u = u * dpc[len][0] % MOD;
			} else {
				if (len >= 2) {
					u = u * (dp[len][0] + dp[len][1]) % MOD;
				} else {
					u = u * dp[len][0] % MOD;
				}
			}
		}
	}
	int now = *max_element(col, col + N);
	if (now >= K) return ;
	for (int i = 0; i <= now; ++i) {
		u = u * (K - i) % MOD;
	}
	ans = (ans + u) % MOD;
}

void dfs(int p, int num, const V<pair<pii,int>>& es) {
	if (p == num) {
		add(num, es);
		return ;
	}
	set<int> st;
	rep(i, p) {
		if (!st.count(col[i])) {
			col[p] = col[i];
			dfs(p + 1, num, es);
			st.insert(col[i]);
		}
	}
	int now = 0;
	while (st.count(now)) {
		now++;
	}
	col[p] = now;
	dfs(p + 1, num, es);
}

set<int> st[maxn];

void solve() {
	dp[1][2] = 1;
	dp[1][0] = K - 2;
	for (int i = 1; i < maxn - 1; ++i) {
		if (K >= 3) {
			(dp[i+1][0] += dp[i][0] * (K-3)) %= MOD;
		}
		(dp[i+1][1] += dp[i][0]) %= MOD;
		(dp[i+1][2] += dp[i][0]) %= MOD;
		(dp[i+1][0] += dp[i][1] * (K-2)) %= MOD;
		(dp[i+1][2] += dp[i][1]) %= MOD;
		(dp[i+1][0] += dp[i][2] * (K-2)) %= MOD;
		(dp[i+1][1] += dp[i][2]) %= MOD;		
	}

	dpc[1][0] = K - 1;

	for (int i = 1; i < maxn - 1; ++i) {
		(dpc[i+1][0] += dpc[i][0] * (K - 2)) %= MOD;
		(dpc[i+1][1] += dpc[i][0]) %= MOD;
		(dpc[i+1][0] += dpc[i][1] * (K - 1)) %= MOD;
	}

	rep(i, N) {
		for (int to : g[i]) {
			st[i].insert(to);
		}
	}
	queue<int> que;
	int leaf = 0;
	rep(i, N) if (st[i].size() == 1) {
		que.push(i);
	}
	while (!que.empty()) {
		int v = que.front(); que.pop();
		for (auto to : st[v]) {
			st[to].erase(v);
			if (st[to].size() == 1) {
				que.push(to);
			}
		}
		st[v].clear();
		++leaf;
	}

	V<int> special;
	V<int> rid(N, -1);
	int now = 0;
	rep(i, N) {
		if (st[i].size() >= 3) {
			rid[i] = now++;
			special.pb(i);
		}
	}
	if (special.size() == 0) {
		rep(i, N) {
			if (st[i].size() == 2) {
				rid[i] = now++;
				special.pb(i);
				break;
			}
		}
	}
	//dump(special);

	V<pair<pii, int>> es;

	V<int> vis(N);
	for (int v : special) {
		for (auto to : st[v]) {
			if (vis[to]) continue;
			int cur = to;
			int num = 0;
			int pr = v;
			while (rid[cur] == -1) {
				vis[cur] = 1;
				for (auto t : st[cur]) {
					if (t != pr) {
						pr = cur;
						cur = t;
						break;
					}
				}
				++num;
			}
			es.eb(mp(rid[v], rid[cur]), num);
			//printf("%d---%d, len=%d\n", rid[v], rid[cur], num);
		}
	}

	ans = 0;
	dfs(0, special.size(), es);
	//dump(leaf);

	rep(i, leaf) ans = ans * (K - 1) % MOD;
	cout << ans << endl;	
}

int main() {
	cin >> N >> M >> K;
	rep(i, M) {
		int a, b;
		cin >> a >> b;
		--a; --b;
		g[a].pb(b);
		g[b].pb(a);
	}

	if (K == 1 && N >= 2) {
		puts("0");
		return 0;
	}

	if (M == N-1) {
		ll ans = K;
		rep(i, N-1) {
			ans = ans * (K - 1) % MOD;
		}
		cout << ans << endl;
		return 0;
	}

	solve();

	return 0;
}