#include<bits/stdc++.h>

using namespace std;
#define For(i,l,r) for (int i = l; i <= r; ++i)
#define Cor(i,l,r) for (int i = l; i >= r; --i)
#define next __next__

const int MaxN = 222222;
int v[MaxN], next[MaxN], h[MaxN], tot;
void add(int b, int e) {
	v[++tot] = e; next[tot] = h[b]; h[b] = tot;
	v[++tot] = b; next[tot] = h[e]; h[e] = tot;
}

int id = 0;
int vis[MaxN], L[MaxN], R[MaxN], seq[MaxN], A[MaxN];
void dfs(int x) {
	vis[x] = true;
	seq[L[x] = ++id] = x;
	for (int z = h[x]; z; z = next[z]) if (!vis[v[z]]) {
		dfs(v[z]);
	}
	R[x] = id;
}

const int B = 62;
int BLK = 0;
int MOD;

struct TData {
	long long Mask[22];
	TData() {}
	void clear() { memset(Mask, 0, sizeof Mask); }
	void set(int x, long long val) {
		long long &S = Mask[x / B];
		x %= B;
		if (S >> x & 1) S -= 1LL << x;
		S |= val << x;
	}
	int get(int x) {
		return Mask[x / B] >> (x % B) & 1;
	}
	TData operator + (const TData &b) const {
		TData ret;
		memcpy(ret.Mask, Mask, sizeof Mask);
		For(i,0,BLK) ret.Mask[i] |= b.Mask[i];
		return ret;
	}
	TData move(int offset) {
		offset %= MOD;
		TData ret; ret.clear();
		for (int i = 0; i < MOD; ++i) {
			int t = (i + offset) % MOD;
			int nxt_i = i / B * B + B - 1;
			int nxt_t = t / B * B + B - 1;
			int inc = min(nxt_i - i, nxt_t - t) + 1;
			ret.Mask[nxt_t / B] |= (Mask[nxt_i / B] >> i % B & ((1LL << inc) - 1)) << (t % B);
			i += inc;
		}
		return ret;
	}
};

struct SegTreeNode {
	int l, r, offset;
	TData info;
	SegTreeNode() {}
	void init(int _l, int _r, int _val) {
		l = _l, r = _r;
		info.clear();
		info.set(_val % MOD, 1);
		offset = 0;
	}
	void make_add(int c) {
		(offset += c) %= MOD;
		info = info.move(c % MOD);
	}
}T[MaxN * 2];

struct SegmentTree {
	void push(int t) {
		if (T[t].offset) {
			if (T[t].l == T[t].r) return ;
			T[t + t].make_add(T[t].offset);
			T[t + t + 1].make_add(T[t].offset);
		}
	}
	void update(int t) {
		if (T[t].l == T[t].r) return ;
		T[t].info = T[t + t].info + T[t + t + 1].info;
	}
	void modify(int t, int l, int r, int val) {
		push(t);
		if (l <= T[t].l && T[t].r <= r) {
			T[t].make_add(val);
			return ;
		}
		int mid = (T[t].l + T[t].r) >> 1;
		if (l <= mid) modify(t + t, l, r, val);
		if (r > mid) modify(t + t + 1, l, r, val);
		update(t);
	}
	TData ask(int t, int l, int r) {
		push(t);
		if (l <= T[t].l && T[t].r <= r) {
			return T[t].info;
		}
		int mid = (T[t].l + T[t].r) >> 1;
		TData ret; ret.clear();
		if (l <= mid) ret = ret + ask(t + t, l, r);
		if (r > mid) ret = ret + ask(t + t + 1, l, r);
		update(t);
		return ret;
	}
	void build(int t, int l, int r, int *seq) {
		T[t].init(l, r, A[seq[l]]);
		if (l == r) return ;
		int mid = (l + r) >> 1;
		build(t + t, l, mid, seq);
		build(t + t + 1, mid + 1, r, seq);
		update(t);
	}
}Tab;

