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

#define ll long long

template <typename T>
void pfill(T* pst, const T* ped, T val) {
	for ( ; pst != ped; *(pst++) = val);
}

template <typename T>
void pcopy(T* pst, const T* ped, T* pval) {
	for ( ; pst != ped; *(pst++) = *(pval++));
}

const int N = 262144;
const int Mod = 998244353;
const int bzmax = 19;
const int g = 3;

void exgcd(int a, int b, int& x, int& y) {
	if (!b) {
		x = 1, y = 0;
	} else {
		exgcd(b, a % b, y, x);
		y -= (a / b) * x;
	}
}

int inv(int a) {
	int x, y;
	exgcd(a, Mod, x, y);
	return (x < 0) ? (x + Mod) : (x);
}

template <const int Mod = :: Mod>
class Z {
	public:
		int v;

		Z() : v(0) {	}
		Z(int v) : v(v) {	}
		Z(ll x) : v(x % Mod) {	}

		Z operator + (Z b) {
			int x = v + b.v;
			return Z((x >= Mod) ? (x - Mod) : (x));
		}
		Z operator - (Z b) {
			int x = v - b.v;
			return Z((x < 0) ? (x + Mod) : (x));
		}
		Z operator * (Z b) {
			return Z(1ll * v * b.v);
		}
		Z operator ~ () {
			return inv(v);
		}
		Z operator -() {
			return Z(0) - *this;
		}

		Z& operator += (Z b) {
			return *this = *this + b;
		}
		Z& operator -= (Z b) {
			return *this = *this - b;
		}
		Z& operator *= (Z b) {
			return *this = *this * b;
		}

//		constexpr operator int () const {
//			return v;
//		}
};

typedef Z<> Zi;

Zi qpow(Zi a, int p) {
	if (p < Mod - 1)
		p += Mod - 1;
	Zi rt = 1, pa = a;
	for ( ; p; p >>= 1, pa = pa * pa) {
		if (p & 1) {
			rt = rt * pa;
		}
	}
	return rt;
}

class NTT {
	private:
		Zi gn[bzmax + 4], _gn[bzmax + 4];
	public:

		NTT() {
			for (int i = 0; i <= bzmax; i++) {
				gn[i] = qpow(Zi(g), (Mod - 1) >> i);
				_gn[i] = qpow(Zi(g), -((Mod - 1) >> i));
			}
		}

		void operator () (Zi* f, int len, int sgn) {
			for (int i = 1, j = len >> 1, k; i < len - 1; i++, j += k) {
				if (i < j)
					swap(f[i], f[j]);
				for (k = len >> 1; k <= j; j -= k, k >>= 1);
			}

			Zi *wn = (sgn > 0) ? (gn + 1) : (_gn + 1), w, a, b;
			for (int l = 2, hl; l <= len; l <<= 1, wn++) {
				hl = l >> 1, w = 1;
				for (int i = 0; i < len; i += l, w = 1) {
					for (int j = 0; j < hl; j++, w *= *wn) {
						a = f[i + j], b = f[i + j + hl] * w;
						f[i + j] = a + b;
						f[i + j + hl] = a - b;
					}
				}
			}

			if (sgn < 0) {
				Zi invlen = ~Zi(len);
				for (int i = 0; i < len; i++) {
					f[i] *= invlen;
				}
			}
		}

		int correct_len(int len) {
			int m = 1;
			for ( ; m <= len; m <<= 1);
			return m;
		}
} NTT;

void pol_inverse(Zi* f, Zi* g, int n) {
	static Zi A[N];
	if (n == 1) {
		g[0] = ~f[0];
	} else {
		int hn = (n + 1) >> 1, t = NTT.correct_len(n << 1 | 1);
		pol_inverse(f, g, hn);

		pcopy(A, A + n, f);
		pfill(A + n, A + t, Zi(0));
		pfill(g + hn, g + t, Zi(0));
		NTT(A, t, 1);
		NTT(g, t, 1);
		for (int i = 0; i < t; i++) {
			g[i] = g[i] * (Zi(2) - g[i] * A[i]);
		}
		NTT(g, t, -1);
		pfill(g + n, g + t, Zi(0));
	}
}

typedef vector<Zi> Poly;

Poly operator + (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	int t = max(n, m);
	A.resize(t), B.resize(t);
	for (int i = 0; i < t; i++) {
		A[i] += B[i];
	}
	return A;
}

Poly operator - (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	int t = max(n, m);
	A.resize(t), B.resize(t);
	for (int i = 0; i < t; i++) {
		A[i] -= B[i];
	}
	return A;
}

Poly operator * (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	int k = NTT.correct_len(n + m - 1);
	if (n < 20 || m < 20) {
		Poly rt (n + m - 1);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				rt[i + j] += A[i] * B[j];
			}
		}
		return rt;
	}
	A.resize(k), B.resize(k);
	NTT(A.data(), k, 1);
	NTT(B.data(), k, 1);
	for (int i = 0; i < k; i++) {
		A[i] *= B[i];
	}
	NTT(A.data(), k, -1);
	A.resize(n + m - 1);
	return A;
}

Poly operator ~ (Poly f) {
	int n = f.size(), t = NTT.correct_len((n << 1) | 1);
	Poly rt (t);
	f.resize(t);
	pol_inverse(f.data(), rt.data(), n);
	rt.resize(n);
	return rt;
}

Poly operator / (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	if (n < m) {
		return Poly {0};
	}
	int r = n - m + 1;
	reverse(A.begin(), A.end());
	reverse(B.begin(), B.end());
	A.resize(r), B.resize(r);
	A = A * ~B;
	A.resize(r);
	reverse(A.begin(), A.end());
	return A;
}

Poly operator % (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	if (n < m) {
		return A;
	}
	if (m == 1) {
		return Poly {0};
	}
	A = A - A / B * B;
	A.resize(m - 1);
	return A;
}

Zi Inv[N];
void init_inv(int n) {
	Inv[0] = 0, Inv[1] = 1;
	for (int i = 2; i <= n; i++) {
		Inv[i] = Inv[Mod % i] * Zi((Mod - (Mod / i)));
	}
}

Zi fac[N], _fac[N];
Zi comb(int n, int m) {
	return (n < m) ? (0) : (fac[n] * _fac[m] * _fac[n - m]);
}
void init_fac(int n) {
	fac[0] = 1;
	for (int i = 1; i <= n; i++) {
		fac[i] = fac[i - 1] * i;
	}
	_fac[n] = ~fac[n];
	for (int i = n; i; i--) {
		_fac[i - 1] = _fac[i] * i;
	}
}

int n, K;
int sz[N];
vector<int> G[N];

void dfs1(int p, int fa) {
	sz[p] = 1;
	for (auto& e : G[p]) {
		if (e ^ fa) {
			dfs1(e, p);
			sz[p] += sz[e];
		}
	}
}

Poly dividing(int n, Zi* a) {
	if (n == 1) {
		return Poly {1, *a};
	}
	int hn = n >> 1;
	return dividing(hn, a) * dividing(n - hn, a + hn);
}

Poly divide2(Poly F, int a1, int a0) {
	Zi b = 0, _a1 = Inv[a1];
	for (int i = (signed) F.size() - 1; i; i--) {
		b = F[i] * _a1;
		F[i] = b, F[i - 1] -= b * a0;
	}
	assert(!F[0].v);
	for (int i = 0; i < (signed) F.size() - 1; i++) {
		F[i] = F[i + 1];
	}
	F.pop_back();
	return F;
}

Zi ans = 0;
Zi dfs2(int p, int fa) {
	vector<Zi> Sz;
	if (fa) {
		Sz.push_back(n - sz[p]);
	}
	for (auto& e : G[p]) {
		if (e ^ fa) {
			Sz.push_back(sz[e]);
		}
	}
	Poly H = dividing(Sz.size(), Sz.data());
	sort(G[p].begin(), G[p].end(), [&] (const int& a, const int& b) {
			return sz[a] < sz[b];
		});
	int lst = -1;
	Poly f;
	Zi rt = 0, tmp, cur;
	for (auto& e : G[p]) {
		if (e == fa) {
			continue;
		}
		if (sz[e] != lst) {
			f = divide2(H, sz[e], 1);
			if ((signed) f.size() > K + 1) {
				f.resize(K + 1);
			}
			cur = 0;
			for (int i = 0; i < (signed) f.size(); i++) {
				cur += f[i] * comb(K, i) * fac[i];
			}
		}
		tmp = dfs2(e, p);
		lst = sz[e];
//		cerr << p << " " << (rt * tmp).v << " " << (tmp * cur).v << '\n';
		ans += tmp * (rt + cur);
		rt += tmp;
	}
	if (fa) {
		int x = n - sz[p];
		f = divide2(H, x, 1);
		if ((signed) f.size() > K + 1) {
			f.resize(K + 1);
		}
		tmp = 0;
		for (int i = 0; i < (signed) f.size(); i++) {
			tmp += f[i] * comb(K, i) * fac[i];
		}
		rt += tmp;
	}
	return rt;
}

int main() {
	scanf("%d%d", &n, &K);
	if (K == 1 || n == 1) {
		printf("%d\n", ((n * 1ll * (n - 1)) >> 1) % Mod);
		return 0;
	}
	init_inv(n);
	init_fac(K);
	for (int i = 1, u, v; i < n; i++) {
		scanf("%d%d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs1(1, 0);
	dfs2(1, 0);
	printf("%d\n", ans.v);
	return 0;
}


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

#define ll long long

template <typename T>
void pfill(T* pst, const T* ped, T val) {
	for ( ; pst != ped; *(pst++) = val);
}

template <typename T>
void pcopy(T* pst, const T* ped, T* pval) {
	for ( ; pst != ped; *(pst++) = *(pval++));
}

const int N = 262144;
const int Mod = 998244353;
const int bzmax = 19;
const int g = 3;

void exgcd(int a, int b, int& x, int& y) {
	if (!b) {
		x = 1, y = 0;
	} else {
		exgcd(b, a % b, y, x);
		y -= (a / b) * x;
	}
}

int inv(int a) {
	int x, y;
	exgcd(a, Mod, x, y);
	return (x < 0) ? (x + Mod) : (x);
}

template <const int Mod = :: Mod>
class Z {
	public:
		int v;

		Z() : v(0) {	}
		Z(int v) : v(v) {	}
		Z(ll x) : v(x % Mod) {	}

		Z operator + (Z b) {
			int x = v + b.v;
			return Z((x >= Mod) ? (x - Mod) : (x));
		}
		Z operator - (Z b) {
			int x = v - b.v;
			return Z((x < 0) ? (x + Mod) : (x));
		}
		Z operator * (Z b) {
			return Z(1ll * v * b.v);
		}
		Z operator ~ () {
			return inv(v);
		}
		Z operator -() {
			return Z(0) - *this;
		}

		Z& operator += (Z b) {
			return *this = *this + b;
		}
		Z& operator -= (Z b) {
			return *this = *this - b;
		}
		Z& operator *= (Z b) {
			return *this = *this * b;
		}

//		constexpr operator int () const {
//			return v;
//		}
};

typedef Z<> Zi;

Zi qpow(Zi a, int p) {
	if (p < Mod - 1)
		p += Mod - 1;
	Zi rt = 1, pa = a;
	for ( ; p; p >>= 1, pa = pa * pa) {
		if (p & 1) {
			rt = rt * pa;
		}
	}
	return rt;
}

class NTT {
	private:
		Zi gn[bzmax + 4], _gn[bzmax + 4];
	public:

		NTT() {
			for (int i = 0; i <= bzmax; i++) {
				gn[i] = qpow(Zi(g), (Mod - 1) >> i);
				_gn[i] = qpow(Zi(g), -((Mod - 1) >> i));
			}
		}

		void operator () (Zi* f, int len, int sgn) {
			for (int i = 1, j = len >> 1, k; i < len - 1; i++, j += k) {
				if (i < j)
					swap(f[i], f[j]);
				for (k = len >> 1; k <= j; j -= k, k >>= 1);
			}

			Zi *wn = (sgn > 0) ? (gn + 1) : (_gn + 1), w, a, b;
			for (int l = 2, hl; l <= len; l <<= 1, wn++) {
				hl = l >> 1, w = 1;
				for (int i = 0; i < len; i += l, w = 1) {
					for (int j = 0; j < hl; j++, w *= *wn) {
						a = f[i + j], b = f[i + j + hl] * w;
						f[i + j] = a + b;
						f[i + j + hl] = a - b;
					}
				}
			}

			if (sgn < 0) {
				Zi invlen = ~Zi(len);
				for (int i = 0; i < len; i++) {
					f[i] *= invlen;
				}
			}
		}

		int correct_len(int len) {
			int m = 1;
			for ( ; m <= len; m <<= 1);
			return m;
		}
} NTT;

void pol_inverse(Zi* f, Zi* g, int n) {
	static Zi A[N];
	if (n == 1) {
		g[0] = ~f[0];
	} else {
		int hn = (n + 1) >> 1, t = NTT.correct_len(n << 1 | 1);
		pol_inverse(f, g, hn);

		pcopy(A, A + n, f);
		pfill(A + n, A + t, Zi(0));
		pfill(g + hn, g + t, Zi(0));
		NTT(A, t, 1);
		NTT(g, t, 1);
		for (int i = 0; i < t; i++) {
			g[i] = g[i] * (Zi(2) - g[i] * A[i]);
		}
		NTT(g, t, -1);
		pfill(g + n, g + t, Zi(0));
	}
}

typedef vector<Zi> Poly;

Poly operator + (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	int t = max(n, m);
	A.resize(t), B.resize(t);
	for (int i = 0; i < t; i++) {
		A[i] += B[i];
	}
	return A;
}

Poly operator - (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	int t = max(n, m);
	A.resize(t), B.resize(t);
	for (int i = 0; i < t; i++) {
		A[i] -= B[i];
	}
	return A;
}

Poly operator * (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	int k = NTT.correct_len(n + m - 1);
	if (n < 20 || m < 20) {
		Poly rt (n + m - 1);
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				rt[i + j] += A[i] * B[j];
			}
		}
		return rt;
	}
	A.resize(k), B.resize(k);
	NTT(A.data(), k, 1);
	NTT(B.data(), k, 1);
	for (int i = 0; i < k; i++) {
		A[i] *= B[i];
	}
	NTT(A.data(), k, -1);
	A.resize(n + m - 1);
	return A;
}

Poly operator ~ (Poly f) {
	int n = f.size(), t = NTT.correct_len((n << 1) | 1);
	Poly rt (t);
	f.resize(t);
	pol_inverse(f.data(), rt.data(), n);
	rt.resize(n);
	return rt;
}

Poly operator / (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	if (n < m) {
		return Poly {0};
	}
	int r = n - m + 1;
	reverse(A.begin(), A.end());
	reverse(B.begin(), B.end());
	A.resize(r), B.resize(r);
	A = A * ~B;
	A.resize(r);
	reverse(A.begin(), A.end());
	return A;
}

Poly operator % (Poly A, Poly B) {
	int n = A.size(), m = B.size();
	if (n < m) {
		return A;
	}
	if (m == 1) {
		return Poly {0};
	}
	A = A - A / B * B;
	A.resize(m - 1);
	return A;
}

Zi Inv[N];
void init_inv(int n) {
	Inv[0] = 0, Inv[1] = 1;
	for (int i = 2; i <= n; i++) {
		Inv[i] = Inv[Mod % i] * Zi((Mod - (Mod / i)));
	}
}

Zi fac[N], _fac[N];
Zi comb(int n, int m) {
	return (n < m) ? (0) : (fac[n] * _fac[m] * _fac[n - m]);
}
void init_fac(int n) {
	fac[0] = 1;
	for (int i = 1; i <= n; i++) {
		fac[i] = fac[i - 1] * i;
	}
	_fac[n] = ~fac[n];
	for (int i = n; i; i--) {
		_fac[i - 1] = _fac[i] * i;
	}
}

int n, K;
int sz[N];
vector<int> G[N];

void dfs1(int p, int fa) {
	sz[p] = 1;
	for (auto& e : G[p]) {
		if (e ^ fa) {
			dfs1(e, p);
			sz[p] += sz[e];
		}
	}
}

Poly dividing(int n, Zi* a) {
	if (n == 1) {
		return Poly {1, *a};
	}
	int hn = n >> 1;
	return dividing(hn, a) * dividing(n - hn, a + hn);
}

Poly divide2(Poly F, int a1, int a0) {
	Zi b = 0, _a1 = Inv[a1];
	for (int i = (signed) F.size() - 1; i; i--) {
		b = F[i] * _a1;
		F[i] = b, F[i - 1] -= b * a0;
	}
	assert(!F[0].v);
	for (int i = 0; i < (signed) F.size() - 1; i++) {
		F[i] = F[i + 1];
	}
	F.pop_back();
	return F;
}

Zi ans = 0;
Zi dfs2(int p, int fa) {
	vector<Zi> Sz;
	if (fa) {
		Sz.push_back(n - sz[p]);
	}
	for (auto& e : G[p]) {
		if (e ^ fa) {
			Sz.push_back(sz[e]);
		}
	}
	Poly H = dividing(Sz.size(), Sz.data());
	sort(G[p].begin(), G[p].end(), [&] (const int& a, const int& b) {
			return sz[a] < sz[b];
		});
	int lst = -1;
	Poly f;
	Zi rt = 0, tmp, cur;
	for (auto& e : G[p]) {
		if (e == fa) {
			continue;
		}
		if (sz[e] != lst) {
			f = divide2(H, sz[e], 1);
			if ((signed) f.size() > K + 1) {
				f.resize(K + 1);
			}
		}
		tmp = dfs2(e, p), cur = 0;
		for (int i = 0; i < (signed) f.size(); i++) {
			cur += f[i] * comb(K, i) * fac[i];
		}
//		cerr << p << " " << (rt * tmp).v << " " << (tmp * cur).v << '\n';
		ans += tmp * (rt + cur);
		rt += tmp;
	}
	if (fa) {
		int x = n - sz[p];
		f = divide2(H, x, 1);
		if ((signed) f.size() > K + 1) {
			f.resize(K + 1);
		}
		tmp = 0;
		for (int i = 0; i < (signed) f.size(); i++) {
			tmp += f[i] * comb(K, i) * fac[i];
		}
		rt += tmp;
	}
	return rt;
}

