int n, m, typ;namespace Solve0 {int par[MAXN], vis[MAXN];
set<pair<int,int>> ss;intfind(int x){return par[x]== x ? x : par[x]=find(par[x]);}voidsolve(){for(int i =1; i <= n; i++) par[i]= i;for(int i =1; i < n; i++){int u, v;read(u, v);
ss.insert(make_pair(u, v));
ss.insert(make_pair(v, u));}for(int i =1; i < n; i++){int u, v;read(u, v);if(ss.find(make_pair(u, v))!= ss.end())
par[find(u)]=find(v);}
ll res =1;for(int i =1; i <= n; i++)if(!vis[find(i)])
vis[find(i)]=1, res = res * m % MOD;printf("%lld\n", res);}}namespace Solve1 {struct Edge {int to, next;} edge[MAXN];int head[MAXN], tot;
ll f[MAXN], g[MAXN], invn, invm;voidaddedge(int u,int v){
edge[++tot]=(Edge){ v, head[u]};
head[u]= tot;}voiddfs(int u,int fa){
f[u]= g[u]= invn;for(int i = head[u]; i; i = edge[i].next){int v = edge[i].to;if(v == fa)continue;dfs(v, u);
ll a =(f[u]* f[v]% MOD * n % MOD * n +(f[u]* g[v]+ g[u]* f[v])% MOD * n % MOD *(invm -1))% MOD;
ll b =(g[u]* f[v]% MOD * n % MOD * n + g[u]* g[v]% MOD * n % MOD *(invm -1))% MOD;
f[u]= a, g[u]= b;}}voidsolve(){for(int i =1; i < n; i++){int u, v;read(u, v);addedge(u, v),addedge(v, u);}
invn =modpow(n, MOD -2);
invm =modpow(m, MOD -2);dfs(1,0);printf("%lld\n", f[1]*modpow(m, n)% MOD);}}namespace Solve2 {
ll fac[MAXN], rev[MAXN];int A[MAXN], B[MAXN];voidsolve(){if(m ==1){printf("%d\n",modpow(n,2* n -4));return;}for(int i = fac[0]=1; i <= n; i++) fac[i]= fac[i -1]* i % MOD;
rev[n]=modpow(fac[n], MOD -2);for(int i = n; i >0; i--) rev[i -1]= rev[i]* i % MOD;
ll invm =modpow(m, MOD -2), iinvm =(ll)modpow(invm -1, MOD -2)* n % MOD * n % MOD;for(int i =1; i <= n; i++) A[i]=modpow(i, i)* rev[i]% MOD * iinvm % MOD;get_exp(A, B,get_tpow(n +1));printf("%lld\n",(ll)B[n]*modpow(n, MOD -5)% MOD * fac[n]% MOD *modpow(m, n)% MOD *modpow(invm -1, n)% MOD);}}intmain(){freopen("tree.in","r",stdin);freopen("tree.out","w",stdout);read(n, m, typ);if(typ ==0) Solve0::solve();elseif(typ ==1) Solve1::solve();else Solve2::solve();return0;}