int n, Q;
int main() {
	cin >> n >> MOD;
	vector<int> primes;
	For(i,2,MOD) {
		bool valid = true;
		For(j,2,i - 1) if (i % j == 0) valid = false ;
		if (valid) primes.push_back(i);
	}

	BLK = (MOD + B - 1) / B;

	For(i,1,n) scanf("%d", &A[i]);
	For(i,1,n - 1) {
		int b, e;
		scanf("%d%d", &b, &e);
		add(b, e);
	}

	dfs(1);

	Tab.build(1, 1, n, seq);

	cin >> Q;
	For(i,1,Q) {
		int op, v, x;
		scanf("%d", &op);
		if (op == 1) {
			scanf("%d%d", &v, &x);
			Tab.modify(1, L[v], R[v], x);
		}
		if (op == 2) {
			scanf("%d", &v);
			TData ans = Tab.ask(1, L[v], R[v]);
			int num = 0;
			for (auto cand : primes) if (ans.get(cand) == 1) ++num;
			printf("%d\n", num);
		}
	}

	return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define For(i,l,r) for (int i = l; i <= r; ++i)
#define Cor(i,l,r) for (int i = l; i >= r; --i)
#define next __next__

const int MaxN = 222222;
int v[MaxN], next[MaxN], h[MaxN], tot;
void add(int b, int e) {
	v[++tot] = e; next[tot] = h[b]; h[b] = tot;
	v[++tot] = b; next[tot] = h[e]; h[e] = tot;
}

int id = 0;
int vis[MaxN], L[MaxN], R[MaxN], seq[MaxN], A[MaxN];
void dfs(int x) {
	vis[x] = true;
	seq[L[x] = ++id] = x;
	for (int z = h[x]; z; z = next[z]) if (!vis[v[z]]) {
		dfs(v[z]);
	}
	R[x] = id;
}

const int B = 62;
int BLK = 0;
int MOD;

struct TData {
	long long Mask[22];
	TData() {}
	void clear() { memset(Mask, 0, sizeof Mask); }
	void set(int x, long long val) {
		long long &S = Mask[x / B];
		x %= B;
		if (S >> x & 1) S -= 1LL << x;
		S |= val << x;
	}
	int get(int x) {
		return Mask[x / B] >> (x % B) & 1;
	}
	TData operator + (const TData &b) const {
		TData ret;
		memcpy(ret.Mask, Mask, sizeof Mask);
		For(i,0,BLK) ret.Mask[i] |= b.Mask[i];
		return ret;
	}
	TData move(int offset) {
		offset %= MOD;
		TData ret; ret.clear();
		for (int i = 0; i < MOD; ++i) {
			int t = (i + offset) % MOD;
			int nxt_i = min(MOD - 1, i / B * B + B - 1);
			int nxt_t = min(MOD - 1, t / B * B + B - 1);
			int inc = min(nxt_i - i, nxt_t - t) + 1;
			ret.Mask[nxt_t / B] |= (Mask[nxt_i / B] >> i % B & ((1LL << inc) - 1)) << (t % B);
			i += inc;
		}
		return ret;
	}
};

struct SegTreeNode {
	int l, r, offset;
	TData info;
	SegTreeNode() {}
	void init(int _l, int _r, int _val) {
		l = _l, r = _r;
		info.clear();
		info.set(_val % MOD, 1);
		offset = 0;
	}
	void make_add(int c) {
		(offset += c) %= MOD;
		info = info.move(c % MOD);
	}
}T[MaxN * 2];

struct SegmentTree {
	void push(int t) {
		if (T[t].offset) {
			if (T[t].l == T[t].r) return ;
			T[t + t].make_add(T[t].offset);
			T[t + t + 1].make_add(T[t].offset);
		}
	}
	void update(int t) {
		if (T[t].l == T[t].r) return ;
		T[t].info = T[t + t].info + T[t + t + 1].info;
	}
	void modify(int t, int l, int r, int val) {
		push(t);
		if (l <= T[t].l && T[t].r <= r) {
			T[t].make_add(val);
			return ;
		}
		int mid = (T[t].l + T[t].r) >> 1;
		if (l <= mid) modify(t + t, l, r, val);
		if (r > mid) modify(t + t + 1, l, r, val);
		update(t);
	}
	TData ask(int t, int l, int r) {
		push(t);
		if (l <= T[t].l && T[t].r <= r) {
			return T[t].info;
		}
		int mid = (T[t].l + T[t].r) >> 1;
		TData ret; ret.clear();
		if (l <= mid) ret = ret + ask(t + t, l, r);
		if (r > mid) ret = ret + ask(t + t + 1, l, r);
		update(t);
		return ret;
	}
	void build(int t, int l, int r, int *seq) {
		T[t].init(l, r, A[seq[l]]);
		if (l == r) return ;
		int mid = (l + r) >> 1;
		build(t + t, l, mid, seq);
		build(t + t + 1, mid + 1, r, seq);
		update(t);
	}
}Tab;

int n, Q;
int main() {
	cin >> n >> MOD;
	vector<int> primes;
	For(i,2,MOD) {
		bool valid = true;
		For(j,2,i - 1) if (i % j == 0) valid = false ;
		if (valid) primes.push_back(i);
	}

	BLK = (MOD + B - 1) / B;

	For(i,1,n) scanf("%d", &A[i]);
	For(i,1,n - 1) {
		int b, e;
		scanf("%d%d", &b, &e);
		add(b, e);
	}

	dfs(1);

	Tab.build(1, 1, n, seq);

	cin >> Q;
	For(i,1,Q) {
		int op, v, x;
		scanf("%d", &op);
		if (op == 1) {
			scanf("%d%d", &v, &x);
			Tab.modify(1, L[v], R[v], x);
		}
		if (op == 2) {
			scanf("%d", &v);
			TData ans = Tab.ask(1, L[v], R[v]);
			int num = 0;
			for (auto cand : primes) if (ans.get(cand) == 1) ++num;
			printf("%d\n", num);
		}
	}

	return 0;
}


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<iostream>
#define sig 26
#define maxn 110005
using namespace std;
int x[maxn],y[maxn],cnt;
vector<int >g[maxn];
void dfs(int u,int pa){
    x[u]=++cnt;
    int p=g[u].size();
    for(int i=0;i<p;i++){
        if(g[u][i]!=pa)
        dfs(g[u][i],u);
    }
    y[u]=cnt;
}
int b[maxn];
short a[maxn];
int vis[405][1005];
short w[405];
int l[405],r[405];
int to[maxn];
int m;
void merg(int le,int ri,int p){
    int x=to[le];
    int y=to[ri];
    if(x==y){
        for(int i=le;i<=ri;i++){
            vis[x][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[x][a[i]]++;
        }
    }
    else {
        for(int i=le;i<=r[x];i++){
            vis[x][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[x][a[i]]++;
        }
        for(int i=x+1;i<=y-1;i++){
            w[i]+=p;
            w[i]%=m;
        }
        for(int i=l[y];i<=ri;i++){
            vis[y][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[y][a[i]]++;
        }
    }
}
int query(int le,int ri,int p){
    int x=to[le];
    int y=to[ri];
    if(x==y){
        for(int i=le;i<=ri;i++){
            if((a[i]+w[x])%m==p){
                return 1;
            }
        }
    }
    else {
        for(int i=x+1;i<=y-1;i++){
            int q=(p-w[i])%m;
            q=(q+m)%m;
            if(vis[i][q]) return 1;
        }
        for(int i=le;i<=r[x];i++){
            if((a[i]+w[x])%m==p) return 1;
        }
        for(int i=l[y];i<=ri;i++){
            if((a[i]+w[y])%m==p) return 1;
        }
    }
    return 0;
}
int use[1005],t1,prim[1005];
void init(){
    for(int i=2;i<m;i++){
        if(!use[i]) prim[t1++]=i;
        for(int j=0;j<t1;j++){
            if(i*prim[j]>=m) break;
            use[i*prim[j]]=1;
            if(i%prim[j]==0) break;
        }
    }
}
int main()
{
    int i,j,n;
    cin>>n>>m;
    int p=sqrt(n*1.0);
    init();
    for(i=1;i<=n;i++) scanf("%d",&b[i]);
    for(i=1;i<n;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        g[a].push_back(b);
        g[b].push_back(a);
    }
    dfs(1,-1);
    for(i=1;i<=n;i++){
        b[i]%=m;
        a[x[i]]=b[i];
    }
    int tot=0;
    for(i=1;i<=n;i++){
        ++tot;
        l[tot]=i;
        int f=i,q=0;
        while(f<=n&&q<p){
            vis[tot][a[f]]++;
            to[f]=tot;
            f++;
            q++;
        }
        r[tot]=f-1;
        i=f-1;
    }
    int q;
    scanf("%d",&q);
    for(i=0;i<q;i++){
        int p;
        scanf("%d",&p);
        if(p==1){
            int u,v;
            scanf("%d%d",&u,&v);
            merg(x[u],y[u],v);
        }
        else{
            int u;
            scanf("%d",&u);
            int s=0;
            for(j=0;j<t1;j++){
                if(query(x[u],y[u],prim[j])) s++;
            }
            printf("%d\n",s);
        }
    }
}


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<iostream>
#define sig 26
#define maxn 110005
using namespace std;
int x[maxn],y[maxn],cnt;
vector<int >g[maxn];
void dfs(int u,int pa){
    x[u]=++cnt;
    int p=g[u].size();
    for(int i=0;i<p;i++){
        if(g[u][i]!=pa)
        dfs(g[u][i],u);
    }
    y[u]=cnt;
}
int b[maxn];
int a[maxn];
int vis[405][1005];
int w[405];
int l[405],r[405];
int to[maxn];
int m;
void merg(int le,int ri,int p){
    int x=to[le];
    int y=to[ri];
    if(x==y){
        for(int i=le;i<=ri;i++){
            vis[x][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[x][a[i]]++;
        }
    }
    else {
        for(int i=le;i<=r[x];i++){
            vis[x][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[x][a[i]]++;
        }
        for(int i=x+1;i<=y-1;i++){
            w[i]+=p;
            w[i]%=m;
        }
        for(int i=l[y];i<=ri;i++){
            vis[y][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[y][a[i]]++;
        }
    }
}
int query(int le,int ri,int p){
    int x=to[le];
    int y=to[ri];
    if(x==y){
        for(int i=le;i<=ri;i++){
            if((a[i]+w[x])%m==p){
                return 1;
            }
        }
    }
    else {
        for(int i=le;i<=r[x];i++){
            if((a[i]+w[x])%m==p) return 1;
        }
        for(int i=x+1;i<=y-1;i++){
            int q=(p-w[i])%m;
            q=(q+m)%m;
            if(vis[i][q]) return 1;
        }
        for(int i=l[y];i<=ri;i++){
            if((a[i]+w[y])%m==p) return 1;
        }
    }
    return 0;
}
int use[1005],t1,prim[1005];
void init(){
    for(int i=2;i<m;i++){
        if(!use[i]) prim[t1++]=i;
        for(int j=0;j<t1;j++){
            if(i*prim[j]>=m) break;
            use[i*prim[j]]=1;
            if(i%prim[j]==0) break;
        }
    }
}
int main()
{
    int i,j,n;
    cin>>n>>m;
    int p=sqrt(n*1.0);
    init();
    for(i=1;i<=n;i++) scanf("%d",&b[i]);
    for(i=1;i<n;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        g[a].push_back(b);
        g[b].push_back(a);
    }
    dfs(1,-1);
    for(i=1;i<=n;i++){
        b[i]%=m;
        a[x[i]]=b[i];
    }
    int tot=0;
    for(i=1;i<=n;i++){
        ++tot;
        l[tot]=i;
        int f=i,q=0;
        while(f<=n&&q<p){
            vis[tot][a[f]]++;
            to[f]=tot;
            f++;
            q++;
        }
        r[tot]=f-1;
        i=f-1;
    }
    int q;
    scanf("%d",&q);
    for(i=0;i<q;i++){
        int p;
        scanf("%d",&p);
        if(p==1){
            int u,v;
            scanf("%d%d",&u,&v);
            merg(x[u],y[u],v);
        }
        else{
            int u;
            scanf("%d",&u);
            int s=0;
            for(j=0;j<t1;j++){
                if(query(x[u],y[u],prim[j])) s++;
            }
            printf("%d\n",s);
        }
    }
}


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<iostream>
#define sig 26
#define maxn 110005
using namespace std;
int x[maxn],y[maxn],cnt;
vector<int >g[maxn];
void dfs(int u,int pa){
    x[u]=++cnt;
    int p=g[u].size();
    for(int i=0;i<p;i++){
        if(g[u][i]!=pa)
        dfs(g[u][i],u);
    }
    y[u]=cnt;
}
int b[maxn];
short a[maxn];
int vis[405][1005];
short w[405];
int l[405],r[405];
int to[maxn];
int m;
void merg(int le,int ri,int p){
    p=p%m;
    int x=to[le];
    int y=to[ri];
    if(x==y){
        for(int i=le;i<=ri;i++){
            vis[x][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[x][a[i]]++;
        }
    }
    else {
        for(int i=le;i<=r[x];i++){
            vis[x][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[x][a[i]]++;
        }
        for(int i=x+1;i<=y-1;i++){
            w[i]+=p;
            w[i]%=m;
        }
        for(int i=l[y];i<=ri;i++){
            vis[y][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[y][a[i]]++;
        }
    }
}
int query(int le,int ri,int p){
    int x=to[le];
    int y=to[ri];
    if(x==y){
        for(int i=le;i<=ri;i++){
            if((a[i]+w[x])%m==p){
                return 1;
            }
        }
    }
    else {
        for(int i=x+1;i<=y-1;i++){
            int q=(p-w[i])%m;
            q=(q+m)%m;
            if(vis[i][q]) return 1;
        }
        for(int i=le;i<=r[x];i++){
            if((a[i]+w[x])%m==p) return 1;
        }
        for(int i=l[y];i<=ri;i++){
            if((a[i]+w[y])%m==p) return 1;
        }
    }
    return 0;
}
int use[1005],t1,prim[1005];
void init(){
    for(int i=2;i<m;i++){
        if(!use[i]) prim[t1++]=i;
        for(int j=0;j<t1;j++){
            if(i*prim[j]>=m) break;
            use[i*prim[j]]=1;
            if(i%prim[j]==0) break;
        }
    }
}
int main()
{
    int i,j,n;
    cin>>n>>m;
    int p=sqrt(n*1.0);
    init();
    for(i=1;i<=n;i++) scanf("%d",&b[i]);
    for(i=1;i<n;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        g[a].push_back(b);
        g[b].push_back(a);
    }
    dfs(1,-1);
    for(i=1;i<=n;i++){
        b[i]%=m;
        a[x[i]]=b[i];
    }
    int tot=0;
    for(i=1;i<=n;i++){
        ++tot;
        l[tot]=i;
        int f=i,q=0;
        while(f<=n&&q<p){
            vis[tot][a[f]]++;
            to[f]=tot;
            f++;
            q++;
        }
        r[tot]=f-1;
        i=f-1;
    }
    int q;
    scanf("%d",&q);
    for(i=0;i<q;i++){
        int p;
        scanf("%d",&p);
        if(p==1){
            int u,v;
            scanf("%d%d",&u,&v);
            merg(x[u],y[u],v);
        }
        else{
            int u;
            scanf("%d",&u);
            int s=0;
            for(j=0;j<t1;j++){
                if(query(x[u],y[u],prim[j])) s++;
            }
            printf("%d\n",s);
        }
    }
}


#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<stack>
#include<cmath>
#include<iostream>
#define sig 26
#define maxn 110005
using namespace std;
int x[maxn],y[maxn],cnt;
vector<int >g[maxn];
void dfs(int u,int pa){
    x[u]=++cnt;
    int p=g[u].size();
    for(int i=0;i<p;i++){
        if(g[u][i]!=pa)
        dfs(g[u][i],u);
    }
    y[u]=cnt;
}
int b[maxn];
int a[maxn];
int vis[405][1005];
int w[405];
int l[405],r[405];
int to[maxn];
int m;
void merg(int le,int ri,int p){
    int x=to[le];
    int y=to[ri];
    if(x==y){
        for(int i=le;i<=ri;i++){
            vis[x][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[x][a[i]]++;
        }
    }
    else {
        for(int i=le;i<=r[x];i++){
            vis[x][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[x][a[i]]++;
        }
        for(int i=x+1;i<=y-1;i++){
            w[i]+=p;
            w[i]%=m;
        }
        for(int i=l[y];i<=ri;i++){
            vis[y][a[i]]--;
            a[i]=a[i]+p;
            a[i]%=m;
            vis[y][a[i]]++;
        }
    }
}
int query(int le,int ri,int p){
    int x=to[le];
    int y=to[ri];
    if(x==y){
        for(int i=le;i<=ri;i++){
            if((a[i]+w[x])%m==p){
                return 1;
            }
        }
    }
    else {
        for(int i=le;i<=r[x];i++){
            if((a[i]+w[x])%m==p) return 1;
        }
        for(int i=x+1;i<=y-1;i++){
            int q=(p-w[i])%m;
            q=(q+m)%m;
            if(vis[i][q]) return 1;
        }
        for(int i=l[y];i<=ri;i++){
            if((a[i]+w[y])%m==p) return 1;
        }
    }
    return 0;
}
int use[1005],t1,prim[1005];
void init(){
    for(int i=2;i<m;i++){
        if(!use[i]) prim[t1++]=i;
        for(int j=0;j<t1;j++){
            if(i*prim[j]>=m) break;
            use[i*prim[j]]=1;
            if(i%prim[j]==0) break;
        }
    }
}
int main()
{
    int i,j,n;
    cin>>n>>m;
    init();
    for(i=1;i<=n;i++) scanf("%d",&b[i]);
    for(i=1;i<n;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        g[a].push_back(b);
        g[b].push_back(a);
    }
    dfs(1,-1);
    for(i=1;i<=n;i++){
        b[i]%=m;
        a[x[i]]=b[i];
    }
    int p=sqrt(n*1.0);
    int tot=0;
    for(i=1;i<=n;i++){
        ++tot;
        l[tot]=i;
        int f=i,q=0;
        while(f<=n&&q<p){
            vis[tot][a[f]]++;
            to[f]=tot;
            f++;
            q++;
        }
        r[tot]=f;
    }
    int q;
    scanf("%d",&q);
    for(i=0;i<q;i++){
        int p;
        scanf("%d",&p);
        if(p==1){
            int u,v;
            scanf("%d%d",&u,&v);
            merg(x[u],y[u],v);
        }
        else{
            int u;
            scanf("%d",&u);
            int s=0;
            for(j=0;j<t1;j++){
                if(query(x[u],y[u],prim[j])) s++;
            }
            printf("%d\n",s);
        }
    }
}


#include <bits/stdc++.h>

#define pb push_back
#define pp pop_back
#define mp make_pair
#define ld long double
#define f first
#define s second
#define ll long long

using namespace std;

const int N = 1e5 + 5;

const int mod = 1e9 + 7;

int n, m, q, tin[N], tout[N], timer, a[N], p[N], used[N];

vector < int > g[N];

bitset < 1001 > pr, cur;

struct node
{
	bitset < 1001 > b;
	int add;
	node()
	{
		add = 0;
		b.reset();
	}
} T[N * 4];

void dfs(int v = 1, int pr = 0)
{
	tin[v] = ++timer;
	p[timer] = v;
	for (auto to : g[v])
		if (to != pr)
			dfs(to, v);
	tout[v] = timer;
}

void build(int v = 1, int tl = 1, int tr = timer)
{
	if (tl == tr)
	{
		T[v].b[a[p[tl]]] = 1;
//		cout << "v = " << v << " tl = " << tl << " tr = " << tr << " p[tl] = " << p[tl] << " a[p[tl]] = " << a[p[tl]] << endl;
		return;
	}
	int tm = (tl + tr) / 2;
	build(v * 2, tl, tm); build(v * 2 + 1, tm + 1, tr);
	T[v].b = (T[v * 2].b | T[v * 2 + 1].b);
}

void push(int v, int tl, int tr)
{
	if (tl > tr || T[v].add == 0) return;
	if (tl != tr)
	{
		T[v * 2].add += T[v].add; T[v * 2].add %= m;
		T[v * 2 + 1].add += T[v].add; T[v * 2 + 1].add %= m;
	}
	T[v].b = ((T[v].b << T[v].add) | (T[v].b >> (m - T[v].add)));
	T[v].add = 0;
}

void upd(int l, int r, int x, int v = 1, int tl = 1, int tr = timer)
{
	push(v, tl, tr);
	if (tl > r || tr < l) return;
	if (l <= tl && tr <= r)
	{
		T[v].add += x; T[v].add %= m;
		push(v, tl, tr);
		return;
	}
	int tm = (tl + tr) / 2;
	upd(l, r, x, v * 2, tl, tm); upd(l, r, x, v * 2 + 1, tm + 1, tr);
	T[v].b = (T[v * 2].b | T[v * 2 + 1].b);
}

void get(int l, int r, int v = 1, int tl = 1, int tr = timer)
{
	push(v, tl, tr);
	if (tl > r || tr < l) return;
	if (l <= tl && tr <= r)
	{
		cur |= T[v].b;
		return;
	}
	int tm = (tl + tr) / 2;
	get(l, r, v * 2, tl, tm); get(l, r, v * 2 + 1, tm + 1, tr);
}

int main()
{
  ios_base::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 1;i <= n;i++)
  {
  	cin >> a[i];
  	a[i] %= m;
  }
  for (int i = 1, a, b;i < n;i++)
  {
  	cin >> a >> b;
  	g[a].pb(b); g[b].pb(a);
  }
  dfs();
  build();
  for (int i = 2;i <= m;i++)
  {
  	if (!used[i])
  	{
  		pr[i] = 1;
  		for (int j = i;j <= m;j += i) used[j] = 1;
  	}
  }
  cin >> q;
  for (int i = 1, t, a, b;i <= q;i++)
  {
  	cin >> t >> a;
  	if (t == 1)
  	{
  	  cin >> b;
  		upd(tin[a], tout[a], b);
  	}
  	else
  	{
  		cur.reset();
  		get(tin[a], tout[a]);
  		cur = (cur & pr);
  		cout << cur.count() << endl;
  	}
  }
	return 0;
}


#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

const int max_n = 111, max_k = 25, mod = 1000000007;

int n, k, dp[max_n][2][max_k][max_k], res[max_n];
vector<int> g[max_n];

void dfs(int v, int p) {
    //vector<int> all;
    for (int i = 0; i < g[v].size(); ++i) {
        if (g[v][i] != p) {
            dfs(g[v][i], v);
            //all.push_back(g[v][i]);
        }
    }
    //g[v] = all;
    int q1 = 0, q2 = 1;
    for (int i = 1; i < max_k; ++i) {
        dp[v][q1][i][max_k - 1] = 1;
        //dp[v][q1][i][0] = 1;
    }
    dp[v][q1][max_k - 1][max_k - 1] = 1;
    dp[v][q1][0][0] = 1;
    //dp[v][q1][max_k - 1][max_k - 1] = 1;
    for (int i = 0; i < g[v].size(); ++i) {
        if (g[v][i] == p) {
            continue;
        }
        memset(dp[v][q2], 0, sizeof(dp[v][q2]));
        for (int last = 0; last < max_k; ++last) {
            for (int mn = 0; mn < max_k; ++mn) {
                for (int d = 0; d < max_k; ++d) {
                    int nlast = min(mn + 1, last + 1);
                    if (nlast > k) {
                        nlast = max_k - 1;
                    }
                    if (d == 0) {
                        nlast = 0;
                    }
                    /*if (last == 0 && mn == 0 && d == 0) {
                        cout << dp[v][q1][last][mn] << "   " << nlast << " " << d << endl;
                        cout << dp[g[v][i]][res[g[v][i]]][nlast][d] << endl;
                    }*/
                    dp[v][q2][last][min(mn, d + 1)] += (1LL * dp[v][q1][min(d + 1, last)][mn] * dp[g[v][i]][res[g[v][i]]][nlast][d]) % mod;
                    dp[v][q2][last][min(mn, d + 1)] %= mod;
                }
            }
        }
        swap(q1, q2);
    }
    res[v] = q1;
    for (int last = 0; last < max_k; ++last) {
        for (int mn = 0; mn < max_k; ++mn) {
            if (last > k && mn > k) {
                dp[v][res[v]][last][mn] = 0;
            }
        }
    }
}

void solve() {

}

int main() {
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n >> k;
    for (int i = 1; i < n; ++i) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1, -1);
    int ans = (dp[1][res[1]][0][0]) % mod;
    for (int i = 0; i <= k; ++i) {
        //break;
        ans += dp[1][res[1]][max_k - 1][i];
        ans %= mod;
    }
    cout << ans << endl;
    return 0;
}


#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

const int max_n = 111, max_k = 25, mod = 1000000007;

int n, k, dp[max_n][2][max_k][max_k], res[max_n];
vector<int> g[max_n];

void dfs(int v, int p) {
    //vector<int> all;
    for (int i = 0; i < g[v].size(); ++i) {
        if (g[v][i] != p) {
            dfs(g[v][i], v);
            //all.push_back(g[v][i]);
        }
    }
    //g[v] = all;
    int q1 = 0, q2 = 1;
    for (int i = 1; i < max_k; ++i) {
        dp[v][q1][i][max_k - 1] = 1;
    }
    dp[v][q1][max_k - 1][max_k - 1] = 1;
    dp[v][q1][0][0] = 1;
    //dp[v][q1][max_k - 1][max_k - 1] = 1;
    for (int i = 0; i < g[v].size(); ++i) {
        if (g[v][i] == p) {
            continue;
        }
        memset(dp[v][q2], 0, sizeof(dp[v][q2]));
        for (int last = 0; last < max_k; ++last) {
            for (int mn = 0; mn < max_k; ++mn) {
                for (int d = 0; d < max_k; ++d) {
                    int nlast = min(mn + 1, last + 1);
                    if (nlast > k) {
                        nlast = max_k - 1;
                    }
                    if (d == 0) {
                        nlast = 0;
                    }
                    /*if (last == 0 && mn == 0 && d == 0) {
                        cout << dp[v][q1][last][mn] << "   " << nlast << " " << d << endl;
                        cout << dp[g[v][i]][res[g[v][i]]][nlast][d] << endl;
                    }*/
                    dp[v][q2][last][min(mn, d + 1)] += (1LL * dp[v][q1][last][mn] * dp[g[v][i]][res[g[v][i]]][nlast][d]) % mod;
                    dp[v][q2][last][min(mn, d + 1)] %= mod;
                }
            }
        }
        swap(q1, q2);
    }
    res[v] = q1;
    for (int last = 0; last < max_k; ++last) {
        for (int mn = 0; mn < max_k; ++mn) {
            if (last > k && mn > k) {
                dp[v][res[v]][last][mn] = 0;
            }
        }
    }
}

void solve() {

}

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n >> k;
    for (int i = 1; i < n; ++i) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1, -1);
    int ans = (dp[1][res[1]][0][0]) % mod;
    for (int i = 0; i <= k; ++i) {
        //break;
        ans += dp[1][res[1]][max_k - 1][i];
        ans %= mod;
    }
    cout << ans << endl;
    return 0;
}


#include <map>
#include <set>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>

using namespace std;

const int max_n = 111, max_k = 25, mod = 1000000007;

int n, k, dp[max_n][2][max_k][max_k], res[max_n];
vector<int> g[max_n];

void dfs(int v, int p) {
    //vector<int> all;
    for (int i = 0; i < g[v].size(); ++i) {
        if (g[v][i] != p) {
            dfs(g[v][i], v);
            //all.push_back(g[v][i]);
        }
    }
    //g[v] = all;
    int q1 = 0, q2 = 1;
    for (int i = 1; i < max_k; ++i) {
        dp[v][q1][i][max_k - 1] = 1;
        //dp[v][q1][i][0] = 1;
    }
    dp[v][q1][max_k - 1][max_k - 1] = 1;
    dp[v][q1][0][0] = 1;
    //dp[v][q1][max_k - 1][max_k - 1] = 1;
    for (int i = 0; i < g[v].size(); ++i) {
        if (g[v][i] == p) {
            continue;
        }
        memset(dp[v][q2], 0, sizeof(dp[v][q2]));
        for (int last = 0; last < max_k; ++last) {
            for (int mn = 0; mn < max_k; ++mn) {
                for (int d = 0; d < max_k; ++d) {
                    int nlast = min(mn + 1, last + 1);
                    if (nlast > k) {
                        nlast = max_k - 1;
                    }
                    if (d == 0) {
                        nlast = 0;
                    }
                    /*if (last == 0 && mn == 0 && d == 0) {
                        cout << dp[v][q1][last][mn] << "   " << nlast << " " << d << endl;
                        cout << dp[g[v][i]][res[g[v][i]]][nlast][d] << endl;
                    }*/
                    dp[v][q2][last][min(mn, d + 1)] += (1LL * dp[v][q1][min(nlast + 2, last)][mn] * dp[g[v][i]][res[g[v][i]]][nlast][d]) % mod;
                    dp[v][q2][last][min(mn, d + 1)] %= mod;
                }
            }
        }
        swap(q1, q2);
    }
    res[v] = q1;
    for (int last = 0; last < max_k; ++last) {
        for (int mn = 0; mn < max_k; ++mn) {
            if (last > k && mn > k) {
                dp[v][res[v]][last][mn] = 0;
            }
        }
    }
}

void solve() {

}

int main() {
    freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n >> k;
    for (int i = 1; i < n; ++i) {
        int u, v;
        cin >> u >> v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(1, -1);
    int ans = (dp[1][res[1]][0][0]) % mod;
    for (int i = 0; i <= k; ++i) {
        //break;
        ans += dp[1][res[1]][max_k - 1][i];
        ans %= mod;
    }
    cout << ans << endl;
    return 0;
}


#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <cassert>

using namespace std;

#define pb push_back
#define pp pop_back
#define f first
#define s second
#define mp make_pair
#define sz(a) int((a).size())
#ifdef _WIN32
#  define I64 "%I64d"
#else
#  define I64 "%lld"
#endif
#define fname "."

typedef long long ll;
typedef unsigned long long ull;

const int MAX_N = (int)1e7 + 123;
const int mod = (int)1e9 + 7;

int n, k;
vector < int > g[105];
int dp[105][24][24], nw[24][24];
// vertex farthest_unsatisfied nearest_black
// 23 - does not exist

inline void add(int &a, const int &b) {
	a += b;
	if (a >= mod)
		a -= mod;
}

void dfs(int v = 1, int pr = -1) {
	vector < int > child;
	for (auto to : g[v])
		if (to != pr) {
			dfs(to, v);
			child.pb(to);
		}
	dp[v][23][0] = dp[v][0][23] = 1;
	for (auto to : child) {
		memset(nw, 0, sizeof nw);
		for (int x = 0; x < 24; x++)
			for (int y = 0; y < 24; y++) {
				if (!dp[v][x][y])
					continue;
				for (int x2 = 0; x2 < 24; x2++)
					for (int y2 = 0; y2 < 24; y2++) {
						if (!dp[to][x2][y2])
							continue;
						int ny = min(y, y2 + 1);
						int nx = 23;
						if (x2 != 23 && x2 + 1 + y > k)
							nx = x2 + 1;
						if (x != 23 && x + 1 + y2 > k)
							nx = (nx == 23 ? x : max(nx, x));
						add(nw[nx][ny], 1ll * dp[v][x][y] * dp[to][x2][y2] % mod);
					}
			}
		for (int x = 0; x < 24; x++)
			for (int y = 0; y < 24; y++)
				dp[v][x][y] = nw[x][y];
	}
}

int main() {
	#ifdef Nick
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
	#endif
	cin >> n >> k;
	for (int i = 1, u, v; i < n; i++) {
		cin >> u >> v;
		g[u].pb(v), g[v].pb(u);
	}
	dfs();
	int ans = 0;
	for (int i = 0; i < 23; i++)
		add(ans, dp[1][23][i]);
	cout << ans;
	return 0;
}


#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <algorithm>
#include <fstream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <ctime>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <cassert>

using namespace std;

#define pb push_back
#define pp pop_back
#define f first
#define s second
#define mp make_pair
#define sz(a) int((a).size())
#ifdef _WIN32
#  define I64 "%I64d"
#else
#  define I64 "%lld"
#endif
#define fname "."

typedef long long ll;
typedef unsigned long long ull;

const int MAX_N = (int)1e7 + 123;
const int mod = (int)1e9 + 7;

int n, k;
vector < int > g[105];
int dp[105][24][24], nw[24][24];
// vertex farthest_unsatisfied nearest_black
// 23 - does not exist

inline void add(int &a, const int &b) {
	a += b;
	if (a >= mod)
		a -= mod;
}

void dfs(int v = 1, int pr = -1) {
	vector < int > child;
	for (auto to : g[v])
		if (to != pr) {
			dfs(to, v);
			child.pb(to);
		}
	dp[v][23][0] = dp[v][0][23] = 1;
	for (auto to : child) {
		memset(nw, 0, sizeof nw);
		for (int x = 0; x < 24; x++)
			for (int y = 0; y < 24; y++) {
				if (!dp[v][x][y])
					continue;
				for (int x2 = 0; x2 < 24; x2++)
					for (int y2 = 0; y2 < 24; y2++) {
						if (!dp[to][x2][y2])
							continue;
						int ny = min(y, y2 + 1);
						int nx = 23;
						if (x2 != 23 && x2 + 1 + y > k)
							nx = x2 + 1;
						if (x != 23 && x + 1 + y2 > k)
							nx = (nx == 23 ? x : max(nx, x));
						if (nx != 23 && nx > k)
							continue;
						add(nw[nx][ny], 1ll * dp[v][x][y] * dp[to][x2][y2] % mod);
					}
			}
		for (int x = 0; x < 24; x++)
			for (int y = 0; y < 24; y++)
				dp[v][x][y] = nw[x][y];
	}
}

int main() {
	#ifdef Nick
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
	#endif
	cin >> n >> k;
	for (int i = 1, u, v; i < n; i++) {
		cin >> u >> v;
		g[u].pb(v), g[v].pb(u);
	}
	dfs();
	int ans = 0;
	for (int i = 0; i < 23; i++)
		add(ans, dp[1][23][i]);
	cout << ans;
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<string>
#include<cstring>
#include<cctype>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<iomanip>
#include<sstream>
#include<vector>
#include<cstdlib>
#include<ctime>
#include<list>
#include<deque>
#include<bitset>
#include<fstream>
#define ld double
#define ull unsigned long long
#define ll long long
#define pii pair<int,int >
#define iiii pair<int,pii >
#define mp make_pair
#define INF 1000000000
#define MOD 1000000007
#define rep(i,x) for(int (i)=0;(i)<(x);(i)++)
inline int getint(){
    int x=0,p=1;char c=getchar();
    while (c<=32)c=getchar();
    if(c==45)p=-p,c=getchar();
    while (c>32)x=x*10+c-48,c=getchar();
    return x*p;
}
using namespace std;
//ruogu
const int N=110;
const int M=25;
int dp[N][M][M],n,k,res,tmp[N][M][M];
vector<int>G[N];
//
inline void add(int &x,int y){
	x+=y;
	if(x>=MOD)x-=MOD;
}
inline int mul(int x,int y){
	ll ans=1ll*x*y;
	return ans%MOD;
}
void go(int x,int p){
	vector<int>v;
	rep(i,G[x].size()){
		int to=G[x][i];
		if(to!=p){
			go(to,x);
			v.push_back(to);
		}
	}
	tmp[0][1][M-1]=tmp[0][0][1]=1;
	rep(i,v.size()){
		int x=v[i];
		rep(i0,M)rep(i1,M)tmp[i+1][i0][i1]=0;
		rep(i0,k+2)rep(i1,M){
			rep(i2,k+2)rep(i3,M){
				int hh=mul(tmp[i][i0][i1],dp[x][i2][i3]);
				if((!i2||i1+i2-1<=k)&&(!i0||i0+i3-1<=k)){
					add(tmp[i+1][0][min(i1,i3+1)],hh);
					continue;
				}
				if(!i2||i1+i2-1<=k){
					add(tmp[i+1][i0][min(i1,i3+1)],hh);
					continue;
				}
				if(!i0||i0+i3-1<=k){
					if(i2<=k)add(tmp[i+1][i2+1][min(i1,i3+1)],hh);
					continue;
				}
				if(i2<=k)add(tmp[i+1][max(i0,i2+1)][min(i1,i3+1)],hh);
			}
		}
	}
	rep(i,k+2)rep(j,M)dp[x][i][j]=tmp[v.size()][i][j];
}
int main(){
	n=getint();k=getint();
	rep(i,n-1){
		int x=getint()-1,y=getint()-1;
		G[x].push_back(y);
		G[y].push_back(x);
	}
	go(0,-1);
	for(int i=1;i<=k+1;i++)if(dp[0][0][i]>0)add(res,dp[0][0][i]);
	printf("%d\n",res);
	return 0;
}


#include <bits/stdc++.h>

#define pp pop_back
#define pb push_back
#define forn(i, x, n) for (int i = int(x); i <= int(n); ++i)
#define for1(i, n, x) for (int i = int(n); i >= int(x); --i)
#define mp make_pair
#define s second
#define f first
#define sz(a) (int)((a).size())

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> PII;

const int N = 123;
const int mod = 1e9 + 7;

void add(int &a, int b)
{
  a += b;
  if (a >= mod) a -= mod;
}
int mult(int a, int b)
{
  return 1ll * a * b % mod;
}

int n, dp[N][N][2], d[N][2], k;

vector < int > g[N];

void Merge(int a, int b)
{
  for (int i = 0;i <= k;i++)
    for (int t = 0;t < 2;t++)
      d[i][t] = dp[a][i][t], dp[a][i][t] = 0;
  for (int i = 0;i <= k;i++)
  {
    for (int j = 0;j <= k;j++)
    {
      add(dp[a][min(i, j + 1)][0], mult(dp[b][j][0], d[i][0]));
      if (i + j + 1 <= k) add(dp[a][i][0], mult(dp[b][j][1], d[i][0]));
      else add(dp[a][j + 1][1], mult(dp[b][j][1], d[i][0]));
      add(dp[a][max(i, j + 1)][1], mult(dp[b][j][1], d[i][1]));
      if (i + j + 1 <= k) add(dp[a][j + 1][0], mult(dp[b][j][0], d[i][1]));
      else add(dp[a][i][1], mult(dp[b][j][0], d[i][1]));
    }
  }
}

void dfs(int v = 1, int p = 0)
{
  dp[v][0][1] = dp[v][0][0] = 1;
  for (auto to : g[v])
  {
    if (to == p) continue;
    dfs(to, v);
    Merge(v, to);
  }
}

int main() {
  ios_base::sync_with_stdio(0);
  #ifdef wws
    freopen("in", "r", stdin);
  #endif
  cin >> n >> k;
  for (int i = 1;i < n;i++)
  {
    int a, b;
    cin >> a >> b;
    g[a].pb(b);
    g[b].pb(a);
  }
  dfs();
  int ans = 0;
  for (int i = 0;i <= k;i++) add(ans, dp[1][i][0]);
  cout << ans << endl;
  return 0;
}


#include <bits/stdc++.h>

#define pp pop_back
#define pb push_back
#define forn(i, x, n) for (int i = int(x); i <= int(n); ++i)
#define for1(i, n, x) for (int i = int(n); i >= int(x); --i)
#define mp make_pair
#define s second
#define f first
#define sz(a) (int)((a).size())

using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> PII;

const int N = 123;
const int mod = 1e9 + 7;

void add(int &a, int b)
{
  a += b;
  if (a >= mod) a -= mod;
}

int sum(int a, int b)
{
  add(a, b);
  return a;
}

int mult(int a, int b)
{
  return 1ll * a * b % mod;
}

int n, k, dp[N][N];

vector < int > g[N];

void go(int v = 1, int p = 0)
{
  vector < int > adj;
  for (auto to : g[v])
  {
    if (to != p)
    {
      go(to, v);
      adj.pb(to);
    }
  }
  if (adj.size() == 0)
  {
    dp[0][v] = dp[k + 1][v] = 1;
    return;
  }
  // paint
  dp[0][v] = 1;
  for (auto to : adj)
  {
    int s = 0;
    for (int i = 0;i <= 2 * k;i++) add(s, dp[i][to]);
    dp[0][v] = mult(dp[0][v], s);
  }
  for (int i = 0;i < adj.size();i++)
  {
    // set mx
    int to = adj[i];
    for (int mx = 0;mx <= 2 * k + 1;mx++)
    {
      int now = dp[mx][to];
      for (int j = 0;j < adj.size();j++)
      {
        if (i == j) continue;
        int x = adj[j];
        int s = 0;
        for (int lvl = 0;lvl < mx + (j > i);lvl++)
        {
          if (lvl + mx + 2 <= 2 * k + 1) add(s, dp[lvl][x]);
        }
        now = mult(now, s);
      }
      add(dp[mx + 1][v], now);
    }
  }
  //cout << "v = " << v << endl;
  //for (int lvl = 0;lvl <= 2 * k + 1;lvl++) cout << "lvl = " << lvl << " dp = " << dp[lvl][v] << endl;
}

int main() {
  ios_base::sync_with_stdio(0);
  #ifdef wws
    freopen("in", "r", stdin);
  #endif
  cin >> n >> k;
  for (int i = 1, u, v;i < n;i++)
  {
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }
  go();
  int ans = 0;
  for (int d = 0;d <= k;d++) add(ans, dp[d][1]);
  cout << ans << endl;
  return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

#define ll long long

const int MaxN = 107;
const int MaxM = 50;
const int mod = (int)1e9 + 7;

int N,M,MM,S;
vector<int> iv[MaxN];
ll f[MaxN][MaxM], tmp[MaxM];

void DFS(int x, int fa)
{
	int i,j,k,u;
	f[x][0] = 1; f[x][M+1] = 1;
	for (i=0; i<iv[x].size(); i++)
		if (iv[x][i] != fa)
		{
			u = iv[x][i]; DFS(u, x);
			for (i=0; i<=MM; i++) tmp[i] = 0;
			for (j=0; j<=MM; j++)
				for (k=0; k<MM; k++)
					if (j+k <= M+M) (tmp[min(j,k+1)] += f[x][j] * f[u][k]) %= mod;
					else (tmp[max(j,k+1)] += f[x][j] * f[u][k]) %= mod;
			for (j=0; j<=MM; j++) f[x][j] = tmp[j];
		}
}

int main()
{
	//freopen("C.in", "r", stdin);

	int i,u,v;
	scanf("%d%d", &N, &M); MM = M + M + 1;
	for (i=1; i<N; i++)
	{
		scanf("%d%d", &u, &v);
		iv[u].push_back(v);
		iv[v].push_back(u);
	}
	DFS(1, 0);
	for (i=0; i<=M; i++)
		S = (S + f[1][i]) % mod;
	printf("%d\n", S);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
#include <algorithm>
using namespace std;

#define ll long long

const int MaxN = 107;
const int MaxM = 50;
const int mod = (int)1e9 + 7;

int N,M,MM;
vector<int> iv[MaxN];
ll S, f[MaxN][MaxM], tmp[MaxM];

void DFS(int x, int fa)
{
	int i,j,k,u;
	f[x][0] = 1; f[x][M+1] = 1;
	for (i=0; i<iv[x].size(); i++)
		if (iv[x][i] != fa)
		{
			u = iv[x][i]; DFS(u, x);
			for (j=0; j<=MM; j++) tmp[j] = 0;
			for (j=0; j<=MM; j++)
				for (k=0; k<MM; k++)
					if (j+k <= M+M) (tmp[min(j,k+1)] += f[x][j] * f[u][k]) %= mod;
					else (tmp[max(j,k+1)] += f[x][j] * f[u][k]) %= mod;
			for (j=0; j<=MM; j++) f[x][j] = tmp[j];
		}
}

int main()
{
//	freopen("C.in", "r", stdin);

	int i,u,v;
	scanf("%d%d", &N, &M); MM = M + M + 1;
	for (i=1; i<N; i++)
	{
		scanf("%d%d", &u, &v);
		iv[u].push_back(v);
		iv[v].push_back(u);
	}
	DFS(1, 0);
	for (i=0; i<=M; i++)
		S = (S + f[1][i]) % mod;
	printf("%I64d\n", S);
	return 0;
}


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

#define N 105

const int mod = 1e9 + 7;

int n, k, ans;
vector<int> v[N];
int dp[N][N], tmp[N];

void dfs(int x, int par = 0) {
    dp[x][0] = dp[x][k+1] = 1;
    for (int ii = 0; ii < v[x].size(); ii ++) {
        int y = v[x][ii];
        if (y == par) continue;
        dfs(y, x);
        memset(tmp, 0, sizeof tmp);
        for (int i = 0; i <= 2 * k; i ++)
        for (int j = 0; j <= 2 * k; j ++) {
            int t = i + j <= 2 * k ? min(i, j + 1) : max(i, j + 1);
            (tmp[t] += 1ll * dp[x][i] * dp[y][j] % mod) %= mod;
        }
        for (int i = 0; i <= 2 * k; i ++) dp[x][i] = tmp[i];
    }
}

int main() {
    scanf("%d %d", &n, &k);
    for (int i = 1; i < n; i ++) {
        int x, y;
        scanf("%d %d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1);
    for (int i = 0; i <= k; i ++) (ans += dp[1][i]) %= mod;
    printf("%d\n", ans);
    return 0;
}


#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define m_k make_pair
#define mod 1000000007
#define int long long
using namespace std;
const int N=110;
int n,k,dp[N][N][2],f[N][2],de[N];
int tot,first[N],nxt[N*2],point[N*2];
inline void add(int &a,int b){a=(a+b)%mod;}
inline void del(int &a,int b){a=(a-b+mod)%mod;}
inline void mul(int &a,int b){a=(a*b)%mod;}
inline void add_edge(int x,int y)
{
	tot++;
	nxt[tot]=first[x];
	first[x]=tot;
	point[tot]=y;
}
void dfs(int x,int fa)
{
	int cnt=0;
	for (int i=first[x];i!=-1;i=nxt[i])
	{
		int u=point[i];
		if (u==fa) continue;
		de[u]=de[x]+1;
		dfs(u,x);
		cnt++;
		if (cnt==1)
		{
			for (int j=1;j<=n;j++)
			{
				dp[x][j][0]=dp[u][j][0];
				dp[x][j][1]=dp[u][j][1];
			}
			continue;
		}
		memset(f,0,sizeof(f));
		for (int j=1;j<=n;j++)
		{
			if (dp[x][j][0]==0) continue;
			for (int p=1;p<=n;p++) add(f[min(j,p)][0],dp[x][j][0]*dp[u][p][0]);
			for (int p=1;p<=n;p++)
			{
				if (p+j-2*de[x]<=k) add(f[j][0],dp[x][j][0]*dp[u][p][1]);
				else add(f[p][1],dp[x][j][0]*dp[u][p][1]);
			}
		}
		for (int j=1;j<=n;j++)
		{
			if (dp[x][j][1]==0) continue;
			for (int p=1;p<=n;p++) add(f[max(j,p)][1],dp[x][j][1]*dp[u][p][1]);
			for (int p=1;p<=n;p++)
			{
				if (p+j-2*de[x]<=k) add(f[p][0],dp[x][j][1]*dp[u][p][0]);
				else add(f[j][1],dp[x][j][1]*dp[u][p][0]);
			}
		}
		for (int j=1;j<=n;j++) dp[x][j][0]=f[j][0],dp[x][j][1]=f[j][1];
	}
	if (cnt==0)
	{
		dp[x][de[x]][0]=1;
		dp[x][de[x]][1]=1;
		return;
	}
	memset(f,0,sizeof(f));
	for (int i=1;i<=n;i++)
	{
		add(f[min(i,de[x])][0],dp[x][i][0]);
		add(f[max(i,de[x])][1],dp[x][i][1]);
		if (i-de[x]<=k) add(f[de[x]][0],dp[x][i][1]),add(f[i][0],dp[x][i][0]);
		else add(f[de[x]][1],dp[x][i][0]);
	}
	for (int i=1;i<=n;i++) dp[x][i][0]=f[i][0],dp[x][i][1]=f[i][1];
}
signed main()
{
	tot=-1;
	memset(first,-1,sizeof(first));
	scanf("%lld%lld",&n,&k);
	for (int i=1;i<n;i++)
	{
		int u,v;
		scanf("%lld%lld",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}
	de[1]=1;
	dfs(1,1);
	int ans=0;
	for (int i=1;i<=n;i++) add(ans,dp[1][i][0]);
	printf("%lld\n",ans);
}


#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define m_k make_pair
#define mod 1000000007
using namespace std;
const int N=110;
int n,k,dp[N][N][2],f[N][2],de[N];
int tot,first[N],nxt[N*2],point[N*2];
inline void add(int &a,int b){a=(a+b)%mod;}
inline void del(int &a,int b){a=(a-b+mod)%mod;}
inline void mul(int &a,int b){a=(a*b)%mod;}
inline void add_edge(int x,int y)
{
	tot++;
	nxt[tot]=first[x];
	first[x]=tot;
	point[tot]=y;
}
void dfs(int x,int fa)
{
	int cnt=0;
	for (int i=first[x];i!=-1;i=nxt[i])
	{
		int u=point[i];
		if (u==fa) continue;
		de[u]=de[x]+1;
		dfs(u,x);
		cnt++;
		if (cnt==1)
		{
			for (int j=1;j<=n;j++)
			{
				dp[x][j][0]=dp[u][j][0];
				dp[x][j][1]=dp[u][j][1];
			}
			continue;
		}
		memset(f,0,sizeof(f));
		for (int j=1;j<=n;j++)
		{
			if (dp[x][j][0]==0) continue;
			for (int p=1;p<=n;p++) add(f[min(j,p)][0],dp[x][j][0]*dp[u][p][0]);
			for (int p=1;p<=n;p++)
			{
				if (p+j-2*de[x]<=k) add(f[j][0],dp[x][j][0]*dp[u][p][1]);
				else add(f[p][1],dp[x][j][0]*dp[u][p][1]);
			}
		}
		for (int j=1;j<=n;j++)
		{
			if (dp[x][j][1]==0) continue;
			for (int p=1;p<=n;p++) add(f[max(j,p)][1],dp[x][j][1]*dp[u][p][1]);
			for (int p=1;p<=n;p++)
			{
				if (p+j-2*de[x]<=k) add(f[p][0],dp[x][j][1]*dp[u][p][0]);
				else add(f[j][1],dp[x][j][1]*dp[u][p][0]);
			}
		}
		for (int j=1;j<=n;j++) dp[x][j][0]=f[j][0],dp[x][j][1]=f[j][1];
	}
	if (cnt==0)
	{
		dp[x][de[x]][0]=1;
		dp[x][de[x]][1]=1;
		return;
	}
	memset(f,0,sizeof(f));
	for (int i=1;i<=n;i++)
	{
		add(f[min(i,de[x])][0],dp[x][i][0]);
		add(f[max(i,de[x])][1],dp[x][i][1]);
		if (i-de[x]<=k) add(f[de[x]][0],dp[x][i][1]),add(f[i][0],dp[x][i][0]);
		else add(f[de[x]][1],dp[x][i][0]);
	}
	for (int i=1;i<=n;i++) dp[x][i][0]=f[i][0],dp[x][i][1]=f[i][1];
}
signed main()
{
	tot=-1;
	memset(first,-1,sizeof(first));
	scanf("%d%d",&n,&k);
	for (int i=1;i<n;i++)
	{
		int u,v;
		scanf("%d%d",&u,&v);
		add_edge(u,v);
		add_edge(v,u);
	}
	de[1]=1;
	dfs(1,1);
	int ans=0;
	for (int i=1;i<=n;i++) add(ans,dp[1][i][0]);
	printf("%d\n",ans);
}


#include<bits/stdc++.h>
#define ll long long
#define mp make_pair
using namespace std;
ll dp[101][44],f[44],md=1e9+7,ans;
int n,k;
vector<int>g[101];
inline void add(ll&x,ll y){x=(x+y)%md;}
void dfs(int u,int par){
	dp[u][0]=dp[u][k+1]=1;
	for(int v:g[u])if(v!=par){
		dfs(v,u);
		memset(f,0,sizeof(f));
		for(int i=0;i<=k<<1;++i)for(int j=0;j<=k<<1;++j)if(i+j<=k<<1)add(f[min(i,j+1)],dp[u][i]*dp[v][j]);else add(f[max(i,j+1)],dp[u][i]*dp[v][j]);
		for(int i=0;i<=k<<1;++i)dp[u][i]=f[i];
	}
}
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<n;++i){
		int u,v;scanf("%d%d",&u,&v);
		g[u].push_back(v),g[v].push_back(u);
	}
	dfs(1,0);
	for(int i=0;i<=k;++i)add(ans,dp[1][i]);
	printf("%lld\n",ans);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int uli;
const uli mod=1e9+9;
const int mxn=123;
const int mxk=25;
vector<int>g[mxn];
uli f[mxn][mxn][mxn];
uli acum[mxn][mxn][mxn];
int dep[mxn];
int n,k;
void dfs(int u,int pu){
  for(int v:g[u])if(v!=pu){
    dfs(v,u);
    dep[u]=max(dep[u],1+dep[v]);
  }
  for(int up=1;up<=n;up++){
    uli f0=1ll;
    for(int v:g[u])if(v!=pu)f0=f0*acum[v][1][0]%mod;
    f[u][up][0]=f0;
    for(int dwn=1;dwn<=n;dwn++)if(min(up,dwn)<=k){
      uli all=1ll;
      uli neg=1ll;
      for(int v:g[u])if(v!=pu){
        int upv=min(up,dwn)+1;
        uli q=acum[v][upv][min(dwn-1,dep[v]+1)];
        all=all*q%mod;
        q=acum[v][upv][min(dwn,dep[v]+1)];
        neg=neg*q%mod;
      }
      f[u][up][dwn]=(all-neg)%mod;
    }
    if(dep[u]+up<=k){
      f[u][up][dep[u]+1]=1;//all white;
    }
    for(int i=n;i>=0;i--)
      acum[u][up][i]=(f[u][up][i]+acum[u][up][i+1])%mod;
  }
}
int main(){
  int u,v;
  scanf("%d %d",&n,&k);
  if(k==0){
    puts("1");
    return 0;
  }
  for(int i=0;i<n-1;i++){
    scanf("%d %d",&u,&v);
    g[--u].push_back(--v);
    g[v].push_back(u);
  }
  dfs(0,0);
  printf("%lld\n",(acum[0][k+1][0]+mod)%mod);
  return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long int uli;
const uli mod=1e9+7;
const int mxn=123;
const int mxk=25;
vector<int>g[mxn];
uli f[mxn][mxn][mxn];
uli acum[mxn][mxn][mxn];
int dep[mxn];
int n,k;
void dfs(int u,int pu){
  for(int v:g[u])if(v!=pu){
    dfs(v,u);
    dep[u]=max(dep[u],1+dep[v]);
  }
  for(int up=1;up<=n;up++){
    uli f0=1ll;
    for(int v:g[u])if(v!=pu)f0=f0*acum[v][1][0]%mod;
    f[u][up][0]=f0;
    for(int dwn=1;dwn<=n;dwn++)if(min(up,dwn)<=k){
      uli all=1ll;
      uli neg=1ll;
      for(int v:g[u])if(v!=pu){
        int upv=min(up,dwn)+1;
        uli q=acum[v][upv][min(dwn-1,dep[v]+1)];
        all=all*q%mod;
        q=acum[v][upv][min(dwn,dep[v]+1)];
        neg=neg*q%mod;
      }
      f[u][up][dwn]=(all-neg)%mod;
    }
    if(dep[u]+up<=k){
      f[u][up][dep[u]+1]=1;//all white;
    }
    for(int i=n;i>=0;i--)
      acum[u][up][i]=(f[u][up][i]+acum[u][up][i+1])%mod;
  }
}
int main(){
  int u,v;
  scanf("%d %d",&n,&k);
  if(k==0){
    puts("1");
    return 0;
  }
  for(int i=0;i<n-1;i++){
    scanf("%d %d",&u,&v);
    g[--u].push_back(--v);
    g[v].push_back(u);
  }
  dfs(0,0);
  printf("%lld\n",(acum[0][k+1][0]+mod)%mod);
  return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define mp make_pair
using namespace std;
ll dp[101][44],f[44],md=1e9+7,ans;
int n,k;
vector<int>g[101];
inline void add(ll&x,ll y){x=(x+y)%md;}
void dfs(int u,int par){
	dp[u][0]=dp[u][k+1]=1;
	for(int v:g[u])if(v!=par){
		dfs(v,u);
		memset(f,0,sizeof(f));
		for(int i=0;i<=k<<1;++i)for(int j=0;j<=k<<1;++j)if(i+j<=k<<1)add(f[min(i,j+1)],dp[u][i]*dp[v][j]);else add(f[max(i,j+1)],dp[u][i]*dp[v][j]);
		for(int i=0;i<=k<<1;++i)dp[u][i]=f[i];
	}
}
int main(){
	scanf("%d%d",&n,&k);
	for(int i=1;i<n;++i){
		int u,v;scanf("%d%d",&u,&v);
		g[u].push_back(v),g[v].push_back(u);
	}
	dfs(1,0);
	for(int i=0;i<=k;++i)add(ans,dp[1][i]);
	printf("%lld\n",ans);
}//hellobig_tq//hello


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

typedef long long LL;

#define N 110

LL dp[N][N], f[N];
const int mod = 1e9 + 7;
vector <int> v[N];
int n, k;

void dfs(int x, int pre = 0){
	dp[x][0] = dp[x][k+1] = 1;
	for (auto y : v[x]) if(y != pre) {
		dfs(y, x);
		for(int i = 0; i <= 2 * k; i ++){
			for(int j = 0; j <= 2 * k; j ++){
				int t = (i + j <= 2 * k) ? min(i, j + 1) : max(i, j + 1);
				f[t] = (f[t] + dp[x][i] * dp[y][j]) % mod;
			}
		}
		for(int i = 0; i <= 2 * k; i ++) dp[x][i] = f[i], f[i] = 0;
	}
}

int x, y;

int main() {
	//freopen("in.txt", "r", stdin);
	scanf("%d %d", &n, &k);
	for(int i = 1; i < n; i ++){
		scanf("%d %d", &x, &y);
		v[x].push_back(y);
		v[y].push_back(x);
	}

	dfs(1, 0);

	int ans = 0;
	for(int i = 0; i <= k; i ++) ans = (ans + dp[1][i]) % mod;
	cout << ans << endl;
}


#include <bits/stdc++.h>
#define ll long long
#define MOD ((ll)(1e9 + 7))
using namespace std;
int n, k;
vector<int> e[101];
ll dp[101][42];
void dfs(int x, int p)
{
    dp[x][0] = 1;
    dp[x][2*k] = 1;
    for(auto &j: e[x])
    {
        if(j != p)
        {
            dfs(j, x);
            if(1)
            {
                ll nxtDP[42]{};
                for(int f=0; f<=2*k; f++)
                {
                    for(int g=0; g<=2*k; g++)
                    {
                        if(f<=k && g<=k)
                        {
                            nxtDP[min(f, g+1)] += dp[x][f]*dp[j][g];
                            nxtDP[min(f, g+1)] %= MOD;
                        }
                        if(f>k && g>k)
                        {
                            nxtDP[max(f, g+1)] += dp[x][f]*dp[j][g];
                            nxtDP[max(f, g+1)] %= MOD;
                        }
                        if(f>k && g<=k)
                        {
                            if(f-k <= k-g)
                            {
                                nxtDP[f] += dp[x][f] * dp[j][g];
                                nxtDP[f] %= MOD;
                            }
                            else
                            {
                                nxtDP[g+1] += dp[x][f]*dp[j][g];
                                nxtDP[g+1] %= MOD;
                            }
                        }
                        else
                        {
                            if(k-f >= g-k)
                            {
                                nxtDP[g+1] += dp[x][f] * dp[j][g];
                                nxtDP[g+1] %= MOD;
                            }
                            else
                            {
                                nxtDP[f] += dp[x][f] * dp[j][g];
                                nxtDP[f] %= MOD;
                            }
                        }
                    }
                }
                memcpy(dp[x], nxtDP, sizeof(nxtDP));
            }
        }
    }
}
int main()
{
    cin >> n >> k;
    for(int i=1; i<n; i++)
    {
        int a, b;
        cin >> a >> b;
        a--, b--;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    dfs(0, 0);
    ll res = 0;
    for(int i=0; i<=k; i++)
        res += dp[0][i];
    cout << (res%MOD) << "\n";
    return 0;
}


#include <bits/stdc++.h>
//figured this out 5 minutes after the end of the contest :(
#define ll long long
#define MOD ((ll)(1e9 + 7))
using namespace std;
int n, k;
vector<int> e[101];
ll dp[101][42];
void dfs(int x, int p)
{
    dp[x][0] = 1;
    dp[x][k+1] = 1;
    for(auto &j: e[x])
    {
        if(j != p)
        {
            dfs(j, x);
            if(1)
            {
                ll nxtDP[42]{};
                for(int f=0; f<=2*k; f++)
                {
                    for(int g=0; g<=2*k; g++)
                    {
                        if(f<=k && g<=k)
                        {
                            nxtDP[min(f, g+1)] += dp[x][f]*dp[j][g];
                            nxtDP[min(f, g+1)] %= MOD;
                        }
                        else if(f>k && g>k)
                        {
                            nxtDP[max(f, g+1)] += dp[x][f]*dp[j][g];
                            nxtDP[max(f, g+1)] %= MOD;
                        }
                        else if(f>k && g<=k)
                        {
                            if(f-k <= k-g)
                            {
                                nxtDP[g+1] += dp[x][f] * dp[j][g];
                                nxtDP[g+1] %= MOD;
                            }
                            else
                            {
                                nxtDP[f] += dp[x][f]*dp[j][g];
                                nxtDP[f] %= MOD;
                            }
                        }
                        else if(f<=k && g>k)
                        {
                            if(g-k <= k-f)
                            {
                                nxtDP[f] += dp[x][f] * dp[j][g];
                                nxtDP[f] %= MOD;
                            }
                            else
                            {
                                nxtDP[g+1] += dp[x][f] * dp[j][g];
                                nxtDP[g+1] %= MOD;
                            }
                        }
                    }
                }
                memcpy(dp[x], nxtDP, sizeof(nxtDP));
            }
        }
    }
}
int main()
{
    cin >> n >> k;
    for(int i=1; i<n; i++)
    {
        int a, b;
        cin >> a >> b;
        a--, b--;
        e[a].push_back(b);
        e[b].push_back(a);
    }
    dfs(0, 0);
    ll res = 0;
    for(int i=0; i<=k; i++)
        res += dp[0][i];
    cout << (res%MOD) << "\n";
    return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <complex>
#include <map>
#include <queue>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<pii> vii;
typedef vector<string> vs;
const int mod = 1000000007;

int n, k;
vvi g;
ll d[105][50];
ll sd[105][50];
ll tmp[50];

void dfs(int v, int p) {
//  if (g[v].size() == 0 || g[v].size() == 1 && g[v][0] == p)
    d[v][k+1] = 1;
//  else d[v][1] = 1;
  ll d0 = 1;
  for (int nv : g[v]) {
    if (nv == p) continue;
    dfs(nv, v);
    d0 = d0 * sd[nv][2*k] % mod;
    memset(tmp, 0, sizeof(tmp));
    for (int i = 1; i <= 2*k; ++i) for (int j = 0; j < 2*k; ++j) {
      int x = max(i, j+1);
      if (i + j + 1 <= 2 * k + 1) x = min(i, j + 1);
      tmp[x] = (tmp[x] + d[v][i] * d[nv][j]) % mod;
    }
    memcpy(d[v], tmp, sizeof(tmp));
  }
  sd[v][0] = d[v][0] = d0;
//  for (int i = 0; i <= 2*k; ++i) cerr << v << ' ' << d[v][i] << endl;
  for (int i = 1; i <= 2*k; ++i) sd[v][i] = (sd[v][i-1] + d[v][i]) % mod;
}

int main() {
  cin >> n >> k;
  if (k == 0) {
    cout << 1 << endl;
    return 0;
  }
//  k = min(2*k+1, n + 1);
  g.resize(n);
  for (int i = 0; i < n-1; ++i) {
    int a,b;
    cin >> a >> b;
    --a; --b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  dfs(0, -1);
  cout << sd[0][k] << endl;
  return 0;
}


#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <set>
#include <vector>
#include <cstring>
#include <string>
#include <algorithm>
#include <numeric>
#include <cmath>
#include <complex>
#include <map>
#include <queue>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<vi> vvi;
typedef vector<vl> vvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<int, int> pii;
typedef pair<double, double> pdd;
typedef vector<pii> vii;
typedef vector<string> vs;
const int mod = 1000000007;

int n, k;
vvi g;
ll d[105][50];
ll sd[105][50];
ll tmp[50];

void dfs(int v, int p) {
  if (g[v].size() == 0 || g[v].size() == 1 && g[v][0] == p) d[v][k+1] = 1;
  else d[v][1] = 1;
  ll d0 = 1;
  for (int nv : g[v]) {
    if (nv == p) continue;
    dfs(nv, v);
    d0 = d0 * sd[nv][2*k] % mod;
    memset(tmp, 0, sizeof(tmp));
    for (int i = 1; i <= 2*k; ++i) for (int j = 0; j < 2*k; ++j) {
      tmp[max(i, j+1)] = (tmp[max(i, j+1)] + d[v][i] * d[nv][j]) % mod;
    }
    memcpy(d[v], tmp, sizeof(tmp));
  }
  sd[v][0] = d[v][0] = d0;
//  for (int i = 0; i <= 2*k; ++i) cerr << v << ' ' << d[v][i] << endl;
  for (int i = 1; i <= 2*k; ++i) sd[v][i] = (sd[v][i-1] + d[v][i]) % mod;
}

int main() {
  cin >> n >> k;
  if (k == 0) {
    cout << 1 << endl;
    return 0;
  }
//  k = min(2*k+1, n + 1);
  g.resize(n);
  for (int i = 0; i < n-1; ++i) {
    int a,b;
    cin >> a >> b;
    --a; --b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  dfs(0, -1);
  cout << sd[0][k] << endl;
  return 0;
}


//μ's forever
#include <bits/stdc++.h>
#define mod 1000000007
#define N 105
//#define getchar nc
using namespace std;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
    register int x=0,f=1;register char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
    return x*f;
}
inline void write(register int x)
{
    if(!x)putchar('0');if(x<0)x=-x,putchar('-');
    static int sta[20];register int tot=0;
    while(x)sta[tot++]=x%10,x/=10;
    while(tot)putchar(sta[--tot]+48);
}
struct edge{
    int to,nxt;
}e[N<<1];
int head[N],cnt;
inline void add(register int u,register int v)
{
    e[++cnt]=(edge){v,head[u]};
    head[u]=cnt;
}
int n,k,f[N][N],tmp[N],ans;
inline void dfs(register int x,register int fa)
{
    f[x][0]=f[x][k+1]=1;
    for(register int id=head[x];id;id=e[id].nxt)
    {
        int v=e[id].to;
        if(v==fa)
            continue;
        dfs(v,x);
        for(register int i=0;i<=2*k;++i)
            for(register int j=0;j<=2*k;++j)
            {
                int len;
                if(i+j<=2*k)
                    len=min(i,j+1);
                else
                    len=max(i,j+1);
                if(len<=2*k)
                    tmp[len]=(0ll+tmp[len]+1ll*f[x][i]*f[v][j]%mod)%mod;
            }
        for(register int i=0;i<=2*k;++i)
            f[x][i]=tmp[i],tmp[i]=0;
    }
}
int main()
{
    n=read(),k=read();
    for(register int i=1;i<n;++i)
    {
        int u=read(),v=read();
        add(u,v),add(v,u);
    }
    dfs(1,0);
    for(register int i=0;i<=k;++i)
        ans=(0ll+ans+f[1][i])%mod;
    write(ans),puts("");
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long

#define maxN 111
#define maxK 23

#define mod 1000000007

int n, k, i, j, x, y;
vector<int> list[maxN];
vector<int> act;

ll dp[maxN][maxK][maxK]; // dp[node][need][down]
ll aux[maxK][maxK];

int n1, d1, n2, d2, nn, dd;

inline int get_nn(int n1, int n2) {
    if (n1 != k + 1 && n1 >= d2 + 1) n1 = k + 1;
    if (n2 != k + 1 && n2 >= d1 + 1) n2 = k + 1;

    if (n1 == n2 && n1 == k + 1) return k + 1;

    if (n1 == k + 1) return n2 - 1;
    if (n2 == k + 1) return n1;
    return min(n1, n2 - 1);
}

void compute(int node) {
    static int i, j;
    ll paint;

    if (act.size() == 0) {
        dp[node][k + 1][0] = 1; // paint it
        dp[node][k][k + 1] = 1; // don't paint it
        return;
    }

    // add initial state
    for (i = 1; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            dp[node][ (i == k + 1 ? k + 1 : i - 1) ][min(k + 1, j + 1)] += dp[act[0]][i][j];

    for (i = 0; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            dp[node][i][j] %= mod;

    // add other states
    for (i = 1; i < act.size(); i++) {
        int newn = act[i];

        memcpy(aux, dp[node], sizeof(dp[node]));
        memset(dp[node], 0, sizeof(dp[node]));

        for (n1 = 0; n1 <= k + 1; n1++) {
            for (d1 = (n1 == k + 1 || n1 == 0 ? 0 : k + 1); d1 <= k + 1; d1++) {
                if (aux[n1][d1] == 0) continue;

                for (n2 = 1; n2 <= k + 1; n2++) {
                    for (d2 = (n2 == k + 1 ? 0 : k + 1); d2 <= k + 1; d2++) {
                        nn = get_nn(n1, n2);
                        dd = min(d1, d2 + 1);

                        dp[node][nn][dd] = (dp[node][nn][dd] + aux[n1][d1] * dp[newn][n2][d2]) % mod;
                    }
                }
            }
        }
    }

    dp[node][k][k + 1] += dp[node][k + 1][k + 1] ;
    dp[node][k + 1][k + 1] = 0;

    paint = 0;
    for (i = 0; i <= k + 1; i++) {
        paint += dp[node][0][i];
        dp[node][0][i] = 0;
    }

    for (i = 1; i <= k + 1; i++) {
        //if (dp[node][i][0] != 0) cerr << "err";
        dp[node][i][0] = 0;

        for (j = 1; j <= k + 1; j++)
            paint += dp[node][i][j];
    }

    dp[node][k + 1][0] += paint;
    dp[node][k + 1][0] %= mod;
}

void solve(int node, int root) {
    for (auto to : list[node]) {
        if (to == root) continue;
        solve(to, node);
    }

    act.clear();
    for (auto to : list[node]) {
        if (to == root) continue;
        act.pb(to);
    }

    compute(node);
}

int main()
{
    //freopen("test.in","r",stdin);

    scanf("%d%d", &n, &k);
    for (i = 1; i < n; i++) {
        scanf("%d%d", &x, &y);
        list[x].pb(y);
        list[y].pb(x);
    }

    if (k == 0) {
        printf("1");
        return 0;
    }

    solve(1, 0);

    ll ans = 0;
    for (i = k + 1; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            ans += dp[1][i][j];

    ans %= mod;
    printf("%lld", ans);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long

#define maxN 111
#define maxK 23

#define mod 1000000007

int n, k, i, j, x, y;
vector<int> list[maxN];
vector<int> act;

ll dp[maxN][maxK][maxK]; // dp[node][need][down]
ll aux[maxK][maxK];

int n1, d1, n2, d2, nn, dd;

inline int get_nn(int n1, int n2) {
    if (n1 != k + 1 && n1 >= d2 + 1) n1 = k + 1;
    if (n2 != k + 1 && n2 >= d1 + 1) n2 = k + 1;

    if (n1 == n2 && n1 == k + 1) return k + 1;

    if (n1 == k + 1) return n2 - 1;
    if (n2 == k + 1) return n1;
    return min(n1, n2 - 1);
}

void compute(int node) {
    static int i, j;
    ll paint;

    if (act.size() == 0) {
        dp[node][k + 1][0] = 1; // paint it
        dp[node][k][k + 1] = 1; // don't paint it
        return;
    }

    // add initial state
    for (i = 1; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            dp[node][ (i == k + 1 ? k + 1 : i - 1) ][min(k + 1, j + 1)] += dp[act[0]][i][j];

    for (i = 0; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            dp[node][i][j] %= mod;

    // add other states
    for (i = 1; i < act.size(); i++) {
        int newn = act[i];

        memcpy(aux, dp[node], sizeof(dp[node]));
        memset(dp[node], 0, sizeof(dp[node]));

        for (n1 = 0; n1 <= k + 1; n1++) {
            for (d1 = 0; d1 <= k + 1; d1++) {
                if (aux[n1][d1] == 0) continue;

                for (n2 = 1; n2 <= k + 1; n2++) {
                    for (d2 = 0; d2 <= k + 1; d2++) {
                        nn = get_nn(n1, n2);
                        dd = min(d1, d2 + 1);

                        dp[node][nn][dd] = (dp[node][nn][dd] + aux[n1][d1] * dp[newn][n2][d2]) % mod;
                    }
                }
            }
        }
    }

    dp[node][k][k + 1] += dp[node][k + 1][k + 1] ;
    dp[node][k + 1][k + 1] = 0;

    paint = 0;
    for (i = 0; i <= k + 1; i++) {
        paint += dp[node][0][i];
        dp[node][0][i] = 0;
    }

    for (i = 1; i <= k + 1; i++) {
        //if (dp[node][i][0] != 0) cerr << "err";
        dp[node][i][0] = 0;

        for (j = 1; j <= k + 1; j++)
            paint += dp[node][i][j];
    }

    dp[node][k + 1][0] += paint;
    dp[node][k + 1][0] %= mod;
}

void solve(int node, int root) {
    for (auto to : list[node]) {
        if (to == root) continue;
        solve(to, node);
    }

    act.clear();
    for (auto to : list[node]) {
        if (to == root) continue;
        act.pb(to);
    }

    compute(node);
}

int main()
{
    //freopen("test.in","r",stdin);

    scanf("%d%d", &n, &k);
    for (i = 1; i < n; i++) {
        scanf("%d%d", &x, &y);
        list[x].pb(y);
        list[y].pb(x);
    }

    if (k == 0) {
        printf("1");
        return 0;
    }

    solve(1, 0);

    ll ans = 0;
    for (i = k + 1; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            ans += dp[1][i][j];

    ans %= mod;
    printf("%lld", ans);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

#define mp make_pair
#define pb push_back
#define ll long long

#define maxN 111
#define maxK 23

#define mod 1000000007

int n, k, i, j, x, y;
vector<int> list[maxN];
vector<int> act;

ll dp[maxN][maxK][maxK]; // dp[node][need][down]
ll aux[maxK][maxK];

int n1, d1, n2, d2, nn, dd;

inline int get_nn(int n1, int n2) {
    if (n1 != k + 1 && n1 >= d2 + 1) n1 = k + 1;
    if (n2 != k + 1 && n2 >= d1 + 1) n2 = k + 1;

    if (n1 == k + 1) return n2 - 1;
    if (n2 == k + 1) return n1;
    return min(n1, n2 - 1);
}

void compute(int node) {
    static int i, j;
    ll paint;

    if (act.size() == 0) {
        dp[node][k + 1][0] = 1; // paint it
        dp[node][k][k + 1] = 1; // don't paint it
        return;
    }

    // add initial state
    for (i = 1; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            dp[node][ (i == k + 1 ? k + 1 : i - 1) ][min(k + 1, j + 1)] += dp[act[0]][i][j];

    for (i = 0; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            dp[node][i][j] %= mod;

    // add other states
    for (i = 1; i < act.size(); i++) {
        int newn = act[i];

        memcpy(aux, dp[node], sizeof(dp[node]));
        memset(dp[node], 0, sizeof(dp[node]));

        for (n1 = 0; n1 <= k + 1; n1++) {
            for (d1 = 0; d1 <= k + 1; d1++) {
                if (aux[n1][d1] == 0) continue;

                for (n2 = 1; n2 <= k + 1; n2++) {
                    for (d2 = 0; d2 <= k + 1; d2++) {
                        nn = get_nn(n1, n2);
                        dd = min(d1, d2 + 1);

                        dp[node][nn][dd] = (dp[node][nn][dd] + aux[n1][d1] * dp[newn][n2][d2]) % mod;
                    }
                }
            }
        }
    }

    dp[node][k][k + 1] += dp[node][k + 1][k + 1] ;
    dp[node][k + 1][k + 1] = 0;

    paint = 0;
    for (i = 0; i <= k + 1; i++) {
        paint += dp[node][0][i];
        dp[node][0][i] = 0;
    }

    for (i = 1; i <= k + 1; i++) {
        //if (dp[node][i][0] != 0) cerr << "err";
        dp[node][i][0] = 0;

        for (j = 1; j <= k + 1; j++)
            paint += dp[node][i][j];
    }

    dp[node][k + 1][0] += paint;
    dp[node][k + 1][0] %= mod;
}

void solve(int node, int root) {
    for (auto to : list[node]) {
        if (to == root) continue;
        solve(to, node);
    }

    act.clear();
    for (auto to : list[node]) {
        if (to == root) continue;
        act.pb(to);
    }

    compute(node);
}

int main()
{
    //freopen("test.in","r",stdin);

    scanf("%d%d", &n, &k);
    for (i = 1; i < n; i++) {
        scanf("%d%d", &x, &y);
        list[x].pb(y);
        list[y].pb(x);
    }

    if (k == 0) {
        printf("1");
        return 0;
    }

    solve(1, 0);

    ll ans = 0;
    for (i = 1; i <= k + 1; i++)
        for (j = 0; j <= k + 1; j++)
            ans += dp[1][i][j];

    ans %= mod;
    printf("%lld", ans);

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <queue>

using namespace std;
#define Fill(a, b) memset(a, b, sizeof(a))
#define Debug(x) cout<<#x<<"="<<(x)<<endl;
#define fop(i,a,b) for(i=a;i<b;i++)
#define fope(i,a,b) for(i=a;i<=b;i++)
#define fom(i,a,b) for(i=a;i>b;i--)
#define fome(i,a,b) for(i=a;i>=b;i--)
typedef long long LL;
typedef pair<int, int> P;
const LL inf = 1LL << 61;
const LL mod = 1e9+7;
const int max_n = 110;

int n, k;
LL old_dp[max_n];
LL dp[max_n][max_n];
vector<int> G[max_n];
void dfs(int u, int fa);
int main()
{
    int i = 0, j = 0;
    int a, b;
    scanf("%d%d", &n, &k);
    fop(i,0,n-1)
    {
        scanf("%d%d", &a, &b);
        G[a].push_back(b);
        G[b].push_back(a);
    }
    if(n==1)
    {
        puts("1");
        return 0;
    }
    Fill(dp, 0);
    dfs(1, -1);
    LL ans = 0;
    for(i = 0; i <= k; i++)
    {
        ans += dp[1][i];
        ans %= mod;
    }
    cout << ans << endl;

    return 0;
}
void dfs(int u, int fa)
{
    if(G[u].size()==1&&fa!=-1)
    {
        dp[u][0] = 1;
        dp[u][k+1] = 1;//�����
        return ;
    }
    int i, j, s, t, v;
    bool flag = false;
    for(i = 0; i < G[u].size(); i++)
    {
        v = G[u][i];
        if(v==fa)
            continue;
        dfs(v, u);
        if(!flag)
        {
            flag = true;
            for(j = 0; j <= 2*k+1; j++)
            {
                dp[u][j+1] = dp[v][j];
            }
        }
        else
        {
            for(s = 0; s < max_n; s++)
            {
                old_dp[s] = dp[u][s];
                dp[u][s] = 0;
            }
            for(s = 0; s <= 2*k; s++)
            {
                for(t = 1; t <= 2*k+1; t++)
                {
                    if(s+t <= 2*k)
                    {
                        dp[u][min(s+1,t)] += dp[v][s]*old_dp[t];
                        dp[u][min(s+1,t)] %= mod;
                    }
                    else
                    {
                        dp[u][max(s+1,t)] += dp[v][s]*old_dp[t];
                        dp[u][max(s+1,t)] %= mod;
                    }
                }
            }
        }
    }
    for(i = 1; i <= 2*k+1; i++)
    {
        dp[u][0] += dp[u][i];
        dp[u][0] %= mod;
    }
}


#include <bits/stdc++.h>

#ifdef AZN

#include "Azn.cpp"

#else
#define pln(...)
#define dbgln(...)
#endif

using namespace std;

template <int MOD> struct IntMod {
  IntMod() : val_(0) {}

  IntMod(long long x)
    : val_((int) (x % MOD)) {
    if (val_ < 0)
      val_ += MOD;
  }

  IntMod& operator+=(const IntMod& x) {
    val_ += x.val_;
    if (val_ >= MOD)
      val_ -= MOD;
    return *this;
  }

  IntMod operator+(const IntMod& x) const {
    IntMod res(*this);
    return res += x;
  }

  IntMod& operator-=(const IntMod& x) {
    val_ -= x.val_;
    if (val_ < 0)
      val_ += MOD;
    return *this;
  }

  IntMod operator-(const IntMod& x) const {
    IntMod res(*this);
    return res -= x;
  }

  IntMod& operator*=(const IntMod& x) {
    val_ = (int) ((long long) (val_) * x.val_ % MOD);
    return *this;
  }

  IntMod operator*(const IntMod& x) const {
    IntMod res(*this);
    return res *= x;
  }

  IntMod& operator/=(const IntMod& x) {
    return *this *= x.inv();
  }

  IntMod operator/(const IntMod& x) const {
    IntMod res(*this);
    return res /= x;
  }

  IntMod power(int expon) const {
    IntMod ans, temp(*this);
    ans.val_ = 1;
    for (; expon > 0; expon >>= 1) {
      if (expon & 1)
        ans *= temp;
      temp *= temp;
    }
    return ans;
  }

  IntMod inv() const {
    return power(MOD - 2);
  }

  operator int() const {
    return val_;
  }

  friend ostream& operator<<(ostream& out, const IntMod& x) {
    return out << x.val_;
  }

 private:
  int val_;
};

typedef long long ll;
typedef double dd;
typedef IntMod<1000000007> Int;

const int MAXK = 20;
const int MAXN = 128;

struct State {
  // ways[i][j] = # of ways to color subtree with:
  //  closest black vertex i edges away, K+1 if no such vertex exists
  //  farthest white uncovered vertex j edges away, -1 if no such vertex exists
  // optimization: only ways[K+1][j] and ways[i][-1] are useful
  // as if there in an uncovered white vertex, we need a closer black vertex than one in subtree
  Int ways[MAXK + 2][MAXK + 3];

  Int& get(int i, int j) {
    if (j == -1) j = MAXK + 2;
    return ways[i][j];
  }
};

struct Vertex {
  State state;
  vector<Vertex*> adj;

  void merge(State& child, const int K) {
    static State res;
    memset(&res, 0, sizeof(State));
    for (int a = 0; a <= K + 1; ++a) {
      for (int b = -1; b <= K; ++b) {
        for (int x = 0; x <= K + 1; ++x) {
          for (int y = -1; y <= K; ++y) {
            const int i = min(a, x + 1);
            const int j = i + max(b, y + 1) <= K ? -1 : max(b, y + 1);
            res.get(i, j) += state.get(a, b) * child.get(x, y);
            /*if (state.get(a, b) * child.get(x, y) >= 1) {
              pln(i, j, a, b, x, y);
              pln(res.get(i, j), state.get(a, b), child.get(x, y));
            }*/
          }
        }
      }
    }
    state = res;
    cerr << endl;
  }

  void dfs(const Vertex* par, const int K) {
    memset(&state, 0, sizeof(state));
    state.get(0, -1) = 1; // color
    state.get(K + 1, 0) = 1; // don't color
    for (const auto child : adj) {
      if (child != par) {
        child->dfs(this, K);
        merge(child->state, K);
      }
    }
  }
};

void solve(const int test_num) {
  (void) test_num;
  int N, K;
  cin >> N >> K;
  vector<Vertex> verts(N + 1);
  for (int i = 0, u, v; i < N - 1; ++i) {
    cin >> u >> v;
    verts[u].adj.push_back(&verts[v]);
    verts[v].adj.push_back(&verts[u]);
  }
  verts[1].dfs(nullptr, K);
  Int res = 0;
  for (int i = 0; i <= K; ++i) {
    res += verts[1].state.get(i, -1);
  }
  cout << res << endl;
}

void init() {

}

int main() {
#ifdef AZN
  const auto start_time = chrono::system_clock::now();
  freopen("/home/azneye/Documents/Stuff/input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  init();
  int tests = 1;
//  cin >> tests;
  for (int test = 1; test <= tests; ++test) {
    solve(test);
  }
#ifdef AZN
  cerr << "Took: " << ((chrono::system_clock::now() - start_time).count() / 1e9) << " s" << endl;
#endif
  return 0;
}


#include <bits/stdc++.h>

#ifdef AZN

#include "Azn.cpp"

#else
#define pln(...)
#define dbgln(...)
#endif

using namespace std;

template <int MOD> struct IntMod {
  IntMod() : val_(0) {}

  IntMod(long long x)
    : val_((int) (x % MOD)) {
    if (val_ < 0)
      val_ += MOD;
  }

  IntMod& operator+=(const IntMod& x) {
    val_ += x.val_;
    if (val_ >= MOD)
      val_ -= MOD;
    return *this;
  }

  IntMod operator+(const IntMod& x) const {
    IntMod res(*this);
    return res += x;
  }

  IntMod& operator-=(const IntMod& x) {
    val_ -= x.val_;
    if (val_ < 0)
      val_ += MOD;
    return *this;
  }

  IntMod operator-(const IntMod& x) const {
    IntMod res(*this);
    return res -= x;
  }

  IntMod& operator*=(const IntMod& x) {
    val_ = (int) ((long long) (val_) * x.val_ % MOD);
    return *this;
  }

  IntMod operator*(const IntMod& x) const {
    IntMod res(*this);
    return res *= x;
  }

  IntMod& operator/=(const IntMod& x) {
    return *this *= x.inv();
  }

  IntMod operator/(const IntMod& x) const {
    IntMod res(*this);
    return res /= x;
  }

  IntMod power(int expon) const {
    IntMod ans, temp(*this);
    ans.val_ = 1;
    for (; expon > 0; expon >>= 1) {
      if (expon & 1)
        ans *= temp;
      temp *= temp;
    }
    return ans;
  }

  IntMod inv() const {
    return power(MOD - 2);
  }

  operator int() const {
    return val_;
  }

  friend ostream& operator<<(ostream& out, const IntMod& x) {
    return out << x.val_;
  }

 private:
  int val_;
};

typedef long long ll;
typedef double dd;
typedef IntMod<1000000007> Int;

const int MAXK = 20;
const int MAXN = 128;

struct State {
  // ways[i][j] = # of ways to color subtree with:
  //  closest black vertex i edges away, K+1 if no such vertex exists
  //  farthest white uncovered vertex j edges away, -1 if no such vertex exists
  // optimization: only ways[K+1][j] and ways[i][-1] are useful
  // as if there in an uncovered white vertex, we need a closer black vertex than one in subtree
  Int ways[MAXK + 2][MAXK + 3];

  Int& get(int i, int j) {
    if (j == -1) j = MAXK + 2;
    return ways[i][j];
  }
};

struct Vertex {
  State state;
  vector<Vertex*> adj;

  void merge(State& child, const int K) {
    static State res;
    memset(&res, 0, sizeof(State));
    for (int a = 0; a <= K + 1; ++a) {
      for (int b = -1; b <= K; ++b) {
        if (!(a == K + 1 || b == -1))
          break;
        for (int x = 0; x <= K + 1; ++x) {
          for (int y = -1; y <= K; ++y) {
            if (!(x == K + 1 || y == -1))
              break;
            const int i = min(a, x + 1);
            const int j = i + max(b, y + 1) <= K ? -1 : max(b, y + 1);
            res.get(i, j) += state.get(a, b) * child.get(x, y);
            /*if (state.get(a, b) * child.get(x, y) >= 1) {
              pln(i, j, a, b, x, y);
              pln(res.get(i, j), state.get(a, b), child.get(x, y));
            }*/
          }
        }
      }
    }
    state = res;
  }

  void dfs(const Vertex* par, const int K) {
    memset(&state, 0, sizeof(state));
    state.get(0, -1) = 1; // color
    state.get(K + 1, 0) = 1; // don't color
    for (const auto child : adj) {
      if (child != par) {
        child->dfs(this, K);
        merge(child->state, K);
      }
    }
  }
};

void solve(const int test_num) {
  (void) test_num;
  int N, K;
  cin >> N >> K;
  vector<Vertex> verts(N + 1);
  for (int i = 0, u, v; i < N - 1; ++i) {
    cin >> u >> v;
    verts[u].adj.push_back(&verts[v]);
    verts[v].adj.push_back(&verts[u]);
  }
  verts[1].dfs(nullptr, K);
  Int res = 0;
  for (int i = 0; i <= K; ++i) {
    res += verts[1].state.get(i, -1);
  }
  cout << res << endl;
}

void init() {

}

int main() {
#ifdef AZN
  const auto start_time = chrono::system_clock::now();
  freopen("/home/azneye/Documents/Stuff/input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  init();
  int tests = 1;
//  cin >> tests;
  for (int test = 1; test <= tests; ++test) {
    solve(test);
  }
#ifdef AZN
  cerr << "Took: " << ((chrono::system_clock::now() - start_time).count() / 1e9) << " s" << endl;
#endif
  return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#define upd(x, y) ((x += (long long)y) %= MOD)
#define MOD 1000000007
using namespace std;
int n, k, ans, dp[105][45], res[45];
int lst[105], to[205], pre[205], tot;
inline void add_edge(int u, int v)
{
	to[tot] = v;
	pre[tot] = lst[u];
	lst[u] = tot++;
}
void dfs(int u, int fa = -1)
{
	dp[u][0] = 1;
	dp[u][k + 1] = 1;
	for (int i = lst[u]; ~i; i = pre[i])
	{
		int v = to[i];
		if (v == fa)
			continue;
		dfs(v, u);
		memset(res, 0, sizeof(res));
		for (int j = 0; j <= (k << 1 | 1); j++)
		{
			for (int x = 0; x <= k << 1; x++)
			{
				if (j + x <= k << 1)
					upd(res[min(j, x + 1)], dp[u][j] * dp[v][x]);
				else
					upd(res[max(j, x + 1)], dp[u][j] * dp[v][x]);
			}
		}
		memcpy(dp[u], res, sizeof(res));
	}
}
int main()
{
	// freopen("736C.in", "r", stdin);
	memset(lst, -1, sizeof(lst));
	scanf("%d%d", &n, &k);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		add_edge(--u, --v);
		add_edge(v, u);
	}
	dfs(0);
	for (int i = 0; i <= k; i++)
		upd(ans, dp[0][i]);
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstring>
#include <cstdio>
#define upd(x, y) ((x += y) %= MOD)
#define MOD 1000000007
using namespace std;
typedef long long ll;
ll ans, dp[105][45], res[45];
int lst[105], to[205], pre[205], tot, n, k;
inline void add_edge(int u, int v)
{
	to[tot] = v;
	pre[tot] = lst[u];
	lst[u] = tot++;
}
void dfs(int u, int fa = -1)
{
	dp[u][0] = 1;
	dp[u][k + 1] = 1;
	for (int i = lst[u]; ~i; i = pre[i])
	{
		int v = to[i];
		if (v == fa)
			continue;
		dfs(v, u);
		memset(res, 0, sizeof(res));
		for (int j = 0; j <= (k << 1 | 1); j++)
		{
			for (int x = 0; x <= k << 1; x++)
			{
				if (j + x <= k << 1)
					upd(res[min(j, x + 1)], dp[u][j] * dp[v][x]);
				else
					upd(res[max(j, x + 1)], dp[u][j] * dp[v][x]);
			}
		}
		memcpy(dp[u], res, sizeof(res));
	}
}
int main()
{
	// freopen("736C.in", "r", stdin);
	memset(lst, -1, sizeof(lst));
	scanf("%d%d", &n, &k);
	for (int i = 1; i < n; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		add_edge(--u, --v);
		add_edge(v, u);
	}
	dfs(0);
	for (int i = 0; i <= k; i++)
		upd(ans, dp[0][i]);
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAXN = 101;
const int MAXK = 22;
const long long INF = 1000000007;

int N, K;
vector<int> X[MAXN];
long long f[MAXN][MAXK][MAXK];

int dfs(int a, int fa) {
    long long g[MAXK][MAXK];
    f[a][0][K] = f[a][1][0] = 1;
    for (int t = 0; t < X[a].size(); ++t) {
        if (X[a][t] == fa) continue;
        int b = X[a][t];
        dfs(b, a);
        memset(g, 0, sizeof(g));
        for (int i = 0; i <= K; ++i)
         for (int j = 0; j <= K; ++j)
          for (int k = 0; k <= K; ++k)
           for (int l = 0; l <= K; ++l) {
               int p = max(l >= i ? 0 : i, j >= k ? 0 : k + 1);
               int q = max(j, l - 1);
               g[p][q] = (g[p][q] + f[a][i][j] * f[b][k][l]) % INF;
           }

        for (int i = 0; i <= K + 1; ++i)
         for (int j = 0; j <= K + 1; ++j) f[a][i][j] = g[i][j];
    }
    return 0;
}

int main() {
    cin >> N >> K;
    for (int i = 1; i < N; ++i) {
        int a, b;
        cin >> a >> b;
        X[a].push_back(b);
        X[b].push_back(a);
    }
    dfs(1, -1);
    int ans = 0;
    for (int i = 0; i <= K; ++i) ans = (ans + f[1][0][i]) % INF;
    cout << ans << endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

const int MAXN = 101;
const int MAXK = 22;
const long long INF = 1000000007;

int N, K;
vector<int> X[MAXN];
long long f[MAXN][MAXK][MAXK];

int dfs(int a, int fa) {
    long long g[MAXK][MAXK];
    f[a][0][K] = f[a][1][0] = 1;
    for (int t = 0; t < X[a].size(); ++t) {
        if (X[a][t] == fa) continue;
        int b = X[a][t];
        dfs(b, a);
        memset(g, 0, sizeof(g));
        for (int i = 0; i <= K; ++i)
         for (int j = 0; j <= K; ++j)
          for (int k = 0; k <= K; ++k)
           for (int l = 0; l <= K; ++l) {
               int p = max(l >= i ? 0 : i, j >= k ? 0 : k + 1);
               int q = max(j, l - 1);
               g[p][q] = (g[p][q] + f[a][i][j] * f[b][k][l]) % INF;
           }

        for (int i = 0; i <= K + 1; ++i)
         for (int j = 0; j <= K + 1; ++j) f[a][i][j] = g[i][j];
    }
    return 0;
}

int main() {
    cin >> N >> K;
    for (int i = 1; i < N; ++i) {
        int a, b;
        cin >> a >> b;
        X[a].push_back(b);
        X[b].push_back(a);
    }
    dfs(1, -1);
    int ans = 0;
    for (int i = 0; i <= K; ++i) ans = (ans + f[1][0][i]) % INF;
    cout << ans << endl;
    return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

int n,maxd,x,y;
int a[205],b[105],nxt[205],num,fa[105];
int l,r,q[105];
int dp[105][25][25];
int tmp[2][25][25];
const int mod=1e9+7;
void add(int x,int y)
{
	++num;a[num]=y;nxt[num]=b[x];b[x]=num;
}
void work(int x)
{
	int son=0;
	for (int i=b[x];i!=0;i=nxt[i])
	{
		int y=a[i];if (y==fa[x]) continue;
		if (son==0)
		{
			for (int j=0;j<=maxd+2;++j) for (int k=0;k<=maxd+2;++k) tmp[0][j][k]=dp[y][j][k];
			son++;
			continue;
		}
		son++;
		for (int j=0;j<=maxd+2;++j) for (int k=0;k<=maxd+2;++k) tmp[1][j][k]=0;
		for (int j=0;j<=maxd+2;++j) for (int k=0;k<=maxd+2;++k)
			for (int p=0;p<=maxd+2;++p) for (int q=0;q<=maxd+2;++q)
			{
				int minx,maxx;
				minx=min(j,p);maxx=maxd+2;
				if (q!=maxd+2&&j+2>q) maxx=min(maxx,q);
				if (k!=maxd+2&&p+2>k) maxx=min(maxx,k);
				tmp[1][minx][maxx]+=1LL*tmp[0][j][k]*dp[y][p][q]%mod;tmp[1][minx][maxx]%=mod;
			}
		for (int j=0;j<=maxd+2;++j) for (int k=0;k<=maxd+2;++k) tmp[0][j][k]=tmp[1][j][k];
	}
	if (son==0)
	{
		dp[x][0][maxd+2]=1;
		dp[x][maxd+2][maxd]=1;
	}
	else
	{
		for (int j=0;j<=maxd+2;++j) for (int k=1;k<=maxd+2;++k)
		{
			int minx,maxx;
			//black
			dp[x][0][maxd+2]+=tmp[0][j][k];dp[x][0][maxd+2]%=mod;
			//white
			minx=min(j+1,maxd+2);
			maxx=maxd+2;
			if (j+1>maxd) maxx=maxd;
			if (k!=maxd+2) maxx=min(maxx,k-1);

			if (maxx>=0)
			{
				dp[x][minx][maxx]+=tmp[0][j][k];
				dp[x][minx][maxx]%=mod;
			}
		}
	}
}
int main()
{
	scanf("%d%d",&n,&maxd);
	for (int i=1;i<n;++i)
	{
		scanf("%d%d",&x,&y);
		add(x,y);add(y,x);
	}
	l=1;r=1;q[1]=1;
	fa[1]=0;
	while (l<=r)
	{
		x=q[l];
		for (int i=b[x];i!=0;i=nxt[i])
		{
			y=a[i];if (y==fa[x]) continue;
			fa[y]=x;++r;q[r]=y;
		}
		++l;
	}
	for (int i=n;i>=1;--i) work(q[i]);
	for (int i=1;i<=n;++i)
	{
		for (int j=0;j<=maxd+2;++j)
			for (int k=0;k<=maxd+2;++k) ;//cout<<i<<" "<<j<<" "<<k<<" "<<dp[i][j][k]<<endl;
	}
	//dp[i][j][k] i zi shu  juli i zui jin de heidian juli wei j  juli i zui yuan de baidian hai neng zou k
	int ans=0;
	for (int i=0;i<=maxd+2;++i) ans+=dp[1][i][maxd+2],ans%=mod;
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 105, MOD = 1e9 + 7, K = 25;
int n, k, f[N][K][K], sum[N][K][K];
vector<int> G[N];
void dfs(int x, int p) {
	vector<int> child;
	for (int u : G[x]) {
		if (u == p) continue;
		dfs(u, x);
		child.push_back(u);
	}
	for (int up = 1; up <= k + 1; ++ up) {
		f[x][up][0] = 1;
		for (int i : child) f[x][up][0] = 1LL * f[x][up][0] * sum[i][1][0] % MOD;
		if (child.empty() && up <= k) (++ f[x][up][k + 1]) %= MOD;
		for (int down = 1; down <= k + 1; ++ down) {
			if (min(down, up) > k) continue;
			for (int i = 0; i < (int) child.size(); ++ i) {
				if (child.size() == 1) {
					int u = child[i];
					(f[x][up][down] += f[u][min(up + 1, k + 1)][down - 1]) %= MOD;
				}
				else for (int down2 = down; down2 <= k + 1; ++ down2) {
					int UP = min(min(down + 1, up + 1), k + 1);
					vector<int> mul_left, mul_right;
					int las = 1;
					for (int j = 0; j < (int) child.size(); ++ j) {
						if (j != i) las = 1LL * las * sum[child[j]][UP][down2] % MOD;
						mul_left.push_back(las);
					}
					las = 1;
					for (int j = (int) child.size() - 1; j >= 0; -- j) {
						if (j != i) las = 1LL * las * (sum[child[j]][UP][down2] + f[child[j]][UP][down2 - 1]) % MOD;
						mul_right.push_back(las);
					}
					reverse(mul_right.begin(), mul_right.end());
					for (int j = (down2 == down) ? i + 1 : 0; j < (int) child.size(); ++ j) {
						if (j == i) continue;
						int u = child[i], v = child[j];
						int tmp = 1LL * f[u][min(min(down2 + 1, up + 1), k + 1)][down - 1] * f[v][UP][down2 - 1] % MOD;
						/*for (int k = 0; k < (int) child.size(); ++ k) {
							if (k == i || k == j) continue;
							int w = child[k];
							int cur = sum[w][UP][down2];
							if (k > j) (cur += f[w][UP][down2 - 1]) %= MOD;
							tmp = 1LL * tmp * cur % MOD;
						}*/
						if (j) tmp = 1LL * tmp * mul_left[j - 1] % MOD;
						if (j < (int) child.size() - 1) tmp = 1LL * tmp * mul_right[j + 1] % MOD;
						(f[x][up][down] += tmp) %= MOD;
					}
				}
			}
		}
		(f[x][up][k] += f[x][up][k + 1]) %= MOD;
		f[x][up][k + 1] = 0;
		for (int down = k + 1; down >= 0; -- down) sum[x][up][down] = (f[x][up][down] + sum[x][up][down + 1]) % MOD;
	}
}
bool debug = 0;
int main() {
	scanf("%d%d", &n, &k);
	if (debug) {
		n = 100;
		k = 20;
	}
	for (int i = 1; i < n; ++ i) {
		int u, v;
		if (debug) {
			//u = rand() % i + 1;
			u = 1;
			//u = i;
			v = i + 1;
		}
		else scanf("%d%d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	int root = 1;
	dfs(root, 0);
	printf("%d\n", sum[root][k + 1][0]);
}


#include <bits/stdc++.h>
using namespace std;
const int N = 105, MOD = 1e9 + 7, K = 25;
int n, k, f[N][K][K], sum[N][K][K];
vector<int> G[N];
void dfs(int x, int p) {
	vector<int> child;
	for (int u : G[x]) {
		if (u == p) continue;
		dfs(u, x);
		child.push_back(u);
	}
	for (int up = 1; up <= k + 1; ++ up) {
		f[x][up][0] = 1;
		for (int i : child) f[x][up][0] = 1LL * f[x][up][0] * sum[i][1][0] % MOD;
		if (child.empty() && up <= k) (++ f[x][up][0]) %= MOD;
		for (int down = 1; down <= k + 1; ++ down) {
			if (min(down, up) > k) continue;
			for (int i = 0; i < (int) child.size(); ++ i) {
				if (child.size() == 1) {
					int u = child[i];
					(f[x][up][down] += f[u][min(up + 1, k + 1)][down - 1]) %= MOD;
				}
				else for (int down2 = down; down2 <= k + 1; ++ down2) {
					for (int j = (down2 == down) ? i + 1 : 0; j < (int) child.size(); ++ j) {
						if (j == i) continue;
						int u = child[i], v = child[j], UP = min(min(down + 1, up + 1), k + 1);
						int tmp = 1LL * f[u][min(min(down2 + 1, up + 1), k + 1)][down - 1] * f[v][UP][down2 - 1] % MOD;
						for (int k = 0; k < (int) child.size(); ++ k) {
							if (k == i || k == j) continue;
							int w = child[k];
							int cur = sum[w][UP][down2];
							if (k > j) cur += f[w][UP][down2 - 1];
							tmp = 1LL * tmp * cur % MOD;
						}
						(f[x][up][down] += tmp) %= MOD;
					}
				}
			}
		}
		for (int down = k + 1; down >= 0; -- down) sum[x][up][down] = f[x][up][down] + sum[x][up][down + 1];
	}
}
int main() {
	scanf("%d%d", &n, &k);
	for (int i = 1; i < n; ++ i) {
		int u, v;
		scanf("%d%d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1, 0);
	//printf("%d--\n", sum[2][1][0]);
	printf("%d\n", sum[1][k + 1][0]);
}


#include <bits/stdc++.h>
using namespace std;
const int N = 105, MOD = 1e9 + 7, K = 25;
int n, k, f[N][K][K], sum[N][K][K];
vector<int> G[N];
void dfs(int x, int p) {
	vector<int> child;
	for (int u : G[x]) {
		if (u == p) continue;
		dfs(u, x);
		child.push_back(u);
	}
	for (int up = 1; up <= k + 1; ++ up) {
		f[x][up][0] = 1;
		for (int i : child) f[x][up][0] = 1LL * f[x][up][0] * sum[i][1][0] % MOD;
		if (child.empty() && up <= k) (++ f[x][up][k + 1]) %= MOD;
		for (int down = 1; down <= k + 1; ++ down) {
			if (min(down, up) > k) continue;
			for (int i = 0; i < (int) child.size(); ++ i) {
				if (child.size() == 1) {
					int u = child[i];
					(f[x][up][down] += f[u][min(up + 1, k + 1)][down - 1]) %= MOD;
				}
				else for (int down2 = down; down2 <= k + 1; ++ down2) {
					for (int j = (down2 == down) ? i + 1 : 0; j < (int) child.size(); ++ j) {
						if (j == i) continue;
						int u = child[i], v = child[j], UP = min(min(down + 1, up + 1), k + 1);
						int tmp = 1LL * f[u][min(min(down2 + 1, up + 1), k + 1)][down - 1] * f[v][UP][down2 - 1] % MOD;
						for (int k = 0; k < (int) child.size(); ++ k) {
							if (k == i || k == j) continue;
							int w = child[k];
							int cur = sum[w][UP][down2];
							if (k > j) (cur += f[w][UP][down2 - 1]) %= MOD;
							tmp = 1LL * tmp * cur % MOD;
						}
						(f[x][up][down] += tmp) %= MOD;
					}
				}
			}
		}
		(f[x][up][k] += f[x][up][k + 1]) %= MOD;
		f[x][up][k + 1] = 0;
		for (int down = k + 1; down >= 0; -- down) sum[x][up][down] = (f[x][up][down] + sum[x][up][down + 1]) % MOD;
	}
}
int main() {
	scanf("%d%d", &n, &k);
	for (int i = 1; i < n; ++ i) {
		int u, v;
		scanf("%d%d", &u, &v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1, 0);
	//printf("%d--\n", sum[2][1][0]);
	printf("%d\n", sum[1][k + 1][0]);
}


// ==========================================================================
//
//                   Bismillah ir-Rahman ir-Rahim
//
// ==========================================================================

/*************************************************************************
  ████      ▀███▀    ▄▄▄▀▀▀▀▄▄▄   █▀▄▀▄▀▄▀▄▀▄█  ▀███▀   ████       ████
  ███ █      ███     ███    ███              █   ███    ███ █     █ ███
  ███  █     ███     ███    ███            █     ███    ███  █   █  ███
  ███   █    ███     ███    ███          █       ███    ███   █▄█   ███
  ███    █   ███     ███▀▀▀▀███        █         ███    ███         ███
  ███     █  ███     ███    ███      █           ███    ███         ███
  ███      █ ███     ███    ███    █             ███    ███         ███
 ▄███▄      ████     ███    ███   █▄▀▄▀▄▀▄▀▄▀█  ▄███▄  ▄███▄       ▄███▄
**************************************************************************/

// Pre_code

#include <bits/stdc++.h>

// header file

#include <sstream>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <complex>
#include <cmath>
#include <iostream>
#include <iomanip>
#include <string>
#include <utility>
#include <vector>
#include <algorithm>
#include <bitset>
#include <list>
#include <string.h>
#include <assert.h>
#include <time.h>
#include <fstream>
#include <numeric>
#include <cstring>
//#include <unordered_map>
//#include <unordered_set>

using namespace std ;

//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//
//using namespace __gnu_pbds;

//define function

#pragma                 comment(linker, "/STACK:667772160")
#define forln(i,a,n)    for(int i=a ; i<n ; i++)
#define foren(i,a,n)    for(int i=a ; i<=n ; i++)
#define forg0(i,a,n)    for(int i=a ; i>n ; i--)
#define fore0(i,a,n)    for(int i=a ; i>=n ; i--)
#define pb              push_back
#define pp              pop_back
#define clr(a,b)        memset(a,b,sizeof(a))
#define sf1(a)          scanf("%d",&a)
#define sf2(a,b)        scanf("%d %d",&a,&b)
#define sf1ll(a)        scanf("%lld",&a)
#define sf2ll(a,b)      scanf("%lld %lld",&a,&b)
#define pii             acos(-1.0)
#define jora_int        pair<int,int>
#define jora_ll         pair<long long,long long>
#define max3(a,b,c)     max(a,max(b,c))
#define min3(a,b,c)     min(a,min(b,c))
#define Max             2000000000+9
#define sz              1000+7
#define Mod             1000000007
#define EPS             1e-7
#define ll              long long
#define ull             unsigned long long
#define fs              first
#define sc              second
#define wait            system("pause")
#define sf              scanf
#define pf              printf
#define mp              make_pair
#define ps              pf("PASS\n")
#define Read            freopen("00.txt","r",stdin)
#define Write           freopen("C:\\Users\\RONIN-47\\Desktop\\input_output\\output.txt","w",stdout)
#define num_of_bit(a)   __builtin_popcount(a) // for long long use ll as suffix
#define lsb(a)          __builtin_ffs(a) // for long long use ll as suffix
#define msb(a)          32-__builtin_clz(a) // for long long use ll as suffix
#define inf             10000000000000000LL

// typedef

typedef vector<int> VI;
typedef vector<ll> VL;
typedef vector<jora_int> VJ ;
typedef vector<jora_ll> VJL ;

//debug

template<class T1> void deb(T1 e1)
{
    cout<<e1<<endl;
}
template<class T1,class T2> void deb(T1 e1,T2 e2)
{
    cout<<e1<<" "<<e2<<endl;
}
template<class T1,class T2,class T3> void deb(T1 e1,T2 e2,T3 e3)
{
    cout<<e1<<" "<<e2<<" "<<e3<<endl;
}
template<class T1,class T2,class T3,class T4> void deb(T1 e1,T2 e2,T3 e3,T4 e4)
{
    cout<<e1<<" "<<e2<<" "<<e3<<" "<<e4<<endl;
}
template<class T1,class T2,class T3,class T4,class T5> void deb(T1 e1,T2 e2,T3 e3,T4 e4,T5 e5)
{
    cout<<e1<<" "<<e2<<" "<<e3<<" "<<e4<<" "<<e5<<endl;
}
template<class T1,class T2,class T3,class T4,class T5,class T6> void deb(T1 e1,T2 e2,T3 e3,T4 e4,T5 e5,T6 e6)
{
    cout<<e1<<" "<<e2<<" "<<e3<<" "<<e4<<" "<<e5<<" "<<e6<<endl;
}

// moves

//int dx[]= {-1,-1,0,0,1,1};
//int dy[]= {-1,0,-1,1,0,1};
//int dx[]= {0,0,1,-1};/*4 side move*/
//int dy[]= {-1,1,0,0};/*4 side move*/
//int dx[]= {1,1,0,-1,-1,-1,0,1};/*8 side move*/
//int dy[]= {0,1,1,1,0,-1,-1,-1};/*8 side move*/
//int dx[]={1,1,2,2,-1,-1,-2,-2};/*night move*/
//int dy[]={2,-2,1,-1,2,-2,1,-1};/*night move*/

//int set_bit(int n,int pos)
//{
//    return (int)(n|(1<<pos));
//}
//
//int off_bit(int n,int pos)
//{
//    return (int)(n&(~(1<<pos))) ;
//}
//
//bool is_on(int n,int pos)
//{
//    return (bool)(n&(1<<pos));
//}
//
//int flip_bit(int n,int pos)
//{
//    return (int)(n^(1<<pos));
//}

//close

VI graph[107] ;
ll dp[107][43] ;
int k ;

ll rec(int u,int p)
{
    int v ;
    ll tdp[43]  ;
    dp[u][0] = 1 ;
    dp[u][k+1] = 1 ;

    for(int i=0 ; i<graph[u].size() ; i++)
    {
        v = graph[u][i] ;

        if(v == p)
            continue;

        rec(v,u);
        clr(tdp,0);

        for(int i=0 ; i<=2*k ; i++)
        {
            for(int j=0 ; j<=2*k ; j++)
            {
                if(i+j<=2*k)
                    tdp[min(i,j+1)] = (tdp[min(i,j+1)] + (dp[u][i]*dp[v][j])%Mod)%Mod ;

                else
                    tdp[max(i,j+1)] = (tdp[max(i,j+1)] + (dp[u][i]*dp[v][j])%Mod)%Mod ;
            }
        }

        for(int i=0 ; i<=2*k ; i++)
            dp[u][i] = tdp[i] ;
    }
}

int main()
{
    int n , u , v ;

    sf2(n,k);

    for(int i=1 ; i<n ; i++)
    {
        sf2(u,v);
        graph[u].pb(v);
        graph[v].pb(u);
    }

    rec(1,-1);

    ll ans = 0 ;

    for(int i=0 ; i<=k ; i++)
        ans = (ans + dp[1][i])%Mod ;

    pf("%lld\n",ans);

    return 0 ;
}