//多练，就是多练
#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<string>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<cstring>
#include<unordered_map>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const ll mod=998244353;
vector<int>e[5010];
ll dp[5010][5010];
int n,k;
int dfs(int u,int fa)
{
    dp[u][0]=1;
    int h=0;    //存已经遍历的子节点中最高的高度
    for(auto v:e[u])
    {
        if(v!=fa) 
        {
            int sh=dfs(v,u);  //子节点高度
            vector<int>temp(max(h,sh+1)+1);
            for(int i=0;i<=h;i++)
            {
                for(int j=0;j<=sh;j++)
                {
                    if(i+j+1<=k) temp[max(i,j+1)]=(temp[max(i,j+1)]+dp[u][i]*dp[v][j]%mod)%mod;
                    if(i<=k&&j<=k) temp[i]=(temp[i]+dp[u][i]*dp[v][j]%mod)%mod;
                }
            }
            h=max(h,sh+1);
            for(int i=0;i<=h;i++)
            {
                dp[u][i]=temp[i];
            }
        }
    }
    return h;
}
void solve(ll T)
{
    cin>>n>>k;
    for(int i=1;i<n;i++)
    {
        int u,v;
        cin>>u>>v;
        e[u].push_back(v);
        e[v].push_back(u);
    }
    ll ans=0;
    dfs(1,-1);
    // for(int i=1;i<=n;i++)
    // {
    //     for(int j=0;j<=k;j++)
    //     {
    //         cout<<dp[i][j]<<" ";
    //     }
    //     cout<<endl;
    // }
    for(int i=0;i<=k;i++)
    {
        ans=(ans+dp[1][i])%mod;
    }
    cout<<ans<<endl;
}
//#define ONLINE_JUDGE
signed main()
{
    #ifndef ONLINE_JUDGE
    freopen("lotato.in","r",stdin);
    freopen("lotato.out","w",stdout);
    #endif
    int t=1;
    //scanf("%d",&t);
    for(int i=1;i<=t;i++)
    {
        solve(i);
    }
    return 0;
} 