#define _CRT_SECURE_NO_WARNINGS
#define MATH_PI 3.14159265358979323846264338327950288419716939
#define MOD9 1000000007
#define INF 2147483647
#define INF_LLI 9223372036854775807
#define lli long long int
#include <iostream>
#include <string.h>
#include <fstream>
#include <math.h>
#include <iomanip>

using namespace std;

#ifdef _WIN32
#include "include_local.h"
#define DEBUG	1
#else
inline signed wait() { return 0; }
inline void dout(const char *arg, ...) {}
#endif

template<typename T>inline void SWAP(T &a, T &b) { T t = a; a = b; b = t; }
inline void CSWAP(char *&a, char *&b) { char *t = a; a = b; b = t; }

int _ret;

#define CLIP(ptr, min, max) {if((min)<=(max)){if(ptr<(min)){ptr=(min);}if(ptr>(max)){ptr=(max);}}}
//#define max(a, b) a > b ? a : b;
//#define min(a, b) a > b ? b : a;
#define Sin(deg) sin((deg)*MATH_PI/180.0)
#define Cos(deg) cos((deg)*MATH_PI/180.0)
#define Tan(deg) tan((deg)*MATH_PI/180.0)
#define Rad(deg) ((deg)*MATH_PI/180.0)
#define rep(param, num) for(int param=0 ; param<num ; ++param)
#define fi(num) for(int i=0 ; i<num ; ++i)
#define fj(num) for(int j=0 ; j<num ; ++j)
#define fk(num) for(int k=0 ; k<num ; ++k)
#define fl(num) for(int l=0 ; l<num ; ++l)
#define fn(num) for(int n=0 ; n<num ; ++n)
#define ffr(param, num) for(int param=num-1 ; param>=0 ; --param)
#define fir(num) for(int i=num-1 ; i>=0 ; --i)
#define fjr(num) for(int j=num-1 ; j>=0 ; --j)
#define fkr(num) for(int k=num-1 ; k>=0 ; --k)
#define flr(num) for(int l=num-1 ; l>=0 ; --l)
#define fnr(num) for(int n=num-1 ; n>=0 ; --n)

#define gi(p) int p; Gi(p)
#define gi2(p1, p2) int p1, p2; Gi2(p1, p2)
#define gi3(p1, p2, p3) int p1, p2, p3; Gi3(p1, p2, p3)
#define gi4(p1, p2, p3, p4) int p1, p2, p3, p4; Gi4(p1, p2, p3, p4)
#define glli(p) lli p; Glli(p)
#define glli2(p1, p2) lli p1, p2; Glli2(p1, p2)
#define glli3(p1, p2, p3) lli p1, p2, p3; Glli3(p1, p2, p3)
#define glli4(p1, p2, p3, p4) lli p1, p2, p3, p4; Glli4(p1, p2, p3, p4)
#define gf(p) double p; Gf(p);
#define gf2(p1, p2) double p1, p2; Gf2(p1, p2);
#define gf3(p1, p2, p3) double p1, p2, p3; Gf3(p1, p2, p3);
#define gf4(p1, p2, p3, p4) double p1, p2, p3, p4; Gf4(p1, p2, p3, p4)

#define gc(buf) Gc(buf);

#define Gi(p) _ret = Scanf("%d", p)
#define Gi2(p1, p2) _ret = Scanf2("%d %d", p1, p2)
#define Gi3(p1, p2, p3) _ret = Scanf3("%d %d %d", p1, p2, p3)
#define Gi4(p1, p2, p3, p4) _ret = Scanf4("%d %d %d %d", p1, p2, p3, p4)
#define Glli(p) _ret = Scanf("%lld", p)
#define Glli2(p1, p2) _ret = Scanf2("%lld %lld", p1, p2)
#define Glli3(p1, p2, p3) _ret = Scanf3("%lld %lld %lld", p1, p2, p3)
#define Glli4(p1, p2, p3, p4) _ret = Scanf4("%lld %lld %lld %lld", p1, p2, p3, p4)
#define Gf(p) _ret = Scanf("%lf", p)
#define Gf2(p1, p2) _ret = Scanf2("%lf %lf", p1, p2)
#define Gf3(p1, p2, p3) _ret = Scanf3("%lf %lf %lf", p1, p2, p3)
#define Gf4(p1, p2, p3, p4) _ret = Scanf4("%lf %lf %lf %lf", p1, p2, p3, p4)

