For this Question: You are given a tree consisting of N vertices.

We define a K- star as a pair of:
- a center vertex C 
- an unordered K- tuple of corner vertices ( v<sub>1</sub>,..... , v<sub>K</sub>)

which satisfies the following conditions for all (i, j) such that 1 <= i, j <= K and i != j:

- d(C, v<sub>i</sub>) = d(C, v<sub>j</sub>) != 0
- 2 * d(C, v<sub>i</sub>) = d(v<sub>i</sub>, v<sub>j</sub>)

Here d(x, y) denotes the distance between nodes x and y on the given tree.

Given the value K, count the number of K- stars in the given tree. Since this number may be huge, print the answer modulo 998244353.The first line of the input contains two integers: N, the number of nodes in the tree; and K, the star parameter.

It is followed by N-1 lines each containing two integers, u<sub>i</sub> and v<sub>i</sub>, the endpoints of an edge of the tree. It is guaranteed that the given edges form a tree.

<b>Constraints: </b>
3 <= N <= 5000
2 <= K <= N-1
1 <= u<sub>i</sub>, v<sub>i</sub> <= NPrint a single integer, the number of K- stars in the given tree, modulo 998244353.Sample Input 1:
4 3
1 2
1 3
1 4

Sample Output 1:
1

Sample Input 2:
7 2
1 2
1 3
2 4
2 5
3 6
3 7

Sample Output 2:
11

Sample Explanations:

In the first sample, there is exactly 1 3- star in the tree, centered at node 1 and with all other nodes being the corner vertices of the star.

In the second sample, there are five 2- stars centered at node 1, and three each centered on nodes 2 and 3. So, answer is 5 + 3 + 3 = 11., I have written this Solution Code: //HEADER FILES AND NAMESPACES

#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>  
#include <ext/pb_ds/tree_policy.hpp>   
// #include <sys/resource.h>
using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template <typename T>
using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>; 

// PRAGMAS (do these even work?)
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,avx,avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")

// DEFINE STATEMENTS
const long long infty = 1e18;
#define num1 1000000007
#define num2 998244353
#define REP(i,a,n) for(ll i=a;i<n;i++)
#define REPd(i,a,n) for(ll i=a; i>=n; i--)
#define pb push_back
#define pob pop_back
#define f first
#define s second
#define fix(f,n) std::fixed<<std::setprecision(n)<<f
#define all(x) x.begin(), x.end()
#define M_PI 3.14159265358979323846
#define epsilon (double)(0.000000001)
#define popcount __builtin_popcountll
#define fileio(x) freopen("input.txt", "r", stdin); freopen(x, "w", stdout);
#define out(x) cout << ((x) ? "Yes\n" : "No\n")
#define sz(x) x.size()
#define start_clock() auto start_time = std::chrono::high_resolution_clock::now();
#define measure() auto end_time = std::chrono::high_resolution_clock::now(); cerr << (end_time - start_time)/std::chrono::milliseconds(1) << "ms" << endl;


typedef long long ll;
typedef long double ld;
typedef vector<long long> vll;
typedef pair<long long, long long> pll;
typedef vector<pair<long long, long long>> vpll;
typedef vector<int> vii;

// DEBUG FUNCTIONS 
#ifdef LOCALY

template<typename T>
void __p(T a) {
	cout<<a;
}
template<typename T, typename F>
void __p(pair<T, F> a) {
	cout<<"{";
	__p(a.first);
	cout<<",";
	__p(a.second);
	cout<<"}";
}
template<typename T>
void __p(std::vector<T> a) {
	cout<<"{";
	for(auto it=a.begin(); it<a.end(); it++)
		__p(*it),cout<<",}"[it+1==a.end()];
}
template<typename T>
void __p(std::set<T> a) {
	cout<<"{";
	for(auto it=a.begin(); it!=a.end();){
		__p(*it); 
		cout<<",}"[++it==a.end()];
	}

}
template<typename T>
void __p(std::multiset<T> a) {
	cout<<"{";
	for(auto it=a.begin(); it!=a.end();){
		__p(*it); 
		cout<<",}"[++it==a.end()];
	}
}
template<typename T, typename F>
void __p(std::map<T,F> a) {
	cout<<"{\n";
	for(auto it=a.begin(); it!=a.end();++it)
	{
		__p(it->first);
		cout << ": ";
		__p(it->second);
		cout<<"\n";
	}
	cout << "}\n";
}