int main() {
	scanf("%d%d", &n, &K);
	if (K == 1) {
		printf("%d\n", ((n * 1ll * (n - 1)) >> 1) % Mod);
		return 0;
	}
	init_inv(n);
	init_fac(K);
	for (int i = 1, u, v; i < n; i++) {
		scanf("%d%d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs1(1, 0);
	dfs2(1, 0);
	printf("%d\n", ans.v);
	return 0;
}


//by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
#define bged(v) (v).begin(),(v).end()
#define foreach(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
typedef long long ll;
const int Imx=2147483647;
const ll Lbig=2e18;
//My i/o stream
struct fastio
{
	char s[100000];
	int it,len;
	fastio(){it=len=0;}
	inline char get()
	{
		if(it<len)return s[it++];it=0;
		len=fread(s,1,100000,stdin);
		if(len==0)return EOF;else return s[it++];
	}
	bool notend()
	{
		char c=get();
		while(c==' '||c=='\n')c=get();
		if(it>0)it--;
		return c!=EOF;
	}
}_buff;
#define geti(x) x=getnum()
#define getii(x,y) geti(x),geti(y)
#define getiii(x,y,z) getii(x,y),geti(z)
#define puti(x) putnum(x),putchar(' ')
#define putii(x,y) puti(x),puti(y)
#define putiii(x,y,z) putii(x,y),puti(z)
#define putsi(x) putnum(x),putchar('\n')
#define putsii(x,y) puti(x),putsi(y)
#define putsiii(x,y,z) putii(x,y),putsi(z)
inline ll getnum()
{
	ll r=0;bool ng=0;char c;c=_buff.get();
	while(c!='-'&&(c<'0'||c>'9'))c=_buff.get();
	if(c=='-')ng=1,c=_buff.get();
	while(c>='0'&&c<='9')r=r*10+c-'0',c=_buff.get();
	return ng?-r:r;
}
template<class T> inline void putnum(T x)
{
	if(x<0)putchar('-'),x=-x;
	register short a[20]={},sz=0;
	while(x)a[sz++]=x%10,x/=10;
	if(sz==0)putchar('0');
	for(int i=sz-1;i>=0;i--)putchar('0'+a[i]);
}
inline char getreal(){char c=_buff.get();while(c<=32)c=_buff.get();return c;}

//Template: Polynomial
//Author: FizzyDavid
//Last edit: 2018/04/17
/*
You should INITIALIZE with comb_init() and FFTprecalc() before you use the polynomial functions.
Mod should be prime.
You should choose NTT head or FFT head.
The input numbers should be in range (-mod,mod).
The result nubmers are in range (-mod,mod).
*/
const int mod=998244353;
ll qpow(ll x,ll k){return k==0?1:qpow(x*x%mod,k>>1)*(k&1?x:1)%mod;}

const int proot=3;//for NTT only
const int FFTbitn=18;
const int FFTpmx=1<<FFTbitn;
const int FFTmx=FFTpmx+233;//should be slightly larger than FFTpmx
const int FFTbit=15;//for FFT only  max_value=2^(2*FFTbit)
#define useNTT //if you use the NTT head

const int comb_mx=FFTmx;
ll inv[comb_mx],fac[comb_mx],ifac[comb_mx];
//use comb_init() before FFT
//mod should be prime
void comb_init()
{
	fac[0]=1;
	for(int i=1;i<comb_mx;i++)fac[i]=fac[i-1]*i%mod;
	ifac[comb_mx-1]=qpow(fac[comb_mx-1],mod-2);
	for(int i=comb_mx-2;i>=0;i--)ifac[i]=ifac[i+1]*(i+1)%mod;
	inv[1]=1;
	for(int i=2;i<comb_mx;i++)inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
}
int uptopow(int x)
{
	while(x!=(x&(-x)))x+=x&(-x);
	return x;
}
#ifdef useNTT
//-----------------NTT head-----------------
int fsz,w_pre[FFTmx];
void FFTinit(int sz)
{
	fsz=uptopow(sz);
	assert(fsz<=FFTpmx);
}
typedef unsigned long long ull;
void FFT(int a[],int coef)
{
	static ull f_a[FFTmx];
	static int w[FFTmx];
	for(int i=0,j=0;i<fsz;i++)
	{
		f_a[j]=a[i]<0?a[i]+mod:a[i];
		for(int l=fsz>>1;(j^=l)<l;l>>=1);
	}
	const ull md2=1ull*mod*mod;
	for(int l=1;l<fsz;l<<=1)
	{
		int l2=l<<1,u=FFTpmx/l2;
		if(coef==1)for(int j=0,j2=0;j<l;j++,j2+=u)w[j]=w_pre[j2];
		else for(int j=0,j2=FFTpmx;j<l;j++,j2-=u)w[j]=w_pre[j2];
		for(int i=0;i<fsz;i+=l2)
		{
			for(int j=0;j<l;j++)
			{
				ull tmp=f_a[i+j+l]%mod*w[j];
				f_a[i+j+l]=f_a[i+j]+md2-tmp;
				f_a[i+j]+=tmp;
			}
		}
		if(l==(1<<16))for(int j=0;j<fsz;j++)f_a[j]%=mod;
	}
	for(int i=0;i<fsz;i++)a[i]=f_a[i]%mod;
	if(coef==-1)
	{
		int inv=qpow(fsz,mod-2);
		for(int i=0;i<fsz;i++)a[i]=1ll*a[i]*inv%mod;
	}
}
void FFTprecalc()
{
	w_pre[0]=1;
	int ww=qpow(proot,(mod-1)/FFTpmx);
	for(int i=1;i<=FFTpmx;i++)w_pre[i]=1ll*w_pre[i-1]*ww%mod;
}
//Multiply polynomial a[0...an-1] and b[0...bn-1]  Store in c[0...cn-1]
void polymul(int a[],int an,int b[],int bn,int c[],int cn=-1)
{
	static int mul_a[FFTmx],mul_b[FFTmx];
	if(cn==-1)cn=an+bn;
	an=min(an,cn);bn=min(bn,cn);
	if(1ll*an*bn<=4096)
	{
		for(int i=0;i<an+bn;i++)mul_a[i]=0;
		for(int i=0;i<an;i++)
			for(int j=0;j<bn;j++)
				mul_a[i+j]=(mul_a[i+j]+1ll*a[i]*b[j])%mod;
		for(int i=0;i<cn;i++)c[i]=mul_a[i];
		return;
	}
	FFTinit(an+bn);
	for(int i=0;i<fsz;i++)mul_a[i]=i<an?a[i]:0;
	for(int i=0;i<fsz;i++)mul_b[i]=i<bn?b[i]:0;
	FFT(mul_a,1);
	FFT(mul_b,1);
	for(int i=0;i<fsz;i++)mul_a[i]=1ll*mul_a[i]*mul_b[i]%mod;
	FFT(mul_a,-1);
	for(int i=0;i<cn;i++)c[i]=mul_a[i];
}
//---------------NTT head end---------------
#else
//-----------------FTT head-----------------
const double pi=acos(-1);
struct point
{
	double x,y;
	point(double _x=0,double _y=0){x=_x;y=_y;}
	point operator+(const point &t)const{return point(x+t.x,y+t.y);}
	point operator-(const point &t)const{return point(x-t.x,y-t.y);}
	point operator*(const point &t)const{return point(x*t.x-y*t.y,x*t.y+y*t.x);}
	point conj()const{return point(x,-y);}
};
int fsz;
point w_pre[FFTmx];
void FFTprecalc()
{
	for(int i=0;i<=FFTpmx;i++)w_pre[i]=point(cos(2.0/FFTpmx*i*pi),sin(2.0/FFTpmx*i*pi));
}
void FFTinit(int n)
{
	fsz=uptopow(n);
	assert(fsz<=FFTpmx);
}
void FFT(point a[],int coef)
{
	static point w[FFTmx];
	for(int i=0,j=0;i<fsz;i++)
	{
		if(i<j)swap(a[i],a[j]);
		for(int l=fsz>>1;(j^=l)<l;l>>=1);
	}
	for(int l=1;l<fsz;l<<=1)
	{
		int l2=l<<1,u=FFTpmx/l2;
		if(coef==1)for(int j=0,j2=0;j<l;j++,j2+=u)w[j]=w_pre[j2];
		else for(int j=0,j2=FFTpmx;j<l;j++,j2-=u)w[j]=w_pre[j2];
		for(int i=0;i<fsz;i+=l2)
		{
			for(int j=0;j<l;j++)
			{
				point tmp=a[i+l+j]*w[j];
				a[i+l+j]=a[i+j]-tmp;
				a[i+j]=a[i+j]+tmp;
			}
		}
	}
	if(coef==-1)
	{
		for(int i=0;i<fsz;i++)a[i]=a[i]*(1.0/fsz);
	}
}
//Multiply polynomial a[0...an-1] and b[0...bn-1]  Store in c[0...cn-1]
void polymul(int a[],int an,int b[],int bn,int c[],int cn=-1)
{
	static point tl[FFTmx],tr[FFTmx],ta[FFTmx],tb[FFTmx];
	if(cn==-1)cn=an+bn;
	an=min(an,cn);bn=min(bn,cn);
	FFTinit(an+bn);
	int msk=(1<<FFTbit)-1;
	for(int i=0;i<fsz;i++)
	{
		ta[i]=i<an?point((a[i]>=0?a[i]:a[i]+mod)&msk,(a[i]>=0?a[i]:a[i]+mod)>>FFTbit):0;
		tb[i]=i<bn?point((b[i]>=0?b[i]:b[i]+mod)&msk,(b[i]>=0?b[i]:b[i]+mod)>>FFTbit):0;
	}
	FFT(ta,1);ta[fsz]=ta[0];
	FFT(tb,1);tb[fsz]=tb[0];
	for(int i=0;i<fsz;i++)
	{
		point a0=(ta[i]+ta[fsz-i].conj())*point(+0.5,0),a1=(ta[i]-ta[fsz-i].conj())*point(0,-0.5);
		point b0=(tb[i]+tb[fsz-i].conj())*point(+0.5,0),b1=(tb[i]-tb[fsz-i].conj())*point(0,-0.5);
		tl[i]=a0*b0+a0*b1*point(0,1);
		tr[i]=a1*b0+a1*b1*point(0,1);
	}
	FFT(tl,-1);
	FFT(tr,-1);
	for(int i=0;i<fsz;i++)
	{
		c[i]=(ll(tl[i].x+0.5)+
		    ((ll(tr[i].y+0.5)%mod)<<(FFTbit+FFTbit))+
	       (((ll(tl[i].y+0.5)+ll(tr[i].x+0.5))%mod)<<FFTbit))%mod;
	}
}
//---------------FTT head end---------------
#endif

//Basic operations
void dotmul(int a[],int an,int b[],int bn,int c[],int cn)
{
	for(int i=0;i<cn;i++)c[i]=1ll*(i<an?a[i]:0)*(i<bn?b[i]:0)%mod;
}
void dotmul(int a[],int b[],int c[],int sz){dotmul(a,sz,b,sz,c,sz);}

void polyadd(int a[],int an,int b[],int bn,int c[],int cn)
{
	for(int i=0;i<cn;i++)c[i]=((i<an?a[i]:0)+(i<bn?b[i]:0))%mod;
}
void polyadd(int a[],int b[],int c[],int sz){polyadd(a,sz,b,sz,c,sz);}

void polysub(int a[],int an,int b[],int bn,int c[],int cn)
{
	for(int i=0;i<cn;i++)c[i]=((i<an?a[i]:0)-(i<bn?b[i]:0)+mod)%mod;
}
void polysub(int a[],int b[],int c[],int sz){polysub(a,sz,b,sz,c,sz);}

void polyaddinv(int a[],int an,int b[],int bn)
{
	for(int i=0;i<bn;i++)b[i]=(mod-(i<an?a[i]:0))%mod;
}
void polyaddinv(int a[],int n,int b[]){polyaddinv(a,n,b,n);}
void polyaddinv(int a[],int n){polyaddinv(a,n,a,n);}

void polyclear(int a[],int n){for(int i=0;i<n;i++)a[i]=0;}
void polyclear(int a[],int l,int r){for(int i=l;i<r;i++)a[i]=0;}

void polyset(int a[],int an,int b[],int bn){for(int i=0;i<bn;i++)b[i]=i<an?a[i]:0;}

void polymulnum(int a[],int an,int b,int c[],int cn)
{
	for(int i=0;i<cn;i++)c[i]=1ll*(i<an?a[i]:0)*b%mod;
}
void polymulnum(int a[],int b,int c[],int n){polymulnum(a,n,b,c,n);}
void polymulnum(int a[],int b,int n){polymulnum(a,n,b,a,n);}

void polydrv(int a[],int an,int b[],int bn)
{
	for(int i=0;i<bn;i++)b[i]=1ll*(i+1<an?a[i+1]:0)*(i+1)%mod;
}
void polydrv(int a[],int n,int b[]){polydrv(a,n,b,n);}
void polydrv(int a[],int n){polydrv(a,n,a,n);}

void polyitg(int a[],int an,int b[],int bn)
{
	for(int i=bn-1;i>0;i--)b[i]=1ll*(i-1<an?a[i-1]:0)*inv[i]%mod;
	b[0]=0;
}
void polyitg(int a[],int n,int b[]){polyitg(a,n,b,n);}
void polyitg(int a[],int n){polyitg(a,n,a,n);}

//Calc the kth pow of a[0..an-1]  Store in b[0...bn-1]
//if an*k<=bn then O(bn log bn) else O(bn log bn log K)
void polyqpow(int a[],int an,int k,int b[],int bn=-1)
{
	if(bn==-1)bn=(an-1)*k+1;
	static int pow_ans[FFTmx],pow_x[FFTmx];
	copy(a,a+an,pow_x);
	pow_ans[0]=1;
	int ansn=1;
	while(k>0)
	{
		if(k&1)
		{
			polymul(pow_ans,ansn,pow_x,an,pow_ans);
			ansn=min(ansn+an,bn);
		}
		polymul(pow_x,an,pow_x,an,pow_x);
		an=min(an+an,bn);
		k>>=1;
	}
	for(int i=0;i<bn;i++)b[i]=i<ansn?pow_ans[i]:0;
}

//Inverse
void polyinv_s(int a[],int n,int b[])
{
	static int inv_a[FFTmx],inv_b[FFTmx];
	assert(a!=b);
	if(n==1)
	{
		assert(a[0]!=0);
		b[0]=qpow(a[0],mod-2);
		return;
	}
	int nn=n>>1;
	polyinv_s(a,nn,b);
#ifdef useNTT
	FFTinit(n+n);
	polyset(b,nn,inv_a,fsz);
	FFT(inv_a,1);
	polyset(a,n,inv_b,fsz);
	FFT(inv_b,1);
	for(int i=0;i<fsz;i++)inv_a[i]=1ll*(2ll-1ll*inv_a[i]*inv_b[i]%mod+mod)*inv_a[i]%mod;
	FFT(inv_a,-1);
	polyset(inv_a,fsz,b,n);
#else
	polymul(b,nn,a,n,inv_a,n);
	polyaddinv(inv_a,n);
	inv_a[0]=(inv_a[0]+2)%mod;
	polymul(b,nn,inv_a,n,b,n);
#endif
}
//Calculate the inverse of a[0...n-1]  a[0] SHOULDN'T BE 0   fsz>=2n
//O(n log n)
void polyinv(int a[],int an,int b[],int bn)
{
	static int inv_ta[FFTmx],inv_tb[FFTmx];
	int sz=uptopow(bn);
	polyset(a,an,inv_ta,sz);
	polyinv_s(inv_ta,sz,inv_tb);
	polyset(inv_tb,sz,b,bn);
}
void polyinv(int a[],int n,int b[]){polyinv(a,n,b,n);}
void polyinv(int a[],int n){polyinv(a,n,a,n);}

//Divide  need: Inverse
//Calc C(x)  A(x)=B(x)*C(x)+r(x)  B(x) SOULDNT'T be 0  fsz>=2(an-bn)  Store in c[0...an-bn]  return max(0,an-bn+1)
//n=an-bn  O(an+bn+nlogn)
int polydiv(int a[],int an,int b[],int bn,int c[])
{
	static int div_a[FFTmx],div_b[FFTmx];
	int cn=an-bn+1;
	if(cn<=0)return 0;
	for(int i=0;i<bn;i++)div_b[i]=b[bn-i-1];
	polyinv(div_b,bn,div_a,cn);
	for(int i=0;i<an;i++)div_b[i]=a[an-i-1];
	polymul(div_b,cn,div_a,cn,c,cn);
	for(int i=0;i<cn-i;i++)swap(c[i],c[cn-i-1]);
	return cn;
}

//Modulo  need: Divide
//Calc r(x)  A(x)=B(x)*C(x)+r(x)  B(x) SOULDNT'T be 0  fsz>=2max(an,bn)  Store in c[0...bn-2]  return bn-1
//n=max(an-bn,bn)  O(n log n)
int polymod(int a[],int an,int b[],int bn,int c[])
{
	static int mod_a[FFTmx];
	assert(bn>0);
	int rn=bn-1;
	int cn=polydiv(a,an,b,bn,mod_a);
	polymul(mod_a,cn,b,bn,mod_a,rn);
	polysub(a,mod_a,c,rn);
	return rn;
}

//Ln  need: Inverse
//Calc ln(A(x))  a[0] SHOULD be 1   store in b[0...bn-1]
//n=bn  O(n log n)
void polyln(int a[],int an,int b[],int bn)
{
	static int ln_a[FFTmx],ln_b[FFTmx];
	assert((a[0]%mod+mod)%mod==1);
	polydrv(a,an,ln_a,bn);
	polyinv(a,an,ln_b,bn);
	polymul(ln_a,bn,ln_b,bn,b,bn);
	polyitg(b,bn);
}
void polyln(int a[],int n,int b[]){polyln(a,n,b,n);}
void polyln(int a[],int n){polyln(a,n,a,n);}

//Exp  need: Ln
void polyexp_s(int a[],int n,int b[])
{
	static int ex_a[FFTmx];
	assert(a!=b);
	if(n==1)
	{
		assert(a[0]==0);
		b[0]=1;
		return;
	}
	int nn=n>>1;
	polyexp_s(a,nn,b);
	polyln(b,nn,ex_a,n);
	polyaddinv(ex_a,n);
	polyadd(ex_a,a,ex_a,n);
	ex_a[0]=(ex_a[0]+1)%mod;
	polymul(ex_a,n,b,nn,b,n);
}
//Calc exp(A(x))  A[0] SHOULD be 0  fsz>=2n
//O(n log n)
void polyexp(int a[],int an,int b[],int bn)
{
	static int exp_ta[FFTmx],exp_tb[FFTmx];
	int sz=uptopow(bn);
	polyset(a,an,exp_ta,sz);
	polyexp_s(exp_ta,sz,exp_tb);
	polyset(exp_tb,sz,b,bn);
}
void polyexp(int a[],int n,int b[]){polyexp(a,n,b,n);}
void polyexp(int a[],int n){polyexp(a,n,a,n);}

//Pow   need: Exp
//Calc the kth power of A(x)  Store in c[0...cn-1]
//O(n log n)
void polypow(int a[],int n,ll K,int c[],int cn)
{
	if(K==0)
	{
		for(int i=0;i<cn;i++)c[i]=0;c[0]=1;
		return;
	}
	n=min(n,cn);
	int t=0;
	while(t<n&&a[t]%mod==0)t++;
	if(1.0*t*K>10*cn||1ll*t*K>=cn)
	{
		for(int i=0;i<cn;i++)c[i]=0;
		return;
	}
	static int pow_a[FFTmx];
	polyset(a+t,n-t,pow_a,cn-t);
	int sz=cn-t;
	ll coef=pow_a[0];
	polymulnum(pow_a,sz,qpow(coef,mod-2),pow_a,sz);
	polyln(pow_a,sz);
	polymulnum(pow_a,sz,K%mod,pow_a,sz);
	polyexp(pow_a,sz);
	polymulnum(pow_a,sz,qpow(coef,K),pow_a,sz);
	ll cnt0=t*K;
	polyclear(c,cnt0);
	polyset(pow_a,sz,c+cnt0,cn-cnt0);
}

//Sqrt  need: Inverse
void polysqrt_s(int a[],int n,int b[])
{
	static int sqrt_a[FFTmx];
	assert(a!=b);
	if(n==1)
	{
		assert((a[0]%mod+mod)%mod==1);
		b[0]=1;
		return;
	}
	int nn=n>>1;
	polysqrt_s(a,nn,b);
	polyinv(b,nn,sqrt_a,n);
	polymul(sqrt_a,n,a,n,sqrt_a,n);
	polyadd(b,nn,sqrt_a,n,sqrt_a,n);
	polymulnum(sqrt_a,n,qpow(2,mod-2),b,n);
}
//Calc sqrt(A(x))  A[0] SHOULD be 1   fsz>=2n
//O(n log n)
void polysqrt(int a[],int an,int b[],int bn)
{
	static int sqrt_ta[FFTmx],sqrt_tb[FFTmx];
	int sz=uptopow(bn);
	polyset(a,an,sqrt_ta,sz);
	polysqrt_s(sqrt_ta,sz,sqrt_tb);
	polyset(sqrt_tb,sz,b,bn);
}
void polysqrt(int a[],int n,int b[]){polysqrt(a,n,b,n);}
void polysqrt(int a[],int n){polysqrt(a,n,a,n);}

//Evaluate  need: Modulo
int ev_tab[FFTbitn][FFTmx<<1];
int ev_ans[FFTbitn][FFTmx<<1];
void eval_prework(int lv,int a[],int l,int r)
{
	assert(lv<FFTbitn);
	if(l==r)
	{
		ev_tab[lv][l*2]=mod-a[l]%mod;
		ev_tab[lv][l*2+1]=1;
		return;
	}
	int m=l+r>>1;
	eval_prework(lv+1,a,l,m);
	eval_prework(lv+1,a,m+1,r);
	polymul(ev_tab[lv+1]+l*2,m-l+2,ev_tab[lv+1]+(m+1)*2,r-(m+1)+2,ev_tab[lv]+l*2,r-l+2);
}
void eval_solve(int lv,int a[],int an,int l,int r,int ans[])
{
	assert(lv<FFTbitn);
	int sz=polymod(a,an,ev_tab[lv]+l*2,r-l+2,ev_ans[lv]+l);
	if(l==r)
	{
		ans[l]=ev_ans[lv][l];
		return;
	}
	int m=l+r>>1;
	eval_solve(lv+1,ev_ans[lv]+l,sz,l,m,ans);
	eval_solve(lv+1,ev_ans[lv]+l,sz,m+1,r,ans);
}
//Evaluate A with size n at points b_i (0<=i<m) and store in c
void polyeval(int a[],int n,int b[],int m,int c[])
{
	eval_prework(0,b,0,m-1);
	eval_solve(0,a,n,0,m-1,c);
}

//Interpolate   need: Evaluate
int it_f[FFTmx],it_c[FFTmx];
int it_ta[FFTmx],it_tb[FFTmx];
void itpl_solve(int lv,int c[],int l,int r,int a[])
{
	if(l==r)
	{
		a[l]=1ll*qpow(it_c[l],mod-2)*c[l]%mod;
		return;
	}
	int m=l+r>>1;
	itpl_solve(lv+1,c,l,m,a);
	itpl_solve(lv+1,c,m+1,r,a);
	polymul(a+l,m+1-l,ev_tab[lv+1]+(m+1)*2,r-(m+1)+2,it_ta,r-l+1);
	polymul(a+m+1,r-m,ev_tab[lv+1]+l*2,m-l+2,it_tb,r-l+1);
	polyadd(it_ta,it_tb,a+l,r-l+1);
}
//Interpolate A with n points (b_i,c_i) (0<=i<n) and store in a
void polyitpl(int b[],int n,int c[],int a[])
{
	eval_prework(0,b,0,n-1);
	polydrv(ev_tab[0],n+1,it_f);
	eval_solve(0,it_f,n,0,n-1,it_c);
	itpl_solve(0,c,0,n-1,a);
}

vector<int> con[100111];
ll ANS;
int n,K;
int SZ[100111],SZ_pre[100111];
int getsz(int x,int to){return SZ_pre[to]==x?SZ[to]:n-SZ[x];}
void dfs_sz(int x,int pre=-1)
{
	SZ[x]=1;
	for(int i=0;i<con[x].size();i++)
	{
		int u=con[x][i];
		if(u==pre)continue;
		SZ_pre[u]=x;
		dfs_sz(u,x);
		SZ[x]+=SZ[u];
	}
}
int cur_lv,cur_rt;
int dlv[100111];
int sz[100111],an,arr[100111];
void pdfs(int x,int pre=-1)
{
	dlv[x]=cur_lv+1;
	sz[x]=1;
	arr[an++]=x;
	for(int i=0;i<con[x].size();i++)
	{
		int u=con[x][i];
		if(u==pre||dlv[u]<cur_lv)continue;
		pdfs(u,x);
		sz[x]+=sz[u];
	}
}
int findrt(int x)
{
	an=0;
	pdfs(x);
	int ret=x;
	for(int i=0;i<an;i++)if(sz[arr[i]]*2>=sz[x]&&sz[arr[i]]<sz[ret])ret=arr[i];
	return ret;
}
ll ans[100111],sans[100111];

void eval_prework2(int lv,int a[],int l,int r)
{
	assert(lv<FFTbitn);
	if(l==r)
	{
		ev_tab[lv][l*2]=1;
		ev_tab[lv][l*2+1]=a[l];
		return;
	}
	int m=l+r>>1;
	eval_prework2(lv+1,a,l,m);
	eval_prework2(lv+1,a,m+1,r);
	polymul(ev_tab[lv+1]+l*2,m-l+2,ev_tab[lv+1]+(m+1)*2,r-(m+1)+2,ev_tab[lv]+l*2,r-l+2);
}
int A[FFTmx],nA[FFTmx];
void mult(int sz,int c)
{
	for(int i=0;i<=sz;i++)nA[i]=0;
	for(int i=0;i<=sz;i++)
	{
		nA[i]=(nA[i]+A[i])%mod;
		nA[i+1]=(nA[i+1]+1ll*A[i]*c)%mod;
	}
	for(int i=0;i<=sz;i++)A[i]=nA[i];
}
void divi(int sz,int c)//div cx+1
{
	for(int i=0;i<=sz;i++)nA[i]=0;
	ll inv=qpow(c,mod-2);
	for(int i=sz;i>0;i--)
	{
		ll k=A[i]*inv%mod;
		nA[i-1]=k;
		A[i-1]=(A[i-1]-k+mod)%mod;
	}
	for(int i=0;i<=sz;i++)A[i]=nA[i];
}
ll calc_arr(int a[],int sz)
{
	ll ret=0;
	for(int i=0;i<=min(K,sz);i++)
	{
		ll coef=1ll*fac[K]*ifac[K-i]%mod;
		ret=(ret+coef*a[i])%mod;
	}
	return ret;
}
ll calc(vector<int> &v)
{
	ll ret=0;
	int sz=v.size();
	if(sz==0)return 1;
	static int calc_a[FFTmx];
	for(int i=0;i<sz;i++)calc_a[i]=v[i];
	eval_prework2(0,calc_a,0,sz-1);
	ret=calc_arr(ev_tab[0],min(sz,K));
/*	memset(A,0,sizeof(A));
	cerr<<"calc:"<<endl;
	for(int i=0;i<v.size();i++)cerr<<v[i]<<" ";cerr<<endl;
	A[0]=1;
	for(int i=0;i<sz;i++)mult(sz,v[i]);
	for(int i=0;i<=sz;i++)cerr<<A[i]<<" ";cerr<<endl;
	ret=calc_arr(A,sz);
	cerr<<"ret="<<ret<<endl;*/
	return ret;
}
ll dfs(int x,int pre)
{
	ll ret=0;
	for(int i=0;i<con[x].size();i++)
	{
		int u=con[x][i];
		if(u==pre||dlv[u]<cur_lv)continue;
		ret=(ret+dfs(u,x))%mod;
	}
	static vector<int> v;
	v.clear();
	for(int i=0;i<con[x].size();i++)
	{
		int u=con[x][i];
		if(u==pre)continue;
		v.PB(getsz(x,u));
	}
	ans[x]=calc(v);
	return (ret+ans[x])%mod;
}
map<int,int> mp;
void clear_ans()
{
	mp.clear();
}
int get_ans(int sz,int x)
{
	if(mp.find(x)!=mp.end())return mp[x];
	int &ret=mp[x];
	divi(sz,x);
	ret=calc_arr(A,sz);
	mult(sz,x);
	return ret;
}
void solve(int _x,int lv)
{
	cur_lv=lv;
	int rt=findrt(_x);
	dlv[rt]=lv;

//	cerr<<"solve:"<<rt<<" "<<lv<<endl;
//	for(int i=1;i<=n;i++)cerr<<dlv[i]<<" ";cerr<<endl;

	ll SUM=0;
	for(int i=0;i<con[rt].size();i++)
	{
		int u=con[rt][i];
		if(dlv[u]<lv)continue;
		sans[u]=dfs(u,rt);
		SUM=(SUM+sans[u])%mod;
	}
//	for(int i=1;i<=n;i++)cerr<<ans[i]<<" ";cerr<<endl;

	vector<int> v;
	for(int i=0;i<con[rt].size();i++)
	{
		int u=con[rt][i];
//		if(dlv[u]<lv)continue;
		v.PB(getsz(rt,u));
	}
	calc(v);
	int vsz=v.size();
//	cerr<<"v:"<<endl;
//	for(int i=0;i<vsz;i++)cerr<<v[i]<<" ";cerr<<endl;
	for(int i=0;i<=vsz;i++)A[i]=ev_tab[0][i];
//	cerr<<"A:"<<endl;
//	for(int i=0;i<=vsz;i++)cerr<<A[i]<<" ";cerr<<endl;

	clear_ans();
	for(int i=0;i<con[rt].size();i++)
	{
		int u=con[rt][i];
		if(dlv[u]<lv)continue;
		ll cur_ans=get_ans(vsz,getsz(rt,u));
//		cerr<<u<<":"<<cur_ans<<endl;
		ANS=(ANS+sans[u]*((SUM-sans[u])*qpow(2,mod-2)%mod+mod+cur_ans)%mod)%mod;
	}
//	cerr<<"ANS="<<ANS<<endl;

	for(int i=0;i<con[rt].size();i++)
	{
		int u=con[rt][i];
		if(dlv[u]<lv)continue;
		solve(u,lv+1);
	}
}
int main()
{
	FFTprecalc();
	comb_init();
	getii(n,K);
	if(K==1)
	{
		cout<<(1ll*n*(n-1)/2)%mod<<endl;
		return 0;
	}
	for(int i=1;i<n;i++)
	{
		int x,y;
		getii(x,y);
		con[x].PB(y);
		con[y].PB(x);
	}
	dfs_sz(1);
	solve(1,0);
	cout<<ANS<<endl;
	return 0;
}


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

typedef pair<int, int> pii;
typedef vector<int> poly;
typedef long long ll;
const int maxn = 100005, mod = 998244353;

inline int gi()
{
	char c = getchar();
	while (c < '0' || c > '9') c = getchar();
	int sum = 0;
	while ('0' <= c && c <= '9') sum = sum * 10 + c - 48, c = getchar();
	return sum;
}

#define eb emplace_back
#define fi first
#define se second

inline int add(int a, int b) {return a + b >= mod ? a + b - mod : a + b;}
inline int sub(int a, int b) {return a >= b ? a - b : a - b + mod;}
inline int fpow(int x, int k)
{
	int res = 1;
	while (k) {
		if (k & 1) res = (ll)res * x % mod;
		k >>= 1; x = (ll)x * x % mod;
	}
	return res;
}

int n, k, ans, s1, s2, fac[maxn], ifac[maxn];

struct edge
{
	int to, next;
} e[maxn * 2];
int h[maxn], siz[maxn], tot;
int f[maxn], fs[maxn];
vector<pii> vec;
poly _F[maxn], _G[maxn];
int N, L, R[maxn << 2], w[maxn << 2], F[maxn << 2], Fl[maxn << 2], Fr[maxn << 2], G[maxn << 2], Gl[maxn << 2], Gr[maxn << 2];

inline void adde(int u, int v)
{
	e[++tot] = (edge) {v, h[u]}; h[u] = tot;
	e[++tot] = (edge) {u, h[v]}; h[v] = tot;
}

void init(int n)
{
	for (N = 1, L = -1; N <= n; N <<= 1) ++L;
	for (int i = 0; i < N; ++i) R[i] = (R[i >> 1] >> 1) | ((i & 1) << L);
	w[N >> 1] = 1;
	int wn = fpow(3, (mod - 1) / N);
	for (int i = (N >> 1) + 1; i < N; ++i) w[i] = (ll)w[i - 1] * wn % mod;
	for (int i = (N >> 1) - 1; i; --i) w[i] = w[i << 1];
}

void dft(int *a)
{
	for (int i = 0; i < N; ++i) if (i < R[i]) swap(a[i], a[R[i]]);

	for (int d = 1; d < N; d <<= 1)
		for (int i = 0; i < N; i += d << 1)
			for (int j = 0; j < d; ++j) {
				int t = (ll)w[d + j] * a[i + d + j] % mod;
				a[i + d + j] = sub(a[i + j], t);
				a[i + j] = add(a[i + j], t);
			}
}

void idft(int *a)
{
	dft(a);
	reverse(a + 1, a + N);
	int inv = fpow(N, mod - 2);
	for (int i = 0; i < N; ++i) a[i] = (ll)a[i] * inv % mod;
}

void solve(int l, int r, int u)
{
	if (l == r) {
		poly &F = _F[l], &G = _G[l];
		F.resize(2); G.resize(2);
		F[0] = 1; F[1] = vec[l].se;
		G[0] = add(f[vec[l].fi], fs[vec[l].fi]); G[1] = (ll)add(f[vec[l].fi], fs[vec[l].fi]) * (n - siz[u]) % mod;
		return ;
	}
	int mid = (l + r) >> 1, l1 = mid - l + 1, l2 = r - mid;

	solve(l, mid, u);
	solve(mid + 1, r, u);

	init(r - l + 1);
	for (int i = 0; i <= l1; ++i) Fl[i] = _F[l][i], Gl[i] = _G[l][i];
	memset(Fl + l1 + 1, 0, sizeof(int) * (N - l1));
	memset(Gl + l1 + 1, 0, sizeof(int) * (N - l1));
	for (int i = 0; i <= l2; ++i) Fr[i] = _F[mid + 1][i], Gr[i] = _G[mid + 1][i];
	memset(Fr + l2 + 1, 0, sizeof(int) * (N - l2));
	memset(Gr + l2 + 1, 0, sizeof(int) * (N - l2));
	dft(Fl); dft(Gl); dft(Fr); dft(Gr);
	for (int i = 0; i < N; ++i) F[i] = (ll)Fl[i] * Fr[i] % mod;
	for (int i = 0; i < N; ++i) G[i] = ((ll)Fl[i] * Gr[i] + (ll)Fr[i] * Gl[i]) % mod;
	idft(F); idft(G);
	_F[l].resize(r - l + 2); _G[l].resize(r - l + 2);
	for (int i = 0; i <= r - l + 1; ++i) _F[l][i] = F[i], _G[l][i] = G[i];
}

void dfs(int u, int fa)
{
	siz[u] = 1;
	for (int i = h[u], v; v = e[i].to, i; i = e[i].next) if (v != fa) dfs(v, u);
	vec.clear();
	for (int i = h[u], v; v = e[i].to, i; i = e[i].next)
		if (v != fa) {
			fs[u] = add(fs[u], add(f[v], fs[v])); siz[u] += siz[v];
			vec.eb(v, siz[v]);
		}

	if (vec.empty()) return f[u] = 1, s1 = add(s1, f[u]), s2 = add(s2, f[u]), void();
	solve(0, vec.size() - 1, u);
	poly &F = _F[0], &G = _G[0];

	int s = F.size() - 1;
	for (int i = 0; i <= s; ++i) f[u] = (f[u] + (ll)fac[k] * ifac[k - i] % mod * F[i]) % mod;
	s1 = add(s1, f[u]); s2 = (s2 + (ll)f[u] * f[u]) % mod;
	for (int i = 0; i <= s; ++i) ans = (ans + (ll)fac[k] * ifac[k - i] % mod * G[i]) % mod;
	ans = (ans + (ll)(mod - f[u]) * fs[u]) % mod;
}

int main()
{
	n = gi(); k = gi();
	if (k == 1) return printf("%lld\n", (ll)n * (n - 1) / 2 % mod), 0;
	fac[0] = 1;
	for (int i = 1; i <= k; ++i) fac[i] = (ll)fac[i - 1] * i % mod;
	ifac[k] = fpow(fac[k], mod - 2);
	for (int i = k - 1; ~i; --i) ifac[i] = (ll)ifac[i + 1] * (i + 1) % mod;
	for (int i = 1; i < n; ++i) adde(gi(), gi());

	dfs(1, 0);

	printf("%d\n", add(ans, (ll)sub((ll)s1 * s1 % mod, s2) * (mod + 1) / 2 % mod));

	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define rg register
using namespace std;
const int MAXN=53e4+10;
const int Mod=998244353;
struct gao{   int u,v,Next;   }Edge[MAXN<<1];
int n,K,Ls,Ans,Es,First[MAXN],Help[MAXN],Dp[MAXN],Inv[MAXN];
int F1[MAXN],St[MAXN],Sons[MAXN],Tot[MAXN],Fac[MAXN]={1},Invf[MAXN];
vector<int>Son[MAXN];
inline int Read()
{   rg int a=0,c=1;   rg char b=getchar();
	while(b!='-'&&(b<'0'||b>'9'))b=getchar();
	if(b=='-')c=-1,b=getchar();
	while(b>='0'&&b<='9')a=a*10+b-48,b=getchar();
	return a*c;
}
inline int Fast(rg int Di,rg int Mi)
{   rg int Back=1;
	for(;Mi>=1;Mi>>=1,Di=1ll*Di*Di%Mod)
		if(Mi&1) Back=1ll*Back*Di%Mod;
	return Back;
}
inline int Max(rg int A,rg int B){   return A>B?A:B;   }
inline int cmp(rg int A,rg int B){   return Tot[A]<Tot[B];   }
inline int Add(rg int A,rg int B){   return A+=B,A-=A>=Mod?Mod:0,A;   }
inline int C(rg int A,rg int B){   return A<B?0:1ll*Fac[A]*Invf[B]%Mod*Invf[A-B]%Mod;   }
inline void Link(rg int u,rg int v){   Edge[++Es]=(gao){u,v,First[u]},First[u]=Es;   }
namespace Poly
{   int Rader[MAXN],A[MAXN],B[MAXN],W[MAXN],Len,Ms,Invl;
	int H[20][MAXN];
	inline void NTT(int *P,rg int opt)
	{   for(rg int i=0;i<Len;i++)
			if(i<Rader[i]) swap(P[i],P[Rader[i]]);
		for(rg int i=1;i<Len;i<<=1)
		{   rg int Euler=Fast(3,(Mod-1)/(i<<1));
			if(opt<0) Euler=Fast(Euler,Mod-2);
			for(rg int k=0,Wi=1;k<i;k++,Wi=1ll*Wi*Euler%Mod) W[k]=Wi;
			for(rg int Pos=i<<1,j=0;j<Len;j+=Pos)
				for(rg int k=0,X,Y;k<i;k++)
					X=P[j+k],Y=1ll*W[k]*P[i+j+k]%Mod,P[j+k]=Add(X,Y),P[i+j+k]=Add(X,Mod-Y);
		}
		if(opt>0) return ;   Invl=Fast(Len,Mod-2);
		for(rg int i=0;i<Len;i++) P[i]=1ll*P[i]*Invl%Mod;
	}
	inline void Prepare(rg int Lx)
	{   Ms=-1;
		for(Len=1;Len<Lx;Len<<=1) Ms++;
		for(rg int i=0;i<Len;i++) Rader[i]=(Rader[i>>1]>>1)|((i&1)<<Ms);
	}
	inline void Get_Mul(int *X,int *Y,int *Z,rg int Lx)
	{   Prepare(Lx<<1);
		for(rg int i=0;i<Lx;i++) A[i]=X[i],B[i]=Y[i];
		for(rg int i=Lx;i<Len;i++) A[i]=B[i]=0;
		NTT(A,1),NTT(B,1);
		for(rg int i=0;i<Len;i++) A[i]=1ll*A[i]*B[i]%Mod;
		NTT(A,-1);
		for(rg int i=0;i<Len;i++) Z[i]=A[i];
	}
	inline int Get_Div(rg int D,rg int Le,rg int Ri)
	{   if(Le==Ri) return H[D][0]=1,H[D][1]=Help[Le],1;
		rg int Mid=(Le+Ri)>>1,Ll=Get_Div(D+1,Le,Mid),Rl=0;
		for(rg int i=0;i<=Ll;i++) H[D][i]=H[D+1][i],H[D+1][i]=0;
		Rl=Get_Div(D+1,Mid+1,Ri),Get_Mul(H[D],H[D+1],H[D],Max(Ll,Rl)+1);
		return Ll+Rl;
	}
	inline void Multiply(int *X,int *Y,rg int Tot,rg int Lx)
	{   X[Lx]=0,A[0]=X[0];
		for(rg int i=1;i<=Lx;i++) A[i]=(X[i]+1ll*Tot*X[i-1])%Mod;
		for(rg int i=0;i<=Lx;i++) Y[i]=A[i];
	}
	inline void Divide(int *X,int *Y,rg int Tot,rg int Lx)
	{   for(rg int i=0;i<Lx;i++) A[i]=X[i];
		for(rg int i=Lx-2;i>=0;i--) Y[i]=1ll*A[i+1]*Inv[Tot]%Mod,A[i]=(A[i]+Mod-Y[i])%Mod;
	}
}using Poly::Divide;using Poly::Multiply;using Poly::Get_Div;using Poly::Get_Mul;using Poly::H;
inline int Calc(rg int Now,rg int Tv)
{   rg int Back=0;
	for(rg int i=0,j=St[Now];i<=Sons[Now];i++,j++) Help[i]=F1[j];
	Divide(Help,Help,Tv,Sons[Now]+1),Multiply(Help,Help,n-Tot[Now],Sons[Now]);
	for(rg int i=0;i<=Sons[Now];i++) Back=(Back+1ll*Help[i]*C(K,i)%Mod*Fac[i])%Mod;
	return Back;
}
inline void Dfs1(rg int Now,rg int Ba)
{   for(rg int i=First[Now],v,j=1;i!=-1;i=Edge[i].Next)
		if((v=Edge[i].v)!=Ba)   Dfs1(v,Now),Sons[Now]++,Tot[Now]+=Tot[v];
	for(rg int i=First[Now],j=1;i!=-1;i=Edge[i].Next)
		if(Edge[i].v!=Ba) Help[j++]=Tot[Edge[i].v];
	Tot[Now]++,St[Now]=Ls+1,Sons[Now]?Get_Div(1,1,Sons[Now]):H[1][0]=1;
	for(rg int i=0;i<=Sons[Now];i++) F1[++Ls]=H[1][i];
}
inline void Dfs2(rg int Now,rg int Ba)
{   Help[Now]=0;
	for(rg int i=First[Now],v;i!=-1;i=Edge[i].Next)
		if((v=Edge[i].v)!=Ba) Dfs2(v,Now),Help[Now]=Add(Help[Now],Help[v]),Son[Now].push_back(v);
	for(rg int i=First[Now],v;i!=-1;i=Edge[i].Next)
		if((v=Edge[i].v)!=Ba) Ans=(Ans+1ll*Help[v]*(Help[Now]-Help[v]))%Mod;
	Help[Now]=Add(Help[Now],Dp[Now]);
}
inline void Dfs3(rg int Now,rg int Ba,rg int Sum)
{   sort(Son[Now].begin(),Son[Now].end(),cmp),Ans=(Ans+1ll*Sum*Dp[Now])%Mod;
	for(rg int i=0,Endi=Son[Now].size(),Ns;i<Endi;i++)
		Ns=!i||Tot[Son[Now][i]]!=Tot[Son[Now][i-1]]?Calc(Now,Tot[Son[Now][i]]):Ns,Dfs3(Son[Now][i],Now,Add(Sum,Ns));
}
int main()
{   n=Read(),K=Read();
	memset(First,-1,sizeof(First));
	if(K==1) return printf("%lld\n",1ll*n*(n-1)/2%Mod),0;
	for(rg int i=1,u,v;i<n;i++) u=Read(),v=Read(),Link(u,v),Link(v,u);
	for(rg int i=0;i<=n;i++) Inv[i]=Fast(i,Mod-2);
	for(rg int i=1;i<=K;i++) Fac[i]=1ll*Fac[i-1]*i%Mod;
	Dfs1(1,1),Invf[K]=Fast(Fac[K],Mod-2);
	for(rg int i=K-1;i>=0;i--) Invf[i]=1ll*Invf[i+1]*(i+1)%Mod;
	for(rg int i=1;i<=n;i++)
		for(rg int j=0;j<=Sons[i];j++) Dp[i]=(Dp[i]+1ll*F1[St[i]+j]*C(K,j)%Mod*Fac[j])%Mod;
	Dfs2(1,1),Ans=1ll*Ans*Fast(2,Mod-2)%Mod,Dfs3(1,1,0),printf("%d\n",Add(Ans,Mod));
}


#include<bits/stdc++.h>
#define IL inline
#define _ 262144
#define ll long long
using namespace std ;

IL int gi(){
    int data = 0 , m = 1; char ch = 0;
    while(ch!='-' && (ch<'0'||ch>'9')) ch = getchar();
    if(ch == '-'){m = 0 ; ch = getchar() ; }
    while(ch >= '0' && ch <= '9'){data = (data<<1) + (data<<3) + (ch^48) ; ch = getchar(); }
    return (m) ? data : -data ;
}

#define mod 998244353
#define pr 3

int Fac[_],IFac[_],inv[_],rev[_],f1[_],f2[_],wn[30],sz[_],f[_],g[_],h[_],Ans ;
vector<int> poly[_ << 1] , vec[_] , son[_] ;
int n , m , nn , K ;
struct _Edge{int to , next ; } Edge[_ << 1] ; int head[_] , CNT ; int pson[_],coef[_] ;
IL void AddEdge(int u , int v) {
	Edge[++ CNT] = (_Edge){v , head[u]} ; head[u] = CNT ; return ;
}

IL int Pow(int ts , int js) {
	int al = 1 ;
	while(js) {
		if(js & 1) al = 1ll * al * ts % mod ;
		ts = 1ll * ts * ts % mod ; js >>= 1 ;
	}return al ;
}
IL void Numb(int N) {
	for(int i = 0; i <= 25; i ++) wn[i] = Pow(pr , (mod - 1) / (1 << i)) ;
	Fac[0] = Fac[1] = IFac[0] = IFac[1] = inv[0] = inv[1] = 1 ;
	for(int i = 2; i <= N; i ++) {
		Fac[i] = 1ll * i * Fac[i - 1] % mod ;
		inv[i] = 1ll * inv[mod % i] * (mod - mod / i) % mod ;
		IFac[i] = 1ll * inv[i] * IFac[i - 1] % mod ;
	}
	return ;
}
IL int Comb(int N , int M) {if(N < M) return 0 ; return 1ll * Fac[N] * IFac[M] % mod * IFac[N - M] % mod ; }

IL void NTT(int *P , int op) {
	for(int i = 0; i < nn; i ++) if(rev[i] > i) swap(P[i] , P[rev[i]]) ;
	for(int i = 1,id = 0; i < nn; i <<= 1) {
		++ id ;
		for(int j = 0,dt = (i << 1) ; j < nn; j += dt) {
			int w = 1 ;
			for(int k = 0; k < i; k ++, w = 1ll * w * wn[id] % mod) {
				int X = P[j + k] , Y = 1ll * w * P[j + k + i] % mod ;
				P[j + k] = (X + Y) % mod ;
				P[j + k + i] = (X - Y + mod) % mod ;
			}
		}
	}if(op < 0) {
		for(int j = 1; j < nn / 2; j ++) swap(P[j] , P[nn - j]) ;
		int INV = Pow(nn , mod - 2) ;
		for(int j = 0; j < nn; j ++) P[j] = 1ll * INV * P[j] % mod ;
	}
}
int tmp[_] ;
void dfs(int o , int l , int r) {
	/*
	poly[o].clear() ;
	if(l > r) {poly[o].push_back(1) ; return ; }
	if(l == r) {poly[o].push_back(1) , poly[o].push_back(coef[l]) ; return ; }
	int mid = (l + r) >> 1 ;
	dfs(o << 1 , l , mid) ; dfs(o << 1 | 1 , mid + 1 , r) ;
	int l1 = poly[o << 1].size() - 1 , l2 = poly[o << 1 | 1].size() - 1 ;
	int nl = 0 ;
	for(nn = 1; nn <= l1 + l2; nn <<= 1) ++ nl ;
	for(int i = 0; i < nn; i ++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (nl - 1)) ;
	for(int i = 0; i <= l1; i ++) f1[i] = poly[o << 1][i] ;
	for(int i = 0; i <= l2; i ++) f2[i] = poly[o << 1 | 1][i] ;
	NTT(f1 , 1) ; NTT(f2 , 1) ;
	for(int i = 0; i < nn; i ++) f1[i] = 1ll * f1[i] * f2[i] % mod ;
	NTT(f1 , -1) ;
	for(int i = 0; i <= l1 + l2; i ++) poly[o].push_back(f1[i]) ;
	for(int i = 0; i < nn; i ++) f1[i] = f2[i] = 0 ;
	*/
	memset(tmp , 0 , sizeof(tmp)) ; tmp[0] = 1 ;
	poly[1].clear() ;
	for(int i = 1,len = 0; i <= r; i ++, len ++)
		for(int j = len + 1; j >= 1; j --) tmp[j] = (1ll * coef[i] * tmp[j - 1] % mod + tmp[j]) % mod ;
	for(int j = 0; j <= r - l + 1; j ++) poly[1].push_back(tmp[j]) ; return ;
}

void Dfs(int u , int From) {
	sz[u] = 1 ; int sum = 0 ;
	for(int e = head[u] ; e ; e = Edge[e].next) {
		int v = Edge[e].to ; if(v == From) continue ; Dfs(v , u) ;
		sz[u] += sz[v] ; pson[u] ++ ;
		Ans = (Ans + 1ll * f[v] * sum % mod) % mod ;
		f[u] = (f[u] + f[v]) % mod ; sum = (sum + f[v]) % mod ;
	}
	int tot = 0 ;
	for(int e = head[u] ; e ; e = Edge[e].next) {
		int v = Edge[e].to ; if(v == From) continue ;
		coef[++ tot] = sz[v] ;
	}
	dfs(1 , 1 , tot) ;
	for(int i = 0; i <= tot; i ++) vec[u].push_back(poly[1][i]) ;
	sum = 0 ;
	for(int i = 0; i <= tot; i ++) sum = (sum + 1ll * vec[u][i] * Fac[i] % mod * Comb(K , i) % mod) % mod ;
	h[u] = sum ;
	f[u] = (f[u] + sum) % mod ;
}

IL int Calc(int u , int cof) {
	for(int i = 0; i <= pson[u]; i ++) g[i] = vec[u][i] ;
	for(int i = 1; i <= pson[u]; i ++) g[i] = (g[i] - 1ll * cof * g[i - 1] % mod + mod) % mod ;

    int sum = 0 ;
	for(int i = 0; i < pson[u] ; i ++) sum = (sum + 1ll * g[i] * Fac[i] % mod * Comb(K , i) % mod) % mod ;
	return sum ;
}
IL bool cmp(int i , int j) {return sz[i] < sz[j] ; }
void Dfs2(int u , int From , int val_fa) {
	Ans = (Ans + 1ll * h[u] * val_fa % mod) % mod ;
	for(int e = head[u] ; e ; e = Edge[e].next) if(Edge[e].to != From) son[u].push_back(Edge[e].to) ;
	sort(son[u].begin() , son[u].end() , cmp) ;
	if(From) {
		vec[u].resize(pson[u] + 1) ;
		++ pson[u] ;
		for(int j = pson[u] + 1; j >= 1; j --) vec[u][j] = (1ll * vec[u][j - 1] * (n - sz[u]) % mod + vec[u][j]) % mod ;
	}
	int Coef = 0 ;
	for(int j = 0,lt = son[u].size(); j < lt; j ++) {
		if(!j || sz[son[u][j]] != sz[son[u][j - 1]]) Coef = Calc(u , sz[son[u][j]]) ;
		int v = son[u][j] ;
		Dfs2(v , u , (val_fa + Coef) % mod) ;
	}
	return ;
}

int main() {
	n = gi() ; K = gi() ;
	/*
	if(K == 1) {
		cout << (1ll * n * (n - 1) / 2) % mod << endl ;
		return 0 ;
	}
	for(int i = 1,u,v; i < n; i ++) u = gi() , v = gi() , AddEdge(u , v) , AddEdge(v , u) ;
	Numb(n + K) ;
	Dfs(1 , 0) ;
	Dfs2(1 , 0 , 0) ;*/ cout << Ans << endl ;
	return 0 ;
}


#include<bits/stdc++.h>
#define IL inline
#define _ 262144
#define ll long long
using namespace std ;

IL int gi(){
    int data = 0 , m = 1; char ch = 0;
    while(ch!='-' && (ch<'0'||ch>'9')) ch = getchar();
    if(ch == '-'){m = 0 ; ch = getchar() ; }
    while(ch >= '0' && ch <= '9'){data = (data<<1) + (data<<3) + (ch^48) ; ch = getchar(); }
    return (m) ? data : -data ;
}

#define mod 998244353
#define pr 3

int Fac[_],IFac[_],inv[_],rev[_],f1[_],f2[_],wn[30],sz[_],f[_],g[_],h[_],Ans ;
vector<int> poly[_ << 1] , vec[_] , son[_] ;
int n , m , nn , K ;
struct _Edge{int to , next ; } Edge[_ << 1] ; int head[_] , CNT ; int pson[_],coef[_] ;
IL void AddEdge(int u , int v) {
	Edge[++ CNT] = (_Edge){v , head[u]} ; head[u] = CNT ; return ;
}

IL int Pow(int ts , int js) {
	int al = 1 ;
	while(js) {
		if(js & 1) al = 1ll * al * ts % mod ;
		ts = 1ll * ts * ts % mod ; js >>= 1 ;
	}return al ;
}
IL void Numb(int N) {
	for(int i = 0; i <= 25; i ++) wn[i] = Pow(pr , (mod - 1) / (1 << i)) ;
	Fac[0] = Fac[1] = IFac[0] = IFac[1] = inv[0] = inv[1] = 1 ;
	for(int i = 2; i <= N; i ++) {
		Fac[i] = 1ll * i * Fac[i - 1] % mod ;
		inv[i] = 1ll * inv[mod % i] * (mod - mod / i) % mod ;
		IFac[i] = 1ll * inv[i] * IFac[i - 1] % mod ;
	}
	return ;
}
IL int Comb(int N , int M) {if(N < M) return 0 ; return 1ll * Fac[N] * IFac[M] % mod * IFac[N - M] % mod ; }

IL void NTT(int *P , int op) {
	for(int i = 0; i < nn; i ++) if(rev[i] > i) swap(P[i] , P[rev[i]]) ;
	for(int i = 1,id = 0; i < nn; i <<= 1) {
		++ id ;
		for(int j = 0,dt = (i << 1) ; j < nn; j += dt) {
			int w = 1 ;
			for(int k = 0; k < i; k ++, w = 1ll * w * wn[id] % mod) {
				int X = P[j + k] , Y = 1ll * w * P[j + k + i] % mod ;
				P[j + k] = (X + Y) % mod ;
				P[j + k + i] = (X - Y + mod) % mod ;
			}
		}
	}if(op < 0) {
		for(int j = 1; j < nn / 2; j ++) swap(P[j] , P[nn - j]) ;
		int INV = Pow(nn , mod - 2) ;
		for(int j = 0; j < nn; j ++) P[j] = 1ll * INV * P[j] % mod ;
	}
}
int tmp[_] ;
void dfs(int o , int l , int r) {
	/*
	poly[o].clear() ;
	if(l > r) {poly[o].push_back(1) ; return ; }
	if(l == r) {poly[o].push_back(1) , poly[o].push_back(coef[l]) ; return ; }
	int mid = (l + r) >> 1 ;
	dfs(o << 1 , l , mid) ; dfs(o << 1 | 1 , mid + 1 , r) ;
	int l1 = poly[o << 1].size() - 1 , l2 = poly[o << 1 | 1].size() - 1 ;
	int nl = 0 ;
	for(nn = 1; nn <= l1 + l2; nn <<= 1) ++ nl ;
	for(int i = 0; i < nn; i ++) rev[i] = (rev[i >> 1] >> 1) | ((i & 1) << (nl - 1)) ;
	for(int i = 0; i <= l1; i ++) f1[i] = poly[o << 1][i] ;
	for(int i = 0; i <= l2; i ++) f2[i] = poly[o << 1 | 1][i] ;
	NTT(f1 , 1) ; NTT(f2 , 1) ;
	for(int i = 0; i < nn; i ++) f1[i] = 1ll * f1[i] * f2[i] % mod ;
	NTT(f1 , -1) ;
	for(int i = 0; i <= l1 + l2; i ++) poly[o].push_back(f1[i]) ;
	for(int i = 0; i < nn; i ++) f1[i] = f2[i] = 0 ;
	*/
	memset(tmp , 0 , sizeof(tmp)) ; tmp[0] = 1 ;
	poly[1].clear() ;
	for(int i = 1,len = 0; i <= r; i ++, len ++)
		for(int j = len + 1; j >= 1; j --) tmp[j] = (1ll * coef[i] * tmp[j - 1] % mod + tmp[j]) % mod ;
	for(int j = 0; j <= r - l + 1; j ++) poly[1].push_back(tmp[j]) ; return ;
}

void Dfs(int u , int From) {
	sz[u] = 1 ; int sum = 0 ;
	for(int e = head[u] ; e ; e = Edge[e].next) {
		int v = Edge[e].to ; if(v == From) continue ; Dfs(v , u) ;
		sz[u] += sz[v] ; pson[u] ++ ;
		Ans = (Ans + 1ll * f[v] * sum % mod) % mod ;
		f[u] = (f[u] + f[v]) % mod ; sum = (sum + f[v]) % mod ;
	}
	int tot = 0 ;
	for(int e = head[u] ; e ; e = Edge[e].next) {
		int v = Edge[e].to ; if(v == From) continue ;
		coef[++ tot] = sz[v] ;
	}
	dfs(1 , 1 , tot) ;
	for(int i = 0; i <= tot; i ++) vec[u].push_back(poly[1][i]) ;
	sum = 0 ;
	for(int i = 0; i <= tot; i ++) sum = (sum + 1ll * vec[u][i] * Fac[i] % mod * Comb(K , i) % mod) % mod ;
	h[u] = sum ;
	f[u] = (f[u] + sum) % mod ;
}

IL int Calc(int u , int cof) {
	for(int i = 0; i <= pson[u]; i ++) g[i] = vec[u][i] ;
	for(int i = 1; i <= pson[u]; i ++) g[i] = (g[i] - 1ll * cof * g[i - 1] % mod + mod) % mod ;

    int sum = 0 ;
	for(int i = 0; i < pson[u] ; i ++) sum = (sum + 1ll * g[i] * Fac[i] % mod * Comb(K , i) % mod) % mod ;
	return sum ;
}
IL bool cmp(int i , int j) {return sz[i] < sz[j] ; }
void Dfs2(int u , int From , int val_fa) {
	Ans = (Ans + 1ll * h[u] * val_fa % mod) % mod ;
	for(int e = head[u] ; e ; e = Edge[e].next) if(Edge[e].to != From) son[u].push_back(Edge[e].to) ;
	sort(son[u].begin() , son[u].end() , cmp) ;
	if(From) {
		vec[u].resize(pson[u] + 1) ;
		++ pson[u] ;
		for(int j = pson[u] + 1; j >= 1; j --) vec[u][j] = (1ll * vec[u][j - 1] * (n - sz[u]) % mod + vec[u][j]) % mod ;
	}
	int Coef = 0 ;
	for(int j = 0,lt = son[u].size(); j < lt; j ++) {
		if(!j || sz[son[u][j]] != sz[son[u][j - 1]]) Coef = Calc(u , sz[son[u][j]]) ;
		int v = son[u][j] ;
		Dfs2(v , u , (val_fa + Coef) % mod) ;
	}
	return ;
}

int main() {
	n = gi() ; K = gi() ;
	if(K == 1) {
		cout << (1ll * n * (n - 1) / 2) % mod << endl ;
		return 0 ;
	}
	for(int i = 1,u,v; i < n; i ++) u = gi() , v = gi() , AddEdge(u , v) , AddEdge(v , u) ;
	Numb(n + K) ;
	Dfs(1 , 0) ;
	Dfs2(1 , 0 , 0) ; cout << Ans << endl ;
	return 0 ;
}


#include <bits/stdc++.h>

const int N = 262144;
const int mod = 998244353;
using LL = long long;
int n, k, head[N], tot, down[N], x, y;
struct edge { int to, nxt; } e[N << 1];
void link(int x, int y) {
	e[++tot] = (edge) { y, head[x] }, head[x] = tot;
	e[++tot] = (edge) { x, head[y] }, head[y] = tot;
}
int lim, g, wn[N], s, rev[N], w[N];
void reduce(int &x) { x += x >> 31 & mod; }
int pow(int x, int y, int ans = 1) {
	for (; y; y >>= 1, x = (LL) x * x % mod)
		if (y & 1) ans = (LL) ans * x % mod;
	return ans;
}
void fftinit(int len) {
	lim = wn[0] = 1, s = -1; while (lim < len) lim <<= 1, ++s;
	for (int i = 0; i < lim; ++i) rev[i] = rev[i >> 1] >> 1 | (i & 1) << s;
	const int g = pow(3, (mod - 1) / lim);
	for (int i = 1; i < lim; ++i) wn[i] = (LL) wn[i - 1] * g % mod;
}
void fft(int *A, int typ) {
	for (int i = 0; i < lim; ++i) if (i < rev[i]) std::swap(A[i], A[rev[i]]);
	for (int i = 1; i < lim; i <<= 1) {
		for (int j = 0, t = lim / i / 2; j < i; ++j) w[j] = wn[j * t];
		for (int j = 0; j < lim; j += i << 1)
			for (int k = 0; k < i; ++k) {
				int x = A[k + j], y = (LL) A[k + j + i] * w[k] % mod;
				reduce(A[k + j] += y - mod), reduce(A[k + j + i] = x - y);
			}
	}
	if (!typ) {
		const int il = pow(lim, mod - 2);
		for (int i = 0; i < lim; ++i)
			A[i] = (LL) A[i] * il % mod;
		std::reverse(A + 1, A + lim);
	}
}
int F[N], G[N], ans, id[N], cnt, now, size[N];
using poly = std::vector<int>;
poly operator * (const poly &lhs, const poly &rhs) {
	static int a[N], b[N], n, m;
	n = lhs.size(), m = rhs.size();
	fftinit(n + m - 1);
	std::memcpy(a, lhs.data(), n << 2), std::memset(a + n, 0, lim - n << 2);
	std::memcpy(b, rhs.data(), m << 2), std::memset(b + m, 0, lim - m << 2);
	fft(a, 1), fft(b, 1);
	for (int i = 0; i < lim; ++i) a[i] = (LL) a[i] * b[i] % mod;
	fft(a, 0);
	return poly(a, a + n + m - 1);
}
poly operator + (const poly &lhs, const poly &rhs) {
	poly ret(lhs);
	for (int i = 0; i < ret.size(); ++i)
		reduce(ret[i] += rhs[i] - mod);
	return ret;
}
std::pair<poly, poly> solve(int l, int r) {
	if (l == r)
		return {{1, size[id[l]]}, { G[id[l]], (int) ((LL) G[id[l]] * (n - size[now]) % mod) }};
	int mid = l + r >> 1;
	std::pair<poly, poly> L = solve(l, mid), R = solve(mid + 1, r);
	return { L.first * R.first, L.first * R.second + L.second * R.first };
}
int dfs(int x, int f = 0) {
	size[x] = 1; int qaq = 0;
	for (int i = head[x]; i; i = e[i].nxt) if (e[i].to != f) {
		size[x] += dfs(e[i].to, x);
		reduce(ans += (LL) G[x] * G[e[i].to] % mod - mod);
		reduce(G[x] += G[e[i].to] - mod), qaq = 1;
	}
	if (!qaq) return F[x] = G[x] = 1;
	now = x, cnt = 0;
	for (int i = head[x]; i; i = e[i].nxt)
		if (e[i].to != f) id[++cnt] = e[i].to;
	std::pair<poly, poly> ret = solve(1, cnt);
	for (int i = 0; i < ret.second.size(); ++i)
		reduce(ans += (LL) down[i] * ret.second[i] % mod - mod);
	for (int i = 0; i < ret.first.size(); ++i)
		reduce(F[x] += (LL) down[i] * ret.first[i] % mod - mod);
	reduce(G[x] += F[x] - mod);
	return size[x];
}
int main() {
	std::ios::sync_with_stdio(0), std::cin.tie(0);
	std::cin >> n >> k;
	if (k == 1) { std::cout << (LL) n * (n - 1) / 2 % mod << '\n'; return 0; }
	down[0] = 1;
	for (int i = 1; i <= k; ++i)
		down[i] = (LL) down[i - 1] * (k - i + 1) % mod;
	for (int i = 1; i < n; ++i) std::cin >> x >> y, link(x, y);
	dfs(1);
	std::cout << ans << '\n';
	return 0;
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
%:pragma GCC optimize("-fgcse")
%:pragma GCC optimize("-fgcse-lm")
%:pragma GCC optimize("-fipa-sra")
%:pragma GCC optimize("-ftree-pre")
%:pragma GCC optimize("-ftree-vrp")
%:pragma GCC optimize("-fpeephole2")
%:pragma GCC optimize("-ffast-math")
%:pragma GCC optimize("-fsched-spec")
%:pragma GCC optimize("unroll-loops")
%:pragma GCC optimize("-falign-jumps")
%:pragma GCC optimize("-falign-loops")
%:pragma GCC optimize("-falign-labels")
%:pragma GCC optimize("-fdevirtualize")
%:pragma GCC optimize("-fcaller-saves")
%:pragma GCC optimize("-fcrossjumping")
%:pragma GCC optimize("-fthread-jumps")
%:pragma GCC optimize("-funroll-loops")
%:pragma GCC optimize("-fwhole-program")
%:pragma GCC optimize("-freorder-blocks")
%:pragma GCC optimize("-fschedule-insns")
%:pragma GCC optimize("inline-functions")
%:pragma GCC optimize("-ftree-tail-merge")
%:pragma GCC optimize("-fschedule-insns2")
%:pragma GCC optimize("-fstrict-aliasing")
%:pragma GCC optimize("-fstrict-overflow")
%:pragma GCC optimize("-falign-functions")
%:pragma GCC optimize("-fcse-skip-blocks")
%:pragma GCC optimize("-fcse-follow-jumps")
%:pragma GCC optimize("-fsched-interblock")
%:pragma GCC optimize("-fpartial-inlining")
%:pragma GCC optimize("no-stack-protector")
%:pragma GCC optimize("-freorder-functions")
%:pragma GCC optimize("-findirect-inlining")
%:pragma GCC optimize("-fhoist-adjacent-loads")
%:pragma GCC optimize("-frerun-cse-after-loop")
%:pragma GCC optimize("inline-small-functions")
%:pragma GCC optimize("-finline-small-functions")
%:pragma GCC optimize("-ftree-switch-conversion")
%:pragma GCC optimize("-foptimize-sibling-calls")
%:pragma GCC optimize("-fexpensive-optimizations")
%:pragma GCC optimize("-funsafe-loop-optimizations")
%:pragma GCC optimize("inline-functions-called-once")
%:pragma GCC optimize("-fdelete-null-pointer-checks")
#include<bits/stdc++.h>
using namespace std;
const int maxn=8e5;
const int p=998244353;
int r[maxn],lim,fact[maxn],ifact[maxn],inv[maxn];
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x;
}
inline int poww(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=1ll*ans*a%p;
		b>>=1;
		a=1ll*a*a%p;
	}
	return ans;
}
inline void getrev(int deg){
	lim=1;int l=0;
	while(lim<=deg)lim<<=1,++l;
	for(register int i=0;i<=lim;++i)r[i]=r[i>>1]>>1|(i&1)<<(l-1);
}
struct poly{
	vector<int>A;
	int& operator [](const int i){return A[i];}
	void set(int x){A.resize(x+1);}
	int len(){return A.size()-1;}
	void NTT(int type)
    {
        int pr=3;
        if(type==1)A.resize(lim);
		for(register int i=0;i<lim;++i)if(r[i]>i)swap(A[i],A[r[i]]);
		for(register int mid=1;mid<lim;mid<<=1){
			int wn=poww(type==-1?inv[pr]:pr,(p-1)/(mid<<1));
			for(register int j=0,R=mid<<1;j<lim;j+=R){
				int w=1;
				for(register int k=0;k<mid;++k,w=1ll*w*wn%p){
					int x=A[j+k],y=1ll*w*A[j+k+mid]%p;
	                A[j+k]=(x+y)%p;
	                A[j+k+mid]=((x-y+p)%p+p)%p;
				}
			}
		}
		if(type==-1){
			int Inv=inv[lim];for(register int i=0;i<lim;++i)A[i]=1ll*A[i]*Inv%p;
		}
    }
}F[maxn],G[maxn];
int siz[maxn],n,m,f[maxn];
vector<int>v;
void solve(int l,int r,int rt){
	if(l==r){
		F[rt].set(1),G[rt].set(1);
		F[rt][0]=1;F[rt][1]=siz[v[l]];
		G[rt][0]=f[v[l]],G[rt][1]=1ll*f[v[l]]*(n-siz[v[0]])%p;
		return;
	}
	int mid=l+r>>1,len=r-l+1;
	solve(l,mid,rt<<1);solve(mid+1,r,rt<<1|1);
	getrev(len<<1);
	poly &A=F[rt],&B=G[rt],&Fl=F[rt<<1],&Fr=F[rt<<1|1],&Gl=G[rt<<1],&Gr=G[rt<<1|1];
	A.set(lim-1);B.set(lim-1);
	Fl.NTT(1);Fr.NTT(1);Gl.NTT(1);Gr.NTT(1);
	for(register int i=0;i<lim;++i)A[i]=1ll*Fl[i]*Fr[i]%p,B[i]=(1ll*Fl[i]*Gr[i]%p+1ll*Fr[i]*Gl[i]%p)%p;
	A.NTT(-1);B.NTT(-1);
	A.set(len);B.set(len);
}
struct edge{
	int to,nxt;
}e[maxn];
int head[maxn],tot,ans;
void add(int x,int y){
	e[++tot].to=y;
	e[tot].nxt=head[x];
	head[x]=tot;
}
void dfs(int x,int fa){
	siz[x]=1;
	for(register int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		dfs(y,x);
		siz[x]+=siz[y];
	}
	v.clear();v.push_back(x);
	for(register int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		ans=(ans+1ll*f[x]*f[y]%p)%p;f[x]=(f[x]+f[y])%p;
		v.push_back(y);
	}
	if(v.size()==1)return f[x]=1,void();
	solve(1,v.size()-1,1);
	for(register int i=0;i<v.size();++i)
        if(m>=i)f[x]=(f[x]+1ll*fact[m]*ifact[m-i]%p*F[1][i]%p)%p,ans=(ans+1ll*fact[m]*ifact[m-i]%p*G[1][i]%p)%p;
}
int main(){
	inv[0]=inv[1]=1;
	for(int i=2;i<maxn;++i)inv[i]=1ll*(p-p/i)*inv[p%i]%p;
	n=read();m=read();
	for(register int i=1;i<n;++i){
		int x,y;
		x=read();y=read();
		add(x,y);add(y,x);
	}
	fact[0]=1;
	for(register int i=1;i<=n;++i)fact[i]=1ll*fact[i-1]*i%p;
	ifact[n]=poww(fact[n],p-2);
	for(register int i=n-1;i>=0;--i)ifact[i]=1ll*ifact[i+1]*(i+1)%p;
	if(m>1)dfs(1,0);else ans=1ll*inv[2]*n%p*(n-1)%p;
	cout<<ans;
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
%:pragma GCC optimize("-fgcse")
%:pragma GCC optimize("-fgcse-lm")
%:pragma GCC optimize("-fipa-sra")
%:pragma GCC optimize("-ftree-pre")
%:pragma GCC optimize("-ftree-vrp")
%:pragma GCC optimize("-fpeephole2")
%:pragma GCC optimize("-ffast-math")
%:pragma GCC optimize("-fsched-spec")
%:pragma GCC optimize("unroll-loops")
%:pragma GCC optimize("-falign-jumps")
%:pragma GCC optimize("-falign-loops")
%:pragma GCC optimize("-falign-labels")
%:pragma GCC optimize("-fdevirtualize")
%:pragma GCC optimize("-fcaller-saves")
%:pragma GCC optimize("-fcrossjumping")
%:pragma GCC optimize("-fthread-jumps")
%:pragma GCC optimize("-funroll-loops")
%:pragma GCC optimize("-fwhole-program")
%:pragma GCC optimize("-freorder-blocks")
%:pragma GCC optimize("-fschedule-insns")
%:pragma GCC optimize("inline-functions")
%:pragma GCC optimize("-ftree-tail-merge")
%:pragma GCC optimize("-fschedule-insns2")
%:pragma GCC optimize("-fstrict-aliasing")
%:pragma GCC optimize("-fstrict-overflow")
%:pragma GCC optimize("-falign-functions")
%:pragma GCC optimize("-fcse-skip-blocks")
%:pragma GCC optimize("-fcse-follow-jumps")
%:pragma GCC optimize("-fsched-interblock")
%:pragma GCC optimize("-fpartial-inlining")
%:pragma GCC optimize("no-stack-protector")
%:pragma GCC optimize("-freorder-functions")
%:pragma GCC optimize("-findirect-inlining")
%:pragma GCC optimize("-fhoist-adjacent-loads")
%:pragma GCC optimize("-frerun-cse-after-loop")
%:pragma GCC optimize("inline-small-functions")
%:pragma GCC optimize("-finline-small-functions")
%:pragma GCC optimize("-ftree-switch-conversion")
%:pragma GCC optimize("-foptimize-sibling-calls")
%:pragma GCC optimize("-fexpensive-optimizations")
%:pragma GCC optimize("-funsafe-loop-optimizations")
%:pragma GCC optimize("inline-functions-called-once")
%:pragma GCC optimize("-fdelete-null-pointer-checks")
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5;
const int p=998244353;
int r[maxn],lim,fact[maxn],ifact[maxn],inv[maxn];
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x;
}
inline int poww(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=1ll*ans*a%p;
		b>>=1;
		a=1ll*a*a%p;
	}
	return ans;
}
inline void getrev(int deg){
	lim=1;int l=0;
	while(lim<=deg)lim<<=1,++l;
	for(register int i=0;i<=lim;++i)r[i]=r[i>>1]>>1|(i&1)<<(l-1);
}
struct poly{
	vector<int>A;
	int& operator [](const int i){return A[i];}
	void set(int x){A.resize(x+1);}
	int len(){return A.size()-1;}
	void NTT(int type)
    {
        int pr=3;
        if(type==1)A.resize(lim);
		for(register int i=0;i<lim;++i)if(r[i]>i)swap(A[i],A[r[i]]);
		for(register int mid=1;mid<lim;mid<<=1){
			int wn=poww(type==-1?inv[pr]:pr,(p-1)/(mid<<1));
			for(register int j=0,R=mid<<1;j<lim;j+=R){
				int w=1;
				for(register int k=0;k<mid;++k,w=1ll*w*wn%p){
					int x=A[j+k],y=1ll*w*A[j+k+mid]%p;
	                A[j+k]=(x+y)%p;
	                A[j+k+mid]=((x-y+p)%p+p)%p;
				}
			}
		}
		if(type==-1){
			int Inv=inv[lim];for(register int i=0;i<lim;++i)A[i]=1ll*A[i]*Inv%p;
		}
    }
}F[maxn],G[maxn];
int siz[maxn],n,m,f[maxn];
vector<int>v;
void solve(int l,int r,int rt){
	if(l==r){
		F[rt].set(1),G[rt].set(1);
		F[rt][0]=1;F[rt][1]=siz[v[l]];
		G[rt][0]=f[v[l]],G[rt][1]=1ll*f[v[l]]*(n-siz[v[0]])%p;
		return;
	}
	int mid=l+r>>1,len=r-l+1;
	solve(l,mid,rt<<1);solve(mid+1,r,rt<<1|1);
	getrev(len<<1);
	poly &A=F[rt],&B=G[rt],&Fl=F[rt<<1],&Fr=F[rt<<1|1],&Gl=G[rt<<1],&Gr=G[rt<<1|1];
	A.set(lim-1);B.set(lim-1);
	Fl.NTT(1);Fr.NTT(1);Gl.NTT(1);Gr.NTT(1);
	for(register int i=0;i<lim;++i)A[i]=1ll*Fl[i]*Fr[i]%p,B[i]=(1ll*Fl[i]*Gr[i]%p+1ll*Fr[i]*Gl[i]%p)%p;
	A.NTT(-1);B.NTT(-1);
	A.set(len);B.set(len);
}
struct edge{
	int to,nxt;
}e[maxn];
int head[maxn],tot,ans;
void add(int x,int y){
	e[++tot].to=y;
	e[tot].nxt=head[x];
	head[x]=tot;
}
void dfs(int x,int fa){
	siz[x]=1;
	for(register int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		dfs(y,x);
		siz[x]+=siz[y];
	}
	v.clear();v.push_back(x);
	for(register int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		ans=(ans+1ll*f[x]*f[y]%p)%p;f[x]=(f[x]+f[y])%p;
		v.push_back(y);
	}
	if(v.size()==1)return f[x]=1,void();
	solve(1,v.size()-1,1);
	for(register int i=0;i<v.size();++i)
        if(m>=i)f[x]=(f[x]+1ll*fact[m]*ifact[m-i]%p*F[1][i]%p)%p,ans=(ans+1ll*fact[m]*ifact[m-i]%p*G[1][i]%p)%p;
}
int main(){
	inv[0]=inv[1]=1;
	for(int i=2;i<maxn;++i)inv[i]=1ll*(p-p/i)*inv[p%i]%p;
	n=read();m=read();
	for(register int i=1;i<n;++i){
		int x,y;
		x=read();y=read();
		add(x,y);add(y,x);
	}
	fact[0]=1;
	for(register int i=1;i<=n;++i)fact[i]=1ll*fact[i-1]*i%p;
	ifact[n]=poww(fact[n],p-2);
	for(register int i=n-1;i>=0;--i)ifact[i]=1ll*ifact[i+1]*(i+1)%p;
	if(m>1)dfs(1,0);else ans=1ll*inv[2]*n%p*(n-1)%p;
	cout<<ans;
}


#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5;
const int p=998244353;
int r[maxn],lim,fact[maxn],ifact[maxn];
inline int poww(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=1ll*ans*a%p;
		b>>=1;
		a=1ll*a*a%p;
	}
	return ans;
}
inline int inv(int x){
	return poww(x,p-2);
}
inline void getrev(int deg){
	lim=1;int l=0;
	while(lim<=deg)lim<<=1,++l;
	for(int i=0;i<=lim;++i)r[i]=r[i>>1]>>1|(i&1)<<(l-1);
}
struct poly{
	vector<int>A;
	int& operator [](const int i){return A[i];}
	void set(int x){A.resize(x+1);}
	int len(){return A.size()-1;}
	void NTT(int type)
    {
        int pr=3;
        if(type==1)A.resize(lim);
		for(int i=0;i<lim;++i)if(r[i]>i)swap(A[i],A[r[i]]);
		for(int mid=1;mid<lim;mid<<=1){
			int wn=poww(type==-1?inv(pr):pr,(p-1)/(mid<<1));
			for(int j=0,R=mid<<1;j<lim;j+=R){
				int w=1;
				for(int k=0;k<mid;++k,w=1ll*w*wn%p){
					int x=A[j+k],y=1ll*w*A[j+k+mid]%p;
	                A[j+k]=(x+y)%p;
	                A[j+k+mid]=(x-y+p)%p;
				}
			}
		}
		if(type==-1){
			int Inv=inv(lim);for(int i=0;i<lim;++i)A[i]=1ll*A[i]*Inv%p;
		}
    }
}F[maxn],G[maxn];
int siz[maxn],n,m,f[maxn];
vector<int>v;
void solve(int l,int r,int rt){
	if(l==r){
		F[rt].set(1),G[rt].set(1);
		F[rt][0]=1;F[rt][1]=siz[v[l]];
		G[rt][0]=f[v[l]],G[rt][1]=1ll*f[v[l]]*(n-siz[v[0]])%p;
		return;
	}
	int mid=l+r>>1,len=r-l+1;
	solve(l,mid,rt<<1);solve(mid+1,r,rt<<1|1);
	getrev(len<<1);
	poly &A=F[rt],&B=G[rt],&Fl=F[rt<<1],&Fr=F[rt<<1|1],&Gl=G[rt<<1],&Gr=G[rt<<1|1];
	A.set(lim-1);B.set(lim-1);
	Fl.NTT(1);Fr.NTT(1);Gl.NTT(1);Gr.NTT(1);
	for(int i=0;i<lim;++i)A[i]=1ll*Fl[i]*Fr[i]%p,B[i]=(1ll*Fl[i]*Gr[i]%p+1ll*Fr[i]*Gl[i]%p)%p;
	A.NTT(-1);B.NTT(-1);
	A.set(len);B.set(len);
}
struct edge{
	int to,nxt;
}e[maxn];
int head[maxn],tot,ans;
void add(int x,int y){
	e[++tot].to=y;
	e[tot].nxt=head[x];
	head[x]=tot;
}
void dfs(int x,int fa){
	siz[x]=1;
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		dfs(y,x);
		siz[x]+=siz[y];
	}
	v.clear();v.push_back(x);
	for(int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		ans=(ans+1ll*f[x]*f[y]%p)%p;f[x]=(f[x]+f[y])%p;
		v.push_back(y);
	}
	if(v.size()==1)return f[x]=1,void();
	solve(1,v.size()-1,1);
	for(int i=0;i<v.size();++i)
        if(m>=i)f[x]=(f[x]+1ll*fact[m]*ifact[m-i]%p*F[1][i]%p)%p,ans=(ans+1ll*fact[m]*ifact[m-i]%p*G[1][i]%p)%p;
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<n;++i){
		int x,y;scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	fact[0]=1;
	for(int i=1;i<=n;++i)fact[i]=1ll*fact[i-1]*i%p;
	ifact[n]=inv(fact[n]);
	for(int i=n-1;i>=0;--i)ifact[i]=1ll*ifact[i+1]*(i+1)%p;
	if(m>1)dfs(1,0);else ans=1ll*inv(2)*n%p*(n-1)%p;
	cout<<ans;
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
%:pragma GCC optimize("-fgcse")
%:pragma GCC optimize("-fgcse-lm")
%:pragma GCC optimize("-fipa-sra")
%:pragma GCC optimize("-ftree-pre")
%:pragma GCC optimize("-ftree-vrp")
%:pragma GCC optimize("-fpeephole2")
%:pragma GCC optimize("-ffast-math")
%:pragma GCC optimize("-fsched-spec")
%:pragma GCC optimize("unroll-loops")
%:pragma GCC optimize("-falign-jumps")
%:pragma GCC optimize("-falign-loops")
%:pragma GCC optimize("-falign-labels")
%:pragma GCC optimize("-fdevirtualize")
%:pragma GCC optimize("-fcaller-saves")
%:pragma GCC optimize("-fcrossjumping")
%:pragma GCC optimize("-fthread-jumps")
%:pragma GCC optimize("-funroll-loops")
%:pragma GCC optimize("-fwhole-program")
%:pragma GCC optimize("-freorder-blocks")
%:pragma GCC optimize("-fschedule-insns")
%:pragma GCC optimize("inline-functions")
%:pragma GCC optimize("-ftree-tail-merge")
%:pragma GCC optimize("-fschedule-insns2")
%:pragma GCC optimize("-fstrict-aliasing")
%:pragma GCC optimize("-fstrict-overflow")
%:pragma GCC optimize("-falign-functions")
%:pragma GCC optimize("-fcse-skip-blocks")
%:pragma GCC optimize("-fcse-follow-jumps")
%:pragma GCC optimize("-fsched-interblock")
%:pragma GCC optimize("-fpartial-inlining")
%:pragma GCC optimize("no-stack-protector")
%:pragma GCC optimize("-freorder-functions")
%:pragma GCC optimize("-findirect-inlining")
%:pragma GCC optimize("-fhoist-adjacent-loads")
%:pragma GCC optimize("-frerun-cse-after-loop")
%:pragma GCC optimize("inline-small-functions")
%:pragma GCC optimize("-finline-small-functions")
%:pragma GCC optimize("-ftree-switch-conversion")
%:pragma GCC optimize("-foptimize-sibling-calls")
%:pragma GCC optimize("-fexpensive-optimizations")
%:pragma GCC optimize("-funsafe-loop-optimizations")
%:pragma GCC optimize("inline-functions-called-once")
%:pragma GCC optimize("-fdelete-null-pointer-checks")
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5;
const int p=998244353;
int r[maxn],lim,fact[maxn],ifact[maxn],inv[maxn];
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x;
}
inline int poww(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=1ll*ans*a%p;
		b>>=1;
		a=1ll*a*a%p;
	}
	return ans;
}
inline void getrev(int deg){
	lim=1;int l=0;
	while(lim<=deg)lim<<=1,++l;
	for(register int i=0;i<=lim;++i)r[i]=r[i>>1]>>1|(i&1)<<(l-1);
}
struct poly{
	vector<int>A;
	int& operator [](const int i){return A[i];}
	void set(int x){A.resize(x+1);}
	int len(){return A.size()-1;}
	void NTT(int type)
    {
        int pr=3;
        if(type==1)A.resize(lim);
		for(register int i=0;i<lim;++i)if(r[i]>i)swap(A[i],A[r[i]]);
		for(register int mid=1;mid<lim;mid<<=1){
			int wn=poww(type==-1?inv[pr]:pr,(p-1)/(mid<<1));
			for(register int j=0,R=mid<<1;j<lim;j+=R){
				int w=1;
				for(register int k=0;k<mid;++k,w=1ll*w*wn%p){
					int x=A[j+k],y=1ll*w*A[j+k+mid]%p;
	                A[j+k]=(x+y)%p;
	                A[j+k+mid]=(x-y+p)%p;
				}
			}
		}
		if(type==-1){
			int Inv=inv[lim];for(register int i=0;i<lim;++i)A[i]=1ll*A[i]*Inv%p;
		}
    }
}F[maxn],G[maxn];
int siz[maxn],n,m,f[maxn];
vector<int>v;
void solve(int l,int r,int rt){
	if(l==r){
		F[rt].set(1),G[rt].set(1);
		F[rt][0]=1;F[rt][1]=siz[v[l]];
		G[rt][0]=f[v[l]],G[rt][1]=1ll*f[v[l]]*(n-siz[v[0]])%p;
		return;
	}
	int mid=l+r>>1,len=r-l+1;
	solve(l,mid,rt<<1);solve(mid+1,r,rt<<1|1);
	getrev(len<<1);
	poly &A=F[rt],&B=G[rt],&Fl=F[rt<<1],&Fr=F[rt<<1|1],&Gl=G[rt<<1],&Gr=G[rt<<1|1];
	A.set(lim-1);B.set(lim-1);
	Fl.NTT(1);Fr.NTT(1);Gl.NTT(1);Gr.NTT(1);
	for(register int i=0;i<lim;++i)A[i]=1ll*Fl[i]*Fr[i]%p,B[i]=(1ll*Fl[i]*Gr[i]%p+1ll*Fr[i]*Gl[i]%p)%p;
	A.NTT(-1);B.NTT(-1);
	A.set(len);B.set(len);
}
struct edge{
	int to,nxt;
}e[maxn];
int head[maxn],tot,ans;
void add(int x,int y){
	e[++tot].to=y;
	e[tot].nxt=head[x];
	head[x]=tot;
}
void dfs(int x,int fa){
	siz[x]=1;
	for(register int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		dfs(y,x);
		siz[x]+=siz[y];
	}
	v.clear();v.push_back(x);
	for(register int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		ans=(ans+1ll*f[x]*f[y]%p)%p;f[x]=(f[x]+f[y])%p;
		v.push_back(y);
	}
	if(v.size()==1)return f[x]=1,void();
	solve(1,v.size()-1,1);
	for(register int i=0;i<v.size();++i)
        if(m>=i)f[x]=(f[x]+1ll*fact[m]*ifact[m-i]%p*F[1][i]%p)%p,ans=(ans+1ll*fact[m]*ifact[m-i]%p*G[1][i]%p)%p;
}
int main(){
	inv[0]=inv[1]=1;
	for(int i=2;i<maxn;++i)inv[i]=1ll*(p-p/i)*inv[p%i]%p;
	n=read();m=read();
	for(register int i=1;i<n;++i){
		int x,y;
		x=read();y=read();
		add(x,y);add(y,x);
	}
	fact[0]=1;
	for(register int i=1;i<=max(n,m);++i)fact[i]=1ll*fact[i-1]*i%p;
	ifact[max(n,m)]=poww(fact[max(n,m)],p-2);
	for(register int i=max(n,m)-1;i>=0;--i)ifact[i]=1ll*ifact[i+1]*(i+1)%p;
	if(m>1)dfs(1,0);else ans=1ll*inv[2]*n%p*(n-1)%p;
	cout<<ans;
}