#ifdef DEBUG
#define Gc(buf) _ret = fscanf(local_in.fp, "%s", buf)
#define Scanf(expr, p) _ret = fscanf(local_in.fp, expr, &p)
#define Scanf2(expr, p1, p2) _ret = fscanf(local_in.fp, expr, &p1, &p2)
#define Scanf3(expr, p1, p2, p3) _ret = fscanf(local_in.fp, expr, &p1, &p2, &p3)
#define Scanf4(expr, p1, p2, p3, p4) _ret = fscanf(local_in.fp, expr, &p1, &p2, &p3, &p4)
#else
#define Gc(buf) Scanf("%s", buf)
#define Scanf(expr, p) _ret = scanf(expr, &p)
#define Scanf2(expr, p1, p2) _ret = scanf(expr, &p1, &p2)
#define Scanf3(expr, p1, p2, p3) _ret = scanf(expr, &p1, &p2, &p3)
#define Scanf4(expr, p1, p2, p3, p4) _ret = scanf(expr, &p1, &p2, &p3, &p4)
#endif
#define out(p) cout << p << endl;
#define out_e(p) {cout << p << endl; return wait();}

void read(int num, int *ar) { fi(num) Gi(ar[i]); }
void read(int num, lli *ar) { fi(num) Glli(ar[i]); }
void read(int num, double *ar) { fi(num) Gf(ar[i]); }
void read(int num, int *ar1, int *ar2) { fi(num) Gi2(ar1[i], ar2[i]); }
void read(int num, lli *ar1, lli *ar2) { fi(num) Glli2(ar1[i], ar2[i]); }
void read(int num, double *ar1, double *ar2) { fi(num) Gf2(ar1[i], ar2[i]); }
void read(int num, int *ar1, int *ar2, int *ar3) { fi(num) Gi3(ar1[i], ar2[i], ar3[i]); }
void read(int num, lli *ar1, lli *ar2, lli *ar3) { fi(num) Glli3(ar1[i], ar2[i], ar3[i]); }
void read(int num, double *ar1, double *ar2, double *ar3) { fi(num) Gf3(ar1[i], ar2[i], ar3[i]); }
void read(int num, int *ar1, int *ar2, int *ar3, int *ar4) { fi(num) Gi4(ar1[i], ar2[i], ar3[i], ar4[i]); }
void read(int num, lli *ar1, lli *ar2, lli *ar3, lli *ar4) { fi(num) Glli4(ar1[i], ar2[i], ar3[i], ar4[i]); }
void read(int num, double *ar1, double *ar2, double *ar3, double *ar4) { fi(num) Gf4(ar1[i], ar2[i], ar3[i], ar4[i]); }

#define Yes out("Yes")
#define No out("No")
#define YES out("YES")
#define NO out("NO")

int ToBitArray(int n, int b, int *a){
	int m = 1, c = 0;
	for(int i=0 ; i<b ; ++i){ c += a[i] = n & m; m *= 2; }
	return c;
}
int ToBitArray(lli n, int b, int *a) {
	int m = 1, c = 0;
	for (int i = 0; i < b; ++i) { c += a[i] = n & m; m *= 2; }
	return c;
}

void CombSort(int N, int *ar, int order_ascending) { if (N <= 1) return; int h = int(N / 1.3); int flag; int i; while (true) { flag = 0; for (i = 0; i + h < N; ++i) { if ((order_ascending&&ar[i] > ar[i + h]) || (!order_ascending&&ar[i] < ar[i + h])) { swap<int>(ar[i], ar[i + h]); flag = 1; } }if (h == 1 && !flag)break; if (h == 9 || h == 10) h = 11; if (h > 1)h = int(h / 1.3); } }
void CombSort_ll(int N, lli *ar, int order_ascending) { if (N <= 1) return; int h = int(N / 1.3); int flag; int i; while (true) { flag = 0; for (i = 0; i + h < N; ++i) { if ((order_ascending&&ar[i] > ar[i + h]) || (!order_ascending&&ar[i] < ar[i + h])) { swap<lli>(ar[i], ar[i + h]); flag = 1; } }if (h == 1 && !flag)break; if (h == 9 || h == 10) h = 11; if (h > 1)h = int(h / 1.3); } }

