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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define MT make_tuple
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second

#define DUMP(x) cout<<#x<<":"<<(x)<<endl
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class T>
istream& operator>>(istream& is, vector<T>& xs){
  for(auto& x: xs)
	is >> x;
  return is;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
ostream& operator<<(ostream& os, const vector<T>& xs){
  for(unsigned int i=0;i<xs.size();++i)
	os << (i?" ":"") << xs[i];
  return os;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}
void debug(istringstream&){}
template <char sep=',', class Head, class... Tail>
void debug(istringstream& iss, Head&& head, Tail&&... tail)
{
  string name;
  getline(iss, name, ',');
  cout << sep << name << "=" << head;
  debug(iss, forward<Tail>(tail)...);
}
#define DEBUG(...) \
  do{ \
    istringstream ss(#__VA_ARGS__); \
    debug<' '>(ss, __VA_ARGS__); \
    cout<<endl; \
  }while(0)


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 998244353;


const int MAXU = 100000 + 10;
const int MAXK = 300 + 10;
LL dp[2][MAXU][MAXK];
int sz[MAXU];

void add(LL& x, LL y){
    x += y;
    if(x >= MOD) x -= MOD;
}


LL solve(VVI& G, int K, int u, int p){
  sz[u] = 1;

  int ub = 2;
  VL nouse_crt(ub);
  VL use_crt(ub);
  nouse_crt[0] = 1;
  use_crt[1] = 1;

  for(int to : G[u]){
    if(to == p) continue;
    solve(G, K, to, u);

    int ksum = min(K, sz[u]);
    ub = min(K+10, ksum+sz[to]+2);
    VL nouse_nxt(ub);
    VL use_nxt(ub);

    for(int k1=0;k1<=ksum;++k1){
      for(int k2=0;k2<=sz[to] && k1+k2<=K+1;++k2){
        add(nouse_nxt[k1+k2], nouse_crt[k1] * dp[0][to][k2] % MOD);
        if(k2) add(nouse_nxt[k1+k2], nouse_crt[k1] * dp[1][to][k2] % MOD);

        add(use_nxt[k1+k2], use_crt[k1] * dp[0][to][k2] % MOD);
        if(k2) add(use_nxt[k1+k2-1], use_crt[k1] * dp[1][to][k2] % MOD);
        if(k2) add(use_nxt[k1+k2], use_crt[k1] * dp[1][to][k2] % MOD);
      }
    }
    
    sz[u] += sz[to];
    swap(nouse_crt, nouse_nxt);
    swap(use_crt, use_nxt);
  }

  REP(kk,ub){
    dp[0][u][kk] = nouse_crt[kk];
    dp[1][u][kk] = use_crt[kk];
  }

/*
  DEBUG(u);
  REP(i,2){
    cout << "use = " << i << endl;
    REP(kk,K+1){ cout << dp[i][u][kk] << " ";}
    cout << endl;
  }
  cout << "=================" << endl;
*/
  return (dp[0][u][K] + dp[1][u][K]) % MOD;
}


int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N, K;
  cin >> N >> K;
  VVI G(N);
  REP(i,N-1){
    int u, v;
    cin >> u >> v;
    --u;
    --v;
    G[u].PB(v);
    G[v].PB(u);
  }

  cout << solve(G, K, 0, -1) << endl;

  return 0;
}