#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
%:pragma GCC optimize("Ofast")
%:pragma GCC optimize("inline")
%:pragma GCC optimize("-fgcse")
%:pragma GCC optimize("-fgcse-lm")
%:pragma GCC optimize("-fipa-sra")
%:pragma GCC optimize("-ftree-pre")
%:pragma GCC optimize("-ftree-vrp")
%:pragma GCC optimize("-fpeephole2")
%:pragma GCC optimize("-ffast-math")
%:pragma GCC optimize("-fsched-spec")
%:pragma GCC optimize("unroll-loops")
%:pragma GCC optimize("-falign-jumps")
%:pragma GCC optimize("-falign-loops")
%:pragma GCC optimize("-falign-labels")
%:pragma GCC optimize("-fdevirtualize")
%:pragma GCC optimize("-fcaller-saves")
%:pragma GCC optimize("-fcrossjumping")
%:pragma GCC optimize("-fthread-jumps")
%:pragma GCC optimize("-funroll-loops")
%:pragma GCC optimize("-fwhole-program")
%:pragma GCC optimize("-freorder-blocks")
%:pragma GCC optimize("-fschedule-insns")
%:pragma GCC optimize("inline-functions")
%:pragma GCC optimize("-ftree-tail-merge")
%:pragma GCC optimize("-fschedule-insns2")
%:pragma GCC optimize("-fstrict-aliasing")
%:pragma GCC optimize("-fstrict-overflow")
%:pragma GCC optimize("-falign-functions")
%:pragma GCC optimize("-fcse-skip-blocks")
%:pragma GCC optimize("-fcse-follow-jumps")
%:pragma GCC optimize("-fsched-interblock")
%:pragma GCC optimize("-fpartial-inlining")
%:pragma GCC optimize("no-stack-protector")
%:pragma GCC optimize("-freorder-functions")
%:pragma GCC optimize("-findirect-inlining")
%:pragma GCC optimize("-fhoist-adjacent-loads")
%:pragma GCC optimize("-frerun-cse-after-loop")
%:pragma GCC optimize("inline-small-functions")
%:pragma GCC optimize("-finline-small-functions")
%:pragma GCC optimize("-ftree-switch-conversion")
%:pragma GCC optimize("-foptimize-sibling-calls")
%:pragma GCC optimize("-fexpensive-optimizations")
%:pragma GCC optimize("-funsafe-loop-optimizations")
%:pragma GCC optimize("inline-functions-called-once")
%:pragma GCC optimize("-fdelete-null-pointer-checks")
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5;
const int p=998244353;
int r[maxn],lim,fact[maxn],ifact[maxn],inv[maxn];
inline int read(){
	int x=0;char ch=getchar();
	while(ch<'0'||ch>'9'){ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x;
}
inline int poww(int a,int b){
	int ans=1;
	while(b){
		if(b&1)ans=1ll*ans*a%p;
		b>>=1;
		a=1ll*a*a%p;
	}
	return ans;
}
inline void getrev(int deg){
	lim=1;int l=0;
	while(lim<=deg)lim<<=1,++l;
	for(register int i=0;i<=lim;++i)r[i]=r[i>>1]>>1|(i&1)<<(l-1);
}
struct poly{
	vector<int>A;
	int& operator [](const int i){return A[i];}
	void set(int x){A.resize(x+1);}
	int len(){return A.size()-1;}
	void NTT(int type)
    {
        int pr=3;
        if(type==1)A.resize(lim);
		for(register int i=0;i<lim;++i)if(r[i]>i)swap(A[i],A[r[i]]);
		for(register int mid=1;mid<lim;mid<<=1){
			int wn=poww(type==-1?inv[pr]:pr,(p-1)/(mid<<1));
			for(register int j=0,R=mid<<1;j<lim;j+=R){
				int w=1;
				for(register int k=0;k<mid;++k,w=1ll*w*wn%p){
					int x=A[j+k],y=1ll*w*A[j+k+mid]%p;
	                A[j+k]=(x+y)%p;
	                A[j+k+mid]=(x-y+p)%p;
				}
			}
		}
		if(type==-1){
			int Inv=inv[lim];for(register int i=0;i<lim;++i)A[i]=1ll*A[i]*Inv%p;
		}
    }
}F[maxn],G[maxn];
int siz[maxn],n,m,f[maxn];
vector<int>v;
void solve(int l,int r,int rt){
	if(l==r){
		F[rt].set(1),G[rt].set(1);
		F[rt][0]=1;F[rt][1]=siz[v[l]];
		G[rt][0]=f[v[l]],G[rt][1]=1ll*f[v[l]]*(n-siz[v[0]])%p;
		return;
	}
	int mid=l+r>>1,len=r-l+1;
	solve(l,mid,rt<<1);solve(mid+1,r,rt<<1|1);
	getrev(len<<1);
	poly &A=F[rt],&B=G[rt],&Fl=F[rt<<1],&Fr=F[rt<<1|1],&Gl=G[rt<<1],&Gr=G[rt<<1|1];
	A.set(lim-1);B.set(lim-1);
	Fl.NTT(1);Fr.NTT(1);Gl.NTT(1);Gr.NTT(1);
	for(register int i=0;i<lim;++i)A[i]=1ll*Fl[i]*Fr[i]%p,B[i]=(1ll*Fl[i]*Gr[i]%p+1ll*Fr[i]*Gl[i]%p)%p;
	A.NTT(-1);B.NTT(-1);
	A.set(len);B.set(len);
}
struct edge{
	int to,nxt;
}e[maxn];
int head[maxn],tot,ans;
void add(int x,int y){
	e[++tot].to=y;
	e[tot].nxt=head[x];
	head[x]=tot;
}
void dfs(int x,int fa){
	siz[x]=1;
	for(register int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		dfs(y,x);
		siz[x]+=siz[y];
	}
	v.clear();v.push_back(x);
	for(register int i=head[x];i;i=e[i].nxt){
		int y=e[i].to;
		if(y==fa)continue;
		ans=(ans+1ll*f[x]*f[y]%p)%p;f[x]=(f[x]+f[y])%p;
		v.push_back(y);
	}
	if(v.size()==1)return f[x]=1,void();
	solve(1,v.size()-1,1);
	for(register int i=0;i<v.size();++i)
        if(m>=i)f[x]=(f[x]+1ll*fact[m]*ifact[m-i]%p*F[1][i]%p)%p,ans=(ans+1ll*fact[m]*ifact[m-i]%p*G[1][i]%p)%p;
}
int main(){
	inv[0]=inv[1]=1;
	for(int i=2;i<maxn;++i)inv[i]=1ll*(p-p/i)*inv[p%i]%p;
	n=read();m=read();
	for(register int i=1;i<n;++i){
		int x,y;
		x=read();y=read();
		add(x,y);add(y,x);
	}
	fact[0]=1;
	for(register int i=1;i<=n;++i)fact[i]=1ll*fact[i-1]*i%p;
	ifact[n]=poww(fact[n],p-2);
	for(register int i=n-1;i>=0;--i)ifact[i]=1ll*ifact[i+1]*(i+1)%p;
	if(m>1)dfs(1,0);else ans=1ll*inv[2]*n%p*(n-1)%p;
	cout<<ans;
}


#include <bits/stdc++.h>
#pragma GCC optimize(3)
#define N 100005
using namespace std;

typedef long long LL;
const LL M=998244353;
const LL g=3;

void exgcd(LL a,LL b,LL &x,LL &y){
	if (b==0) {x=1,y=0; return;}
	exgcd(b,a%b,x,y);
	LL t=x; x=y, y=t-(a/b)*y;
}
LL inv(LL a){
    LL x,y; exgcd(a,M,x,y);
    return (x+M)%M;
}
LL Qpow(LL x,LL y){//x^y
    if (y==0) return 1;
    LL t=Qpow(x,y/2);
    return (y&1)?t*t%M*x%M:t*t%M;
}

void NTT(vector<LL> &a,vector<LL> &p,LL n,bool INV)
{
    int i,j,k,rev;
    const LL ig=inv(g),in=inv(n);
    for (i=0; i<n; i++){
        rev=0,k=1;
        while (k<n) rev=(rev<<1)+((i&k)>0),k<<=1;
        p[rev]=a[i];
    }

    for (k=1; k<n; k<<=1)
    {
        LL unit=INV?Qpow(ig,(M-1)/(k*2)):Qpow(g,(M-1)/(k*2));
        for (i=0; i<n; i+=k*2)
        {
            LL omega=1;
            for (j=i; j<i+k; j++,omega=omega*unit%M){
                LL x=p[j],y=p[j+k]*omega%M;
                p[j]=(x+y)%M, p[j+k]=(x-y+M)%M;
            }
        }
    }

    if (INV)
        for (i=0; i<n; i++) p[i]=p[i]*in%M;
}

void mul(vector<LL> &A,int dega,vector<LL> B,int degb)//A <- A*B
{
    int bit=1,deg=dega+degb;
    while (bit<deg+1) bit<<=1;

    A.resize(bit,0),B.resize(bit,0);
    vector<LL> pA(bit),pB(bit);
    NTT(A,pA,bit,false), NTT(B,pB,bit,false);
    for (int i=0; i<bit; i++) pA[i]=pA[i]*pB[i]%M;
    NTT(pA,A,bit,true);
}
void polymul(vector<LL> *poly,int *para,int l,int r)//(1+para_1*x)(1+para_2*x)...(1+para_m*x)
{
    if (l>r) return;
    if (l==r) {poly[l].resize(2),poly[l][0]=1,poly[l][1]=para[l]; return;}
    int mid=(l+r)/2;
    polymul(poly,para,l,mid), polymul(poly,para,mid+1,r);
    mul(poly[l],mid-l+1,poly[mid+1],r-mid);
}

int n,m,i,j,k,x,y,sz[N/2];
vector<int> e[N/2];
LL sum[N/2],fact[N/2],ans=0;

LL calc(const vector<LL> &poly,int deg){
    if (deg==0) return 1;
    LL tmp=0,permutation=1;
    for (int i=0; i<=k&&i<=deg; i++)
        tmp=(tmp+poly[i]*permutation%M)%M,permutation=permutation*(k-i)%M;
    //cout<<endl<<tmp<<endl;system("pause");
    return tmp;
}
void dfs(int u,int fa)
{
    const int deg=e[u].size();
    vector<LL> poly[deg+5];
    int i,j,para[deg+5]={0},cnt=0;

    sum[u]=0,sz[u]=1;
    for (int v:e[u]){
        if (v==fa) continue;
        dfs(v,u);

        ans=(ans+sum[v]*sum[u])%M;
        para[++cnt]=sz[v];
        sz[u]+=sz[v],sum[u]+=sum[v];
    }
    //cout<<u<<":\n";
    polymul(poly,para,1,cnt);//poly[1]=answer polynomial
    sum[u]+=calc(poly[1],cnt);

    unordered_map<int,LL> h;
    unordered_map<int,LL>::iterator it;
    for (int v:e[u]){
        if (v==fa) continue;

        it=h.find(sz[v]);
        if (it!=h.cend()){
            ans=(ans+sum[v]*it->second%M)%M;
            continue;
        }
        else{
            vector<LL> t(cnt+1),tmp(poly[1]);
            const LL isz=inv(sz[v]);
            for (i=cnt-1,t[cnt]=0; i>=0; i--)
            {
                t[i]=tmp[i+1]*isz%M;
                tmp[i]=(tmp[i]-t[i]+M)%M;
            }
            for (i=cnt; i; i--)
                t[i]=(t[i]+t[i-1]*(n-sz[u])%M)%M;

            const LL F=calc(t,cnt);
            ans=(ans+sum[v]*F%M)%M, h.insert(make_pair(sz[v],F));
        }
    }
}
int main()
{
    cin>>n>>k;
    if (k==1) {cout<<1ll*n*(n-1)/2%M; return 0;}
    for (i=1; i<n; i++){
        cin>>x>>y;
        e[x].push_back(y), e[y].push_back(x);
    }

    dfs(1,0);
    cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize(3)
#define N 100005
using namespace std;

typedef long long LL;
const LL M=998244353;
const LL g=3;

void exgcd(LL a,LL b,LL &x,LL &y){
	if (b==0) {x=1,y=0; return;}
	exgcd(b,a%b,x,y);
	LL t=x; x=y, y=t-(a/b)*y;
}
LL inv(LL a){
    LL x,y; exgcd(a,M,x,y);
    return (x+M)%M;
}
LL Qpow(LL x,LL y){//x^y
    if (y==0) return 1;
    LL t=Qpow(x,y/2);
    return (y&1)?t*t%M*x%M:t*t%M;
}

void NTT(vector<LL> &a,vector<LL> &p,LL n,bool INV)
{
    int i,j,k,rev;
    const LL ig=inv(g),in=inv(n);
    for (i=0; i<n; i++){
        rev=0,k=1;
        while (k<n) rev=(rev<<1)+((i&k)>0),k<<=1;
        p[rev]=a[i];
    }

    for (k=1; k<n; k<<=1)
    {
        LL unit=INV?Qpow(ig,(M-1)/(k*2)):Qpow(g,(M-1)/(k*2));
        for (i=0; i<n; i+=k*2)
        {
            LL omega=1;
            for (j=i; j<i+k; j++,omega=omega*unit%M){
                LL x=p[j],y=p[j+k]*omega%M;
                p[j]=(x+y)%M, p[j+k]=(x-y+M)%M;
            }
        }
    }

    if (INV)
        for (i=0; i<n; i++) p[i]=p[i]*in%M;
}

void mul(vector<LL> &A,int dega,vector<LL> B,int degb)//A <- A*B
{
    int bit=1,deg=dega+degb;
    while (bit<deg+1) bit<<=1;

    A.resize(bit,0),B.resize(bit,0);
    vector<LL> pA(bit),pB(bit);
    NTT(A,pA,bit,false), NTT(B,pB,bit,false);
    for (int i=0; i<bit; i++) pA[i]=pA[i]*pB[i]%M;
    NTT(pA,A,bit,true);
}
void polymul(vector<LL> *poly,int *para,int l,int r)//(1+para_1*x)(1+para_2*x)...(1+para_m*x)
{
    if (l>r) return;
    if (l==r) {poly[l].resize(2),poly[l][0]=1,poly[l][1]=para[l]; return;}
    int mid=(l+r)/2;
    polymul(poly,para,l,mid), polymul(poly,para,mid+1,r);
    mul(poly[l],mid-l+1,poly[mid+1],r-mid);
}

int n,m,i,j,k,x,y,sz[N];
vector<int> e[N];
LL sum[N],ans=0;

LL calc(const vector<LL> &poly,int deg){
    if (deg==0) return 1;
    LL tmp=0,permutation=1;
    for (int i=0; i<=k&&i<=deg; i++)
        tmp=(tmp+poly[i]*permutation%M)%M,permutation=permutation*(k-i)%M;
    //cout<<endl<<tmp<<endl;system("pause");
    return tmp;
}
void dfs(int u,int fa)
{
    const int deg=e[u].size();
    vector<LL> poly[deg+5];
    int i,j,para[deg+5]={0},cnt=0;

    sum[u]=0,sz[u]=1;
    for (int v:e[u]){
        if (v==fa) continue;
        dfs(v,u);

        ans=(ans+sum[v]*sum[u])%M;
        para[++cnt]=sz[v];
        sz[u]+=sz[v],sum[u]=(sum[u]+sum[v])%M;
    }
    //cout<<u<<":\n";
    polymul(poly,para,1,cnt);//poly[1]=answer polynomial
    sum[u]=(sum[u]+calc(poly[1],cnt))%M;

    unordered_map<int,LL> h;
    unordered_map<int,LL>::iterator it;
    for (int v:e[u]){
        if (v==fa) continue;

        it=h.find(sz[v]);
        if (it!=h.cend()){
            ans=(ans+sum[v]*it->second%M)%M;
            continue;
        }
        else{
            vector<LL> t(cnt+1),tmp(poly[1]);
            const LL isz=inv(sz[v]);
            for (i=cnt-1,t[cnt]=0; i>=0; i--)
            {
                t[i]=tmp[i+1]*isz%M;
                tmp[i]=(tmp[i]-t[i]+M)%M;
            }
            for (i=cnt; i; i--)
                t[i]=(t[i]+t[i-1]*(n-sz[u])%M)%M;

            const LL F=calc(t,cnt);
            ans=(ans+sum[v]*F%M)%M, h.insert(make_pair(sz[v],F));
        }
    }
}
int main()
{
    cin>>n>>k;
    if (k==1) {cout<<1ll*n*(n-1)/2%M; return 0;}
    for (i=1; i<n; i++){
        cin>>x>>y;
        e[x].push_back(y), e[y].push_back(x);
    }

    dfs(1,0);
    cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize(3)
#define N 100005
using namespace std;

typedef long long LL;
const LL M=998244353;
const LL g=3;

void exgcd(LL a,LL b,LL &x,LL &y){
	if (b==0) {x=1,y=0; return;}
	exgcd(b,a%b,x,y);
	LL t=x; x=y, y=t-(a/b)*y;
}
LL inv(LL a){
    LL x,y; exgcd(a,M,x,y);
    return (x+M)%M;
}
LL Qpow(LL x,LL y){//x^y
    if (y==0) return 1;
    LL t=Qpow(x,y/2);
    return (y&1)?t*t%M*x%M:t*t%M;
}

void NTT(vector<LL> &a,vector<LL> &p,LL n,bool INV)
{
    int i,j,k,rev;
    const LL ig=inv(g),in=inv(n);
    for (i=0; i<n; i++){
        rev=0,k=1;
        while (k<n) rev=(rev<<1)+((i&k)>0),k<<=1;
        p[rev]=a[i];
    }

    for (k=1; k<n; k<<=1)
    {
        LL unit=INV?Qpow(ig,(M-1)/(k*2)):Qpow(g,(M-1)/(k*2));
        for (i=0; i<n; i+=k*2)
        {
            LL omega=1;
            for (j=i; j<i+k; j++,omega=omega*unit%M){
                LL x=p[j],y=p[j+k]*omega%M;
                p[j]=(x+y)%M, p[j+k]=(x-y+M)%M;
            }
        }
    }

    if (INV)
        for (i=0; i<n; i++) p[i]=p[i]*in%M;
}

void mul(vector<LL> &A,int dega,vector<LL> B,int degb)//A <- A*B
{
    int bit=1,deg=dega+degb;
    while (bit<deg+1) bit<<=1;

    A.resize(bit,0),B.resize(bit,0);
    vector<LL> pA(bit),pB(bit);
    NTT(A,pA,bit,false), NTT(B,pB,bit,false);
    for (int i=0; i<bit; i++) pA[i]=pA[i]*pB[i]%M;
    NTT(pA,A,bit,true);
}
void polymul(vector<LL> *poly,int *para,int l,int r)//(1+para_1*x)(1+para_2*x)...(1+para_m*x)
{
    if (l>r) return;
    if (l==r) {poly[l].resize(2),poly[l][0]=1,poly[l][1]=para[l]; return;}
    int mid=(l+r)/2;
    polymul(poly,para,l,mid), polymul(poly,para,mid+1,r);
    mul(poly[l],mid-l+1,poly[mid+1],r-mid);
}

int n,m,i,j,k,x,y,sz[N];
vector<int> e[N];
LL sum[N],fact[N],ans=0;

LL calc(const vector<LL> &poly,int deg){
    if (deg==0) return 1;
    LL tmp=0,permutation=1;
    for (int i=0; i<=k&&i<=deg; i++)
        tmp=(tmp+poly[i]*permutation%M)%M,permutation=permutation*(k-i)%M;
    //cout<<endl<<tmp<<endl;system("pause");
    return tmp;
}
void dfs(int u,int fa)
{
    const int deg=e[u].size();
    vector<LL> poly[deg+5];
    int i,j,para[deg+5]={0},cnt=0;

    sum[u]=0,sz[u]=1;
    for (int v:e[u]){
        if (v==fa) continue;
        dfs(v,u);

        ans=(ans+sum[v]*sum[u])%M;
        para[++cnt]=sz[v];
        sz[u]+=sz[v],sum[u]+=sum[v];
    }
    //cout<<u<<":\n";
    polymul(poly,para,1,cnt);//poly[1]=answer polynomial
    sum[u]+=calc(poly[1],cnt);

    unordered_map<int,LL> h;
    unordered_map<int,LL>::iterator it;
    for (int v:e[u]){
        if (v==fa) continue;

        it=h.find(sz[v]);
        if (it!=h.cend()){
            ans=(ans+sum[v]*it->second%M)%M;
            continue;
        }
        else{
            vector<LL> t(cnt+1),tmp(poly[1]);
            const LL isz=inv(sz[v]);
            for (i=cnt-1,t[cnt]=0; i>=0; i--)
            {
                t[i]=tmp[i+1]*isz%M;
                tmp[i]=(tmp[i]-t[i]+M)%M;
            }
            for (i=cnt; i; i--)
                t[i]=(t[i]+t[i-1]*(n-sz[u])%M)%M;

            const LL F=calc(t,cnt);
            ans=(ans+sum[v]*F%M)%M, h.insert(make_pair(sz[v],F));
        }
    }
}
int main()
{
    cin>>n>>k;
    if (k==1) {cout<<1ll*n*(n-1)/2%M; return 0;}
    for (i=1; i<n; i++){
        cin>>x>>y;
        e[x].push_back(y), e[y].push_back(x);
    }

    dfs(1,0);
    cout<<ans;
	return 0;
}


#include <bits/stdc++.h>
#pragma GCC optimize(3)
#define N 100005
using namespace std;

typedef long long LL;
const LL M=998244353;
const LL g=3;

void exgcd(LL a,LL b,LL &x,LL &y){
	if (b==0) {x=1,y=0; return;}
	exgcd(b,a%b,x,y);
	LL t=x; x=y, y=t-(a/b)*y;
}
LL inv(LL a){
    LL x,y; exgcd(a,M,x,y);
    return (x+M)%M;
}
LL Qpow(LL x,LL y){//x^y
    if (y==0) return 1;
    LL t=Qpow(x,y/2);
    return (y&1)?t*t%M*x%M:t*t%M;
}

void NTT(vector<LL> &a,vector<LL> &p,LL n,bool INV)
{
    int i,j,k,rev;
    const LL ig=inv(g),in=inv(n);
    for (i=0; i<n; i++){
        rev=0,k=1;
        while (k<n) rev=(rev<<1)+((i&k)>0),k<<=1;
        p[rev]=a[i];
    }

    for (k=1; k<n; k<<=1)
    {
        LL unit=INV?Qpow(ig,(M-1)/(k*2)):Qpow(g,(M-1)/(k*2));
        for (i=0; i<n; i+=k*2)
        {
            LL omega=1;
            for (j=i; j<i+k; j++,omega=omega*unit%M){
                LL x=p[j],y=p[j+k]*omega%M;
                p[j]=(x+y)%M, p[j+k]=(x-y+M)%M;
            }
        }
    }

    if (INV)
        for (i=0; i<n; i++) p[i]=p[i]*in%M;
}

void mul(vector<LL> &A,int dega,vector<LL> B,int degb)//A <- A*B
{
    int bit=1,deg=dega+degb;
    while (bit<deg+1) bit<<=1;

    A.resize(bit,0),B.resize(bit,0);
    vector<LL> pA(bit),pB(bit);
    NTT(A,pA,bit,false), NTT(B,pB,bit,false);
    for (int i=0; i<bit; i++) pA[i]=pA[i]*pB[i]%M;
    NTT(pA,A,bit,true);
}
void polymul(vector<LL> *poly,int *para,int l,int r)//(1+para_1*x)(1+para_2*x)...(1+para_m*x)
{
    if (l>r) return;
    if (l==r) {poly[l].resize(2),poly[l][0]=1,poly[l][1]=para[l]; return;}
    int mid=(l+r)/2;
    polymul(poly,para,l,mid), polymul(poly,para,mid+1,r);
    mul(poly[l],mid-l+1,poly[mid+1],r-mid);
}

int n,m,i,j,k,x,y,sz[N/2];
vector<int> e[N/2];
LL sum[N/2],fact[N/2],ans=0;

LL calc(const vector<LL> &poly,int deg){
    if (deg==0) return 1;
    LL tmp=0,permutation=1;
    for (int i=0; i<=k&&i<=deg; i++)
        tmp=(tmp+poly[i]*permutation%M)%M,permutation=permutation*(k-i)%M;
    //cout<<endl<<tmp<<endl;system("pause");
    return tmp;
}
void dfs(int u,int fa)
{
    const int deg=e[u].size();
    vector<LL> poly[deg+5];
    int i,j,para[deg+5]={0},cnt=0;

    sum[u]=0,sz[u]=1;
    for (int v:e[u]){
        if (v==fa) continue;
        dfs(v,u);

        ans=(ans+sum[v]*sum[u])%M;
        para[++cnt]=sz[v];
        sz[u]+=sz[v],sum[u]+=sum[v];
    }
    //cout<<u<<":\n";
    polymul(poly,para,1,cnt);//poly[1]=answer polynomial
    sum[u]+=calc(poly[1],cnt);

    unordered_map<int,LL> h;
    unordered_map<int,LL>::iterator it;
    for (int v:e[u]){
        if (v==fa) continue;

        it=h.find(sz[v]);
        if (it!=h.cend()){
            ans=(ans+sum[v]*it->second%M)%M;
            continue;
        }
        else{
            vector<LL> t(cnt+1),tmp(poly[1]);
            const LL isz=inv(sz[v]);
            for (i=cnt-1,t[cnt]=0; i>=0; i--)
            {
                t[i]=tmp[i+1]*isz%M;
                tmp[i]=(tmp[i]-t[i]+M)%M;
            }
            for (i=cnt; i; i--)
                t[i]=(t[i]+t[i-1]*(n-sz[u])%M)%M;

            const LL F=calc(t,cnt);
            ans=(ans+sum[v]*F%M)%M, h.insert(make_pair(sz[v],F));
        }
    }
}
int main()
{
    cin>>n>>k;
    if (k==1) {cout<<1ll*n*(n+1)/2%M; return 0;}
    for (i=1; i<n; i++){
        cin>>x>>y;
        e[x].push_back(y), e[y].push_back(x);
    }

    dfs(1,0);
    cout<<ans;
	return 0;
}


#include<bits/stdc++.h>
#define maxn 262144
#define Mod 998244353
#define ll long long
using namespace std;
inline int read(){
	int x=0,c;while(!isdigit(c=getchar()));
	while(x=x*10+c-'0',isdigit(c=getchar()));
	return x;
}
struct edge{
	int to,next;
}e[maxn<<1];
int cnt,last[maxn];
inline void insert(int x,int y){
	e[++cnt].to=y;e[cnt].next=last[x];last[x]=cnt;
}
typedef vector<int>	poly;
inline int ksm(int x,int y){
	int res=1;
	while(y){
		if(y&1)res=1ll*res*x%Mod;
		x=1ll*x*x%Mod;y>>=1;
	}return res;
}int c[maxn];
inline void NTT(int *a,int n,int f){
	for(int i=0;i<n;i++)if(i<c[i])swap(a[i],a[c[i]]);
	for(int i=1;i<n;i<<=1){
		int wn=ksm(3,Mod-1+f*(Mod-1)/(i<<1));
		for(int j=0,p=i<<1;j<n;j+=p){int w=1;
			for(int k=0;k<i;k++,w=1ll*w*wn%Mod){
				int x=a[j+k],y=1ll*w*a[j+k+i]%Mod;
				a[j+k]=(x+y)%Mod;a[j+k+i]=(x-y+Mod)%Mod;
			}
		}
	}if(f==1)return;int tmp=ksm(n,Mod-2);for(int i=0;i<n;i++)a[i]=1ll*a[i]*tmp%Mod;
}
inline poly operator*(const poly &p,const poly &q){
	static int a[maxn],b[maxn];int N=1;
	for(;N<q.size()+p.size();N<<=1);for(int i=0;i<N;i++)c[i]=(c[i>>1]>>1)|((i&1)*(N>>1));
	for(int i=0;i<p.size();i++)a[i]=p[i];for(int i=p.size();i<N;i++)a[i]=0;
	for(int i=0;i<q.size();i++)b[i]=q[i];for(int i=q.size();i<N;i++)b[i]=0;
	NTT(a,N,1);NTT(b,N,1);
	for(int i=0;i<N;i++)a[i]=1ll*a[i]*b[i]%Mod;NTT(a,N,-1);poly res(p.size()+q.size()-1);
	for(int i=0;i<q.size()+p.size()-1;i++)res[i]=a[i];
	return res;
}
struct node{int x,y;}t[maxn];int ans;
inline bool cmp(node x,node y){return x.x<y.x;}
inline void add(int &x,int y){x+=y;x-=x>=Mod?Mod:0;}
inline poly solve(int l,int r){
	if(l==r){poly res(2);res[0]=1;res[1]=t[l].x;return res;}int mid=(l+r)>>1;
	return solve(l,mid)*solve(mid+1,r);
}
int sz[maxn],tot,f[maxn],s[maxn],n,k,fac[maxn],inv[maxn];
inline int calc(const poly &a,int n=0){
	int res=0;for(int i=0;i<min(k,n?n+1:(int)a.size());i++)add(res,1ll*a[i]*fac[k]%Mod*inv[k-i]%Mod);return res;
}
inline void check(const poly &a){
	printf("%d ",a.size());for(int i=0;i<a.size();i++)printf("%d ",a[i]);printf("\n");
}
void dfs(int x,int fa){
	sz[x]=1;
	for(int j=last[x];j;j=e[j].next){
		int y=e[j].to;if(y==fa)continue;dfs(y,x);sz[x]+=sz[y];add(s[x],s[y]);
	}tot=0;
	for(int j=last[x];j;j=e[j].next){
		int y=e[j].to;if(y==fa)continue;t[++tot].x=sz[y];t[tot].y=s[y];
	}
	if(!tot){f[x]=s[x]=1;return;}sort(t+1,t+tot+1,cmp);poly res=solve(1,tot),b=res;
//	printf("%d\n",x);
//	for(int i=1;i<=tot;i++)printf("%d %d\n",t[i].x,t[i].y);
//	check(res);
	f[x]=calc(res);add(s[x],f[x]);b.push_back(0);
	res.push_back(0);for(int i=res.size()-1;i>=1;i--)add(res[i],1ll*res[i-1]*(n-sz[x])%Mod);int w=0;
	for(int i=1;i<=tot;i++){
		if(t[i].x==t[i-1].x){add(ans,1ll*w*t[i].y%Mod);continue;}
		for(int j=0;j<=tot+1;j++)b[j]=res[j];
		for(int j=1;j<=tot+1;j++)add(b[j],Mod-1ll*b[j-1]*t[i].x%Mod);
		w=calc(b,tot);add(ans,1ll*w*t[i].y%Mod);
	}
}
void Dfs(int x,int fa){
	int w=0;
	for(int j=last[x];j;j=e[j].next){
		int y=e[j].to;if(y==fa)continue;
		Dfs(y,x);add(ans,1ll*w*s[y]%Mod);
		add(w,s[y]);
	}
}
int main(){
	n=read();k=read();fac[0]=1;for(int i=1;i<=k;i++)fac[i]=1ll*fac[i-1]*i%Mod;inv[k]=ksm(fac[k],Mod-2);
	for(int i=k;i>=1;i--)inv[i-1]=1ll*inv[i]*i%Mod;
	for(int i=1;i<n;i++){
		int x=read(),y=read();
		insert(x,y);insert(y,x);
	}
	dfs(1,0);Dfs(1,0);printf("%d\n",ans);return 0;
}