int EuclideanAlgorithm(int N, int *ar){
	fn(N - 1){
		while (true){ 
			if(ar[n] == 0 || ar[n+1] == 0){
				if(ar[n] < ar[n+1]) ar[n] = ar[n+1];
				ar[n+1] = ar[n];
				break;
			}
			if (ar[n] % ar[n + 1] == 0 || ar[n + 1] % ar[n] == 0) {
				ar[n + 1] = ar[n] < ar[n + 1] ? ar[n] : ar[n + 1];
				break; 
			}
			if (ar[n] > ar[n + 1]) {
				ar[n] %= ar[n + 1];
			} 
			else { 
				ar[n + 1] %= ar[n]; 
			} 
		} 
	}
	return ar[N - 1];
}
int Euclid(int n, int *ar){
	return EuclideanAlgorithm(n, ar);
}
lli EuclideanAlgorithm_lli(int N, lli *ar) {
	fn(N - 1) {
		while (true) {
			if (ar[n] == 0 || ar[n + 1] == 0) {
				if (ar[n] < ar[n + 1]) ar[n] = ar[n + 1];
				ar[n + 1] = ar[n];
				break;
			}
			if (ar[n] % ar[n + 1] == 0 || ar[n + 1] % ar[n] == 0) {
				ar[n + 1] = ar[n] < ar[n + 1] ? ar[n] : ar[n + 1];
				break;
			}
			if (ar[n] > ar[n + 1]) {
				ar[n] %= ar[n + 1];
			}
			else {
				ar[n + 1] %= ar[n];
			}
		}
	}
	return ar[N - 1];
}
lli Euclid_lli(int n, lli *ar) {
	return EuclideanAlgorithm_lli(n, ar);
}
int EuclideanAlgorithmPreserved(int N, int *ar) {
	int a, b;
	a = ar[0];
	fn(N - 1) {
		b = ar[n + 1];
		while (true) {
			if(a == 0 || b == 0){
				if(a < b) a = b;
				b = a;
				break;
			}
			if (a % b == 0 || b % a == 0) {
				b = a < b ? a : b;
				break;
			}
			if (a > b) {
				a %= b;
			}
			else {
				b %= a;
			}
		}
		a = b;
	}
	return a;
}
int Euclid2(int n, int *ar) {
	return EuclideanAlgorithmPreserved(n, ar);
}

template<typename T>void CombSort(int N, T *ar, int order_ascending) {
	if (N <= 1) return;
	int i, flag;
	int h = int(N / 1.3);
	while (true) {
		flag = 0;
		for (i = 0; i + h < N; ++i) {
			if (
				order_ascending && ar[i].SortValue > ar[i + h].SortValue ||
				!order_ascending && ar[i].SortValue < ar[i + h].SortValue
				) {
				SWAP<T>(ar[i], ar[i + h]);
				flag = 1;
			}
		}
		if (h > 1) {
			h = int(h / 1.3);
			if (h == 9 || h == 10) h = 11;
		}
		else {
			if (!flag) break;
		}
	}
}
#include <vector>
#include <algorithm>

struct UnionFind {
	vector<int> par; // par[i]:iの親の番号　(例) par[3] = 2 : 3の親が2

	UnionFind(int N) : par(N) { //最初は全てが根であるとして初期化
		for (int i = 0; i < N; i++) par[i] = i;
	}

	int root(int x) { // データxが属する木の根を再帰で得る：root(x) = {xの木の根}
		if (par[x] == x) return x;
		return par[x] = root(par[x]);
	}

	void unite(int x, int y) { // xとyの木を併合
		int rx = root(x); //xの根をrx
		int ry = root(y); //yの根をry
		if (rx == ry) return; //xとyの根が同じ(=同じ木にある)時はそのまま
		par[rx] = ry; //xとyの根が同じでない(=同じ木にない)時：xの根rxをyの根ryにつける
	}

	bool same(int x, int y) { // 2つのデータx, yが属する木が同じならtrueを返す
		int rx = root(x);
		int ry = root(y);
		return rx == ry;
	}
};


void Replace(char *c, int len, char before, char after) {
	fi(len){
		if(c[i] == before) c[i] = after;
	}
}
void Replace(char *c, char before, char after){
	int len = strlen(c);
	Replace(c, len, before, after);
}

/*
class csStack{
public:
	csStack(){
		num = 0;
	}
	void alloc(int size){
		param = new int[size];
	}
	void sort(int order = 1){
		if(num > 1) CombSort(num, param, order);
	}

	int num;
	int *param;

	void push(int p){
		param[num++] = p;
	}
};

class csPosition{
public:
	csPosition(){x = y = 0;}
	int x, y;
};
typedef class csPosition POS;

template<typename T>
class csPos{
public:
	csPos(){x = y = 0;}
	T x, y;
};

*/
char ch[200010], cbuf[128][1024];

