// author : Nguyễn Trọng Nguyễn - ITK22 NBK 
#include <bits/stdc++.h>
 
#define ll long long
#define ii pair <int, int>
#define fi first
#define sc second
 
using namespace std;
 
const int maxn = (int)2e5;
const int BS = 320;
const int MOD = (int)1e9 + 7;
 
int n, k, mx;
vector <int> adj[maxn + 5];
int cnt[maxn + 5], sz[maxn + 5];
bool vist[maxn + 5];
ll ans = 0;
 
int subtree_size (int u, int p = 0) {
	sz[u] = 1;
	for (auto v : adj[u]) {
		if (v == p or vist[v]) continue;
		sz[u] += subtree_size(v, u);
	}
	return sz[u];
}
 
int find_centroid (int tree_size, int u, int p = 0) {
	for (auto v : adj[u]) {
		if (vist[v] or v == p) continue;
		if (sz[v] > tree_size / 2) return find_centroid(tree_size, v, u);
	}
	return u;
}
 
void get (bool type, int u, int p, int dist = 1) {
	if (dist > k) return ;
	mx = max(mx, dist);
 
	if (!type) cnt[dist]++;
	else ans += cnt[k - dist];
 
	for (auto v : adj[u]) {
		if (vist[v] or v == p) continue;
		get(type, v, u, dist + 1);
	}
}
 
void centroid_decompose (int u) {
	int centroid = find_centroid(subtree_size(u), u);
	vist[centroid] = true;
	mx = 0;
 
	for (auto v : adj[centroid]) {
		if (vist[v]) continue;
		get(true, v, centroid);
		get(false, v, centroid);
	}
 
	fill(cnt + 1, cnt + 1 + mx, 0);
	for (auto v : adj[centroid]) {
		if (vist[v]) continue;
		centroid_decompose(v);
	}
}
 
signed main (void) {
	cin.tie(0)->sync_with_stdio(false);
	
	#ifndef ONLINE_JUDGE
	freopen("test.inp","r",stdin);
	freopen("test.out","w",stdout);
	#endif
 
	cin >> n >> k;
	for (int i = 1; i < n; i++) {
		int u, v; cin >> u >> v;
		adj[u].push_back(v);
		adj[v].push_back(u);
	}	
 
	cnt[0] = 1;
	centroid_decompose(1);
	cout << ans;
 
	return 0;
}