#include<bits/stdc++.h>
//#define int long long
#define fi first
#define se second
//#define file(...) freopen("##__VA_ARGS__.in","r",stdin);freopen("##__VA_ARGS__.out","w",stdout)
//#define outfile(...) freopen("##__VA_ARGS__.out","w",stdout)
//#define infile(...) freopen("##__VA_ARGS__.in","r",stdin);
//#define datafile(...) freopen("##__VA_ARGS__.in","w",stdout)
#define debug(...) fprintf(stderr,##__VA_ARGS__)
//#define printf(...) fprintf(stdout,##__VA_ARGS)
template<typename T,typename I>
#define heap(T) std::priority_queue<T>
#define umap(T,I) std::unordered_map<T,I>
#define pii(T,I) std::pair<T,I>
#define map(T,I) std::map<T,I>
#define vector(T) std::vector<T>
#define stack(T) std::stack<T>
using ll=long long;
using i128=__int128;
using ull=unsigned long long;
template<typename T>
inline void read(T &x){
x=0;
char c=getchar();
int f=1;
while(c<'0'||c>'9'){
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(int)(c-'0'),c=getchar();
x*=f;
}
template<typename T,typename I>
void chkmin(T &a,I b){
a=std::min(a,b);
}
template<typename T,typename I>
void chkmax(T &a,I b){
a=std::max(a,b);
}
//随机数部分
std::mt19937 rnd(std::chrono::steady_clock::now().time_since_epoch().count());
template<typename T>
int getgen(T L,T R){
return rnd()%(R-L+1)+L;
}
const double eps=1e-6,pi=std::acos(-1);
const int inf=1e9,MOD1=998244353,MOD2=1e9+7,MOD3=2147483579,MOD4=19198111;
const __int128 inf128=1e30;
bool Mbe;
stack(char) st;
template<typename T>
void print(T x){
while(st.size()) st.pop();
if(x==0) st.push('0');
if(x<0) putchar('-'),x=-x;
while(x) st.push((char)('0'+x%10)),x/=10;
while(st.size()) putchar(st.top()),st.pop();
}
template<typename T>
void printsp(T x){
print(x);
putchar(' ');
}
template<typename T>
void println(T x){
print(x);
putchar('\n');
}
const int maxn=1e5+10,maxk=110;
std::vector<int>a[maxn];
int n,k,dp[maxn][maxk][2][2],sz[maxn];
void dfs(int p,int fa){
sz[p]=1;
// for(int i:a[p]){
// if(i==fa) continue;
// dfs(i,p);
// sz[p]+=sz[i];
// }
// bool in=0;
dp[p][0][0][0]=dp[p][1][0][1]=1;
for(int i:a[p]){
if(i==fa) continue;
dfs(i,p);
sz[p]+=sz[i];
// in=1;
for(int j=std::min(k,sz[p]);j>=0;j--){
int s1,s2,s3,s4;
s1=s2=s3=s4=0;
for(int k=std::max(0,j-sz[i]);k<=j;k++){
// debug("p=%lld i=%lld j=%lld k=%lld 00=%lld 01=%lld 10=%lld 11=%lld\n",p,i,j,k,dp[i][j-k][0][0],dp[i][j-k][0][1],dp[i][j-k][1][0],dp[i][j-k][1][1]);
s1+=1ll*dp[p][k][0][0]*dp[i][j-k][1][0]%MOD2;
if(s1>=MOD2) s1-=MOD2;
s2+=1ll*dp[p][k][0][1]*((dp[i][j-k][0][0]+dp[i][j-k][1][0])%MOD2)%MOD2;
if(s2>=MOD2) s2-=MOD2;
s3+=(1ll*dp[p][k][0][0]*dp[i][j-k][1][1]%MOD2+1ll*dp[p][k][1][0]*((dp[i][j-k][1][0]+dp[i][j-k][1][1])%MOD2)%MOD2)%MOD2;
if(s3>=MOD2) s3-=MOD2;
s4+=(1ll*dp[p][k][0][1]*((dp[i][j-k][0][1]+dp[i][j-k][1][1])%MOD2)%MOD2+1ll*dp[p][k][1][1]*(((dp[i][j-k][1][1]+dp[i][j-k][1][0])%MOD2+(dp[i][j-k][0][1]+dp[i][j-k][0][0])%MOD2)%MOD2)%MOD2)%MOD2;
if(s4>=MOD2) s4-=MOD2;
}
dp[p][j][0][0]=s1,dp[p][j][0][1]=s2,dp[p][j][1][0]=s3,dp[p][j][1][1]=s4;
// println(s4);
// println(s2);
}
}
// for(int j=0;j<=std::min(k,sz[p]);j++)
// for(int p1=0;p1<=1;p1++)
// for(int p2=0;p2<=1;p2++)
// debug("i=%lld j=%lld p1=%lld p2=%lld dp=%lld\n",p,j,p1,p2,dp[p][j][p1][p2]);
}
bool Men;
signed main(){
// file();
assert(1);
debug("%.8lfMB\n",(&Mbe-&Men)/1048576.0);
read(n),read(k);
for(int i=1;i<n;i++){
int u,v;
read(u),read(v);
a[u].push_back(v),a[v].push_back(u);
}
dfs(1,0);
println((dp[1][k][1][0]+dp[1][k][1][1])%MOD2);
debug("%.8lfms\n",1e3*clock()/CLOCKS_PER_SEC);
return 0;
}
/*
Good luck
-std=c++14 -Wall -O2 -Wextra -Wl,-stack=2147483647
*/
/*
dp[i][0/1][j] 代表 i 的子树中放了 j 个监听器 i 是否被监听的方案数
dp[i][0/1][0/1][j] 代表 i 的子树中放了 j 个监听器 i 上是否有 i 是否被监听的方案数
转移不太好转移
dp[i][j][0/1] 代表 i 的子树中 j 个监听器 i 是否被监听的方案数
实际上并不能算一个背包
0 的转移 儿子必须被监听 且儿子上不能有监听器
回到那个状态设计
0 0 的转移 儿子 1 0 自己不放监听器
0 1 的转移 儿子 0 0 或 1 0 自己放监听器
1 0 的转移 必须有一个儿子放监听器且自己不能放监听器
即必须有一个儿子是 1 1 其余可以是 1 0 或者 1 1
1 1 的转移 必须有一个儿子放监听器且自己放监听器
即必须有一个儿子是 0 1 或 1 1 其余可以随便
1 0 的转移中考虑枚举最后一个 1 1 在哪 进行转移
1 1 的转移枚举最后一个 0 1 或 1 1 在哪 讨论是 0 1 还是 1 1 进行转移
*/
一直 TLE on#4