template<typename T, typename ...Arg>
void __p(T a1, Arg ...a) {
	__p(a1);
	__p(a...);
}
template<typename Arg1>
void __f(const char *name, Arg1 &&arg1) {
	cout<<name<<" : ";
	__p(arg1);
	cout<<endl;
}
template<typename Arg1, typename ... Args>
void __f(const char *names, Arg1 &&arg1, Args &&... args) {
	int bracket=0,i=0;
	for(;; i++)
		if(names[i]==','&&bracket==0)
			break;
		else if(names[i]=='(')
			bracket++;
		else if(names[i]==')')
			bracket--;
	const char *comma=names+i;
	cout.write(names,comma-names)<<" : ";
	__p(arg1);
	cout<<" | ";
	__f(comma+1,args...);
}
#define trace(...) cout<<"Line:"<<__LINE__<<" ", __f(#__VA_ARGS__, __VA_ARGS__)
#else
#define trace(...)
#define error(...)
#endif

// DEBUG FUNCTIONS END 

// CUSTOM HASH TO SPEED UP UNORDERED MAP AND TO AVOID FORCED CLASHES
struct custom_hash {
    static uint64_t splitmix64(uint64_t x) {
        x += 0x9e3779b97f4a7c15;
        x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
        x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
        return x ^ (x >> 31);
    }
 
    size_t operator()(uint64_t x) const {
        static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
        return splitmix64(x + FIXED_RANDOM);
    }
};

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());  // FOR RANDOM NUMBER GENERATION

ll mod_exp(ll a, ll b, ll c)
{
	ll res=1;   a=a%c;
	while(b>0)
	{
		if(b%2==1)
			res=(res*a)%c;
		b/=2;
		a=(a*a)%c;
	}
	return res;
}
ll mymod(ll a,ll b)
{
	return (((a = a%b) < 0) ? a + b : a);
}
ll gcdExtended(ll,ll,ll *,ll *);
ll modInverse(ll a, ll m) 
{ 
		ll x, y; 
		ll g = gcdExtended(a, m, &x, &y); 
		g++;   //this line was added just to remove compiler warning
		ll res = (x%m + m) % m;
		return res;
} 
ll gcdExtended(ll a, ll b, ll *x, ll *y) 
{ 
		if (a == 0) 
		{ 
				*x = 0, *y = 1; 
				return b; 
		} 
		ll x1, y1; 
		ll gcd = gcdExtended(b%a, a, &x1, &y1);
		*x = y1 - (b/a) * x1; 
		*y = x1; 
		return gcd; 
}


//Dont forget to reset MOD if some other MOD is needed
const ll MOD = num2;

//Comment the line above and uncomment the line below if problem requires more than 1 MOD
//After uncommenting the below line, declaration of Mint becomes [ Mint<mod> M; ]

//template<ll MOD>
class Mint
{
	//WARNING:
	//Be very careful not to use two Mints with different mods for any operation
	//No guarantee of behavior in this case
	public:
	ll val;
	static ll mod_exp(ll a, ll b){ ll res=1;   a=a%MOD; while(b>0){ if(b%2==1) res=(res*a)%MOD; b/=2; a=(a*a)%MOD; } return res; }
	static ll gcdExtended(ll a, ll b, ll *x, ll *y) { if (a == 0) { *x = 0, *y = 1; return b; } ll x1, y1; ll gcd = gcdExtended(b%a, a, &x1, &y1);*x = y1 - (b/a) * x1; *y = x1; return gcd; }
	static ll modInverse(ll a) { ll x, y; 	ll g = gcdExtended(a, MOD, &x, &y); g++; ll res = (x%MOD);	if(res < 0) res += MOD;	return res;} 
	Mint(){	val = 0;} 
	Mint(ll x){	val = x%MOD;	if(val < 0) val += MOD;}
	Mint& operator +=(const Mint &other){	val += other.val;	if(val >= MOD) val -= MOD; return (*this); }
	Mint& operator -=(const Mint &other){   val -= other.val;if(val < 0) val += MOD;  return (*this); }
	Mint& operator *=(const Mint &other){	val = (val * other.val)%MOD; return (*this); }
	Mint& operator /=(const Mint &other){	val = (val * modInverse(other.val)) % MOD; return (*this); }
	Mint& operator =(const Mint &other) { 	val = other.val; return (*this); }
	Mint operator +(const Mint &other) const {	return Mint(*this) += other; }
	Mint operator -(const Mint &other) const {	return Mint(*this) -= other; }
	Mint operator *(const Mint &other) const {	return Mint(*this) *= other; }
	Mint operator /(const Mint &other) const {	return Mint(*this) /= other; }
	bool operator ==(const Mint &other) const {   return val == other.val; }

