using
System;
using
System.Collections.Generic;
class
CD {
private
int
n, k, mx_depth, ans;
private
List<
bool
> removed;
private
List<
int
> size, freq;
private
List<List<
int
> > g;
public
CD(
int
n1,
int
k1)
{
n = n1;
k = k1;
ans = mx_depth = 0;
g =
new
List<List<
int
> >();
for
(
int
i = 0; i < n; i++)
g.Add(
new
List<
int
>());
size =
new
List<
int
>();
size.AddRange(
new
int
[n]);
freq =
new
List<
int
>();
freq.AddRange(
new
int
[n]);
removed =
new
List<
bool
>();
removed.AddRange(
new
bool
[n]);
}
public
void
Edge(
int
u,
int
v)
{
u--;
v--;
g[u].Add(v);
g[v].Add(u);
}
private
int
GetSize(
int
node,
int
par)
{
if
(removed[node])
return
0;
size[node] = 1;
foreach
(
int
nebr
in
g[node])
{
if
(nebr != par)
size[node] += GetSize(nebr, node);
}
return
size[node];
}
private
int
GetCentroid(
int
node,
int
par,
int
sz)
{
foreach
(
int
nebr
in
g[node])
{
if
(!removed[nebr] && nebr != par
&& size[nebr] > sz / 2)
return
GetCentroid(nebr, node, sz);
}
return
node;
}
private
void
Decompose(
int
node,
int
par)
{
GetSize(node, -1);
int
c = GetCentroid(node, par, size[node]);
PathsOriginatingFrom(c);
removed =
true
;
foreach
(
int
nebr
in
g)
{
if
(!removed[nebr])
Decompose(nebr, c);
}
}
private
void
Dfs(
int
node,
int
par,
int
depth,
bool
contri)
{
if
(depth > k)
return
;
mx_depth = Math.Max(mx_depth, depth);
if
(contri)
ans += freq[k - depth];
else
freq[depth]++;
foreach
(
int
nebr
in
g[node])
{
if
(!removed[nebr] && nebr != par)
Dfs(nebr, node, depth + 1, contri);
}
}
private
void
PathsOriginatingFrom(
int
node)
{
mx_depth = 0;
freq[0] = 1;
foreach
(
int
nebr
in
g[node])
{
if
(!removed[nebr]) {
Dfs(nebr, node, 1,
true
);
Dfs(nebr, node, 1,
false
);
}
}
for
(
int
i = 0; i <= mx_depth; i++)
freq[i] = 0;
}
public
int
Solve()
{
Decompose(0, -1);
return
ans;
}
}
class
Program {
static
void
Main(
string
[] args)
{
int
N = 5, K = 2;
CD cd_s =
new
CD(N, K);
cd_s.Edge(1, 2);
cd_s.Edge(1, 5);
cd_s.Edge(2, 3);
cd_s.Edge(2, 4);
Console.WriteLine(cd_s.Solve());
}
}