#define NodeType int
#define ValueType int
typedef class csNode NODE;
typedef class csPath PATH;
typedef class csEdge EDGE;
class csPath {
public:
	NodeType To;
	ValueType Dist;
	PATH* prev, * next;
};
class csEdge {
public:
	NodeType f, t;
	ValueType d;
};
class csNode {
	PATH* path_tmp;
	int finished;
public:
	csNode() {
		nPath = 0;
	}

	PATH* path_head, * path_tail;
	int nPath;

	inline void Add(NodeType to, ValueType d);
	inline PATH* GetFirstPath() {
		if (nPath == 0) return NULL;
		finished = 0;
		path_tmp = path_head;
		return path_tmp;
	};
	inline PATH* GetNextPath() {
		if (finished) return NULL;
		path_tmp = path_tmp->next;
		if (path_tmp == path_tail) finished = 1;
		return path_tmp;
	}
};

class csTree {
public:
	csTree() {
		nPathPool = 0;
	}

	void Make();

	PATH PathPool[100010 * 2];
	int nPathPool;
	inline PATH* Get() {
		PATH* ret = &PathPool[nPathPool++];
		ret->prev = ret->next = NULL;
		ret->To = -1;
		return ret;
	}
	int nNode;
	NODE Node[100010];
	int nEdge;
	EDGE Edge[100010];
};
csTree Tree;

inline void csNode::Add(NodeType to, ValueType d) {
	PATH* p = Tree.Get();
	p->To = to;
	p->Dist = d;
	if (nPath == 0) {
		path_head = path_tail = p;
	}
	else {
		path_tail->next = p;
		p->prev = path_tail;
		path_tail = p;
	}
	++nPath;
}

inline void csTree::Make() {
	csEdge* p;
	NodeType f, t;
	ValueType d;
	fi(nEdge) {
		f = Edge[i].f;
		t = Edge[i].t;
		d = Edge[i].d;
		Node[f].Add(t, d);
		Node[t].Add(f, d);
	}

}

#include <iostream>

const int MAX = 110000;
const int MOD = 1000000007;

long long fac[MAX], finv[MAX], inv[MAX];

// テーブルを作る前処理
void COMinit() {
	fac[0] = fac[1] = 1;
	finv[0] = finv[1] = 1;
	inv[1] = 1;
	for (int i = 2; i < MAX; i++) {
		fac[i] = fac[i - 1] * i % MOD;
		inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
		finv[i] = finv[i - 1] * inv[i] % MOD;
	}
}

// 二項係数計算
long long COM(int n, int k) {
	if (n < k) return 0;
	if (n < 0 || k < 0) return 0;
	return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}
int stack[100010] = {0};
int from[100010];

int nstack = 0;
int f[100010];

signed main() {

	COMinit();

	lli factorial = 1;
	for (int i = 1; i < 100010; ++i)
	{
		factorial *= i;
		factorial %= MOD9;
		f[i] = factorial;
	}
	
	
	int a, b;
	glli2(N, K);
	fi(N-1){
		Gi2(a, b);
		Tree.Node[a].Add(b, 1);
		Tree.Node[b].Add(a, 1);
	}
	
	if(N == 1){
		out_e(K);
	}

	int p = 1;
	lli c = K;
	fi(Tree.Node[p].nPath){
		if(i == 0){
			stack[nstack] = Tree.Node[p].GetFirstPath()->To;
			from[nstack] = p;
		}else{
			stack[nstack] = Tree.Node[p].GetNextPath()->To;
			from[nstack] = p;
		}
		nstack++;

		c *= K - (long long int)(i + 1);
		c %= MOD9;
	}
	if(N == 2){
		out_e(c);
	}

	lli com;
	int to, frm, nchild;
	while(true){
		p = stack[nstack-1];
		frm = from[nstack-1];
		nstack--;

		nchild = 0;
		fi(Tree.Node[p].nPath){
			if (i == 0) {
				to = Tree.Node[p].GetFirstPath()->To;
			}else{
				to = Tree.Node[p].GetNextPath()->To;
			}
			if(to != frm){
				stack[nstack] = to;
				from[nstack] = p;
				nstack++;
				nchild++;
			}
		}

		if(nchild > 0){
			com = COM(K-2, nchild);
			c *= com;
			c %= MOD;
			c *= f[nchild];
			c %= MOD;
		}
		if(nstack == 0) break;

	}
		
	out(c);

	return wait();


}



Measured memory_bytes: 12544