	Mint operator ++() { ++val; if(val == MOD) val = 0; return (*this); }
	Mint operator ++(int) { val++; if(val == MOD) val = 0; return Mint(val-1); }
	Mint operator --() { --val; if(val == -1) val = MOD-1; return (*this); }
	Mint operator --(int) { val--; if(val == -1) val = MOD-1; return Mint(val+1); }

	// ^ has very low precedence, careful!!

	template<typename T>
	Mint& operator ^=(const T &other){   val = mod_exp(val, other); return (*this); }
	template<typename T>
	Mint operator ^(const T &other) const {  return Mint(*this) ^= other; }

	Mint& operator ^=(const Mint &other){   val = mod_exp(val, other.val); return (*this); }
	Mint operator ^(const Mint &other) const {  return Mint(*this) ^= other; }

	template<typename T>
	explicit operator T() {	return (T)val; }
	template<typename T>
	friend Mint operator +(T other, const Mint &M){	return Mint(other) + M; }
	template<typename T>
	friend Mint operator -(T other, const Mint &M){	return Mint(other) - M; }
	template<typename T>
	friend Mint operator *(T other, const Mint &M){	return Mint(other) * M; }
	template<typename T>
	friend Mint operator /(T other, const Mint &M){	return Mint(other) / M; }
	template<typename T>
	friend Mint operator ^(T other, const Mint &M){	return Mint(other) ^ M; }


	friend std::ostream &operator << (std::ostream &output, const Mint &M){  return output << M.val; }
	friend std::istream &operator >> (std::istream &input, Mint &M) { input >> M.val;	M.val %= MOD;	return input;}
};

const int MAXN = 5e3+5;
Mint facto[MAXN], invfacto[MAXN];

void pre()
{
	facto[0] = 1;
	for(int i=1; i<MAXN; i++) facto[i] = i*facto[i-1];
	invfacto[MAXN-1] = 1/facto[MAXN-1];
	for(int i=MAXN-2; i>=0; i--) invfacto[i] = (i+1)*invfacto[i+1];
}

Mint nCr(ll a, ll b)
{
	if(b < 0 || b > a) return Mint(0);
	return (facto[a]*invfacto[b]*invfacto[a-b]);
}


struct Graph
{
	vector<vector<int>> adj;
	Graph(int n)
	{
		adj.resize(n+1);
	}	
	void add_edge(int a, int b, bool directed = false)
	{
		adj[a].pb(b);
		if(!directed) adj[b].pb(a);
	}
	Mint solve(int root, int k)
	{
		Mint ways = 0;
		vector<vector<Mint>> parts(adj.size());
		vector<bool> vis(adj.size(), false);
		vis[root] = true;
		for(auto &st: adj[root])
		{
			queue<pair<int, int>> q;
			q.push({st, 0});
			vis[st] = true;
			int last = -1;
			while(!q.empty())
			{
				pair<int, int> f = q.front();
				if(f.second != last) {
					parts[f.second].pb(1);
				}
				else {
					parts[f.second].back()++;
				}
				last = f.second;
				q.pop();
				for(auto &p: adj[f.first]) {
					if(!vis[p]) {
						q.push({p, f.second+1});
						vis[p] = true;
					}	
				}
			}
		}

		for(int i=0; i<parts.size(); i++) {
			if(parts[i].size() >= k) {
				vector<vector<Mint>> dp(parts[i].size(), vector<Mint>(k+1));
				dp[0][0] = 1;
				dp[0][1] = parts[i][0];
				for(int j=1; j<parts[i].size(); j++)
				{
					dp[j][0] = 1;
					for(int x = 1; x <= k; x++) {
						//dont take current element
						dp[j][x] += dp[j-1][x];
						//take it
						dp[j][x] += dp[j-1][x-1] * parts[i][j];
					}
				}

				// trace(dp);
				ways += dp[parts[i].size()-1][k];
			}
			else {
				break;
			}
		}

		return ways;
	}
};


int main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	ll n, k;
	cin >> n >> k;
	Mint ans = 0;
	Graph G(n);
	REP(i, 1, n)
	{
		ll a, b;
		cin >> a >> b;
		G.add_edge(a, b);
	}

	REP(i, 1, n+1)
	{
		if(G.adj[i].size() >= k) {
			ans += G.solve(i, k);
		}	
	}

	cout << ans << "\n";

	return 0;
}

/*
1. Check borderline constraints. Can a variable you are dividing by be 0?
2. Use ll while using bitshifts
3. Do not erase from set while iterating it
4. Initialise everything
5. Read the task carefully, is something unique, sorted, adjacent, guaranteed??
6. DO NOT use if(!mp[x]) if you want to iterate the map later
7. Are you using i in all loops? Are the i's conflicting?
*/ 



, In this Programming Language: C++, Now tell me if this Code is compilable or not?