#include <bits/stdc++.h>

using namespace std;

#define N 50000
#define K 500

unsigned int d[N][K+1];
vector<unsigned int> g[N];
bool s[N];
int n, k, a, b, root;

long long int  contaPares (int v) {
    long long int r = 0;
    if (d[v][0]) return 0;
    d[v][0] = 1;
    s[v] = 1;

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (d[*it][0]) continue;
        r += contaPares(*it);
    }

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (s[*it]) continue;

//        printf("%d : entra %d\n", v+1, *it+1);

//        printf("%d : ", v+1);
        for (int j = 0; j < k; j++) d[v][j+1] += d[*it][j];
//        printf("\n");
        for (vector<unsigned int>::iterator jt = it + 1; jt != g[v].end(); jt++) {
            if (s[*jt]) continue;

            for (int l = 0; l <= k-2; l++) {
                r += d[*it][l] * d[*jt][k-2-l];
            }
//            printf("%d : (%d,%d) => r = %lld\n", v+1, *it+1, *jt+1, r);
        }

//        printf("%d : sai %d\n", v+1, *it+1);
    }

    s[v] = 0;
    r += d[v][k];

//    printf("%d : r = %lld\n", v+1, r);
    return r;
}

int main () {
    scanf("%d %d", &n, &k);

    for (int i = 0; i < n; i++) {
        s[i] = 0;
        for (int j = 0; j <= k; j++) d[i][j] = 0;

        if (i) {
            scanf("%d %d", &a, &b);
            a--;
            b--;

            g[a].push_back(b);
            g[b].push_back(a);
            if (i == 1) a = root;
        }
    }

/*
    for (int i = 0; i < n; i++) {
        printf("g[%d] : ", i+1);
        for (vector<unsigned int>::iterator jt = g[i].begin(); jt != g[i].end(); jt++) {
            printf("%d ", *jt+1);
        }
        printf("\n");
    }
*/

    printf("%I64d\n", contaPares(root));
}


#include <bits/stdc++.h>

using namespace std;

#define N 50000
#define K 500

unsigned int d[N][K+1];
vector<unsigned int> g[N];
bool s[N];
int n, k, a, b, root, p;

long long int  contaPares (int v) {
    long long int r = 0;
    if (d[v][0]) return 0;
    d[v][0] = 1;
    s[v] = 1;

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (d[*it][0]) continue;
        r += contaPares(*it);
    }

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (s[*it]) continue;

//        printf("%d : entra %d\n", v+1, *it+1);

//        printf("%d : ", v+1);
        for (int j = 0; j < k; j++) d[v][j+1] += d[*it][j];
//        printf("\n");

        for (p = 0; p <= k-2 && d[*it][p]; p++);

        for (int l = k-2-p; l <= p; l++) {
            for (vector<unsigned int>::iterator jt = it + 1; jt != g[v].end(); jt++) {
                if (s[*jt] || !d[*jt][l]) continue;

                r += d[*it][k-2-l] * d[*jt][l];
            }
        }
//            printf("%d : (%d,%d) => r = %l ld\n", v+1, *it+1, *jt+1, r);

//        printf("%d : sai %d\n", v+1, *it+1);
    }

    s[v] = 0;
    r += d[v][k];

//    printf("%d : r = %l ld\n", v+1, r);
    return r;
}

int main () {
    scanf("%d %d", &n, &k);

    for (int i = 0; i < n; i++) {
        s[i] = 0;
        for (int j = 0; j <= k; j++) d[i][j] = 0;

        if (i) {
            scanf("%d %d", &a, &b);
            a--;
            b--;

            g[a].push_back(b);
            g[b].push_back(a);
            if (i == 1) a = root;
        }
    }

/*
    for (int i = 0; i < n; i++) {
        printf("g[%d] : ", i+1);
        for (vector<unsigned int>::iterator jt = g[i].begin(); jt != g[i].end(); jt++) {
            printf("%d ", *jt+1);
        }
        printf("\n");
    }
*/

    printf("%I64d\n", contaPares(root));
}


#include <bits/stdc++.h>

using namespace std;

#define N 50000
#define K 500

unsigned int d[N][K+1];
vector<unsigned int> g[N];
bool s[N];
int n, k, a, b, root, p;

long long int  contaPares (int v) {
    long long int r = 0;
    if (d[v][0]) return 0;
    d[v][0] = 1;
    s[v] = 1;

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (d[*it][0]) continue;
        r += contaPares(*it);
    }

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (s[*it]) continue;

        for (int j = 0; j < k; j++) d[v][j+1] += d[*it][j];

        for (p = 1; p <= k-2 && d[*it][p]; p++);

        for (vector<unsigned int>::iterator jt = it + 1; jt != g[v].end(); jt++) {
            if (s[*jt]) continue;
            for (int l = p-1; l >= 0; l--) {
                if (d[*jt][k-2-l] == 0) break;

                r += d[*it][l] * d[*jt][k-2-l];
            }
        }
    }

    s[v] = 0;
    r += d[v][k];

    return r;
}

int main () {
    scanf("%d %d", &n, &k);

    for (int i = 0; i < n; i++) {
        s[i] = 0;
        for (int j = 0; j <= k; j++) d[i][j] = 0;

        if (i) {
            scanf("%d %d", &a, &b);
            a--;
            b--;

            g[a].push_back(b);
            g[b].push_back(a);
            if (i == 1) a = root;
        }
    }

/*
    for (int i = 0; i < n; i++) {
        printf("g[%d] : ", i+1);
        for (vector<unsigned int>::iterator jt = g[i].begin(); jt != g[i].end(); jt++) {
            printf("%d ", *jt+1);
        }
        printf("\n");
    }
*/

    printf("%I64d\n", contaPares(root));
}


#include <bits/stdc++.h>

using namespace std;

#define N 50000
#define K 500

unsigned int d[N][K+1];
vector<unsigned int> g[N];
bool s[N];
int n, k, a, b, root, p;

long long int  contaPares (int v) {
    long long int r = 0;
    if (d[v][0]) return 0;
    d[v][0] = 1;
    s[v] = 1;

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (d[*it][0]) continue;
        r += contaPares(*it);
    }

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (s[*it]) continue;

//        printf("%d : entra %d\n", v+1, *it+1);

//        printf("%d : ", v+1);
        for (int j = 0; j < k; j++) d[v][j+1] += d[*it][j];
//        printf("\n");

        for (p = 0; p <= k-2 && d[*it][p]; p++);

        for (int l = p; l >= 0; l--) {
            for (vector<unsigned int>::iterator jt = it + 1; jt != g[v].end(); jt++) {
                if (s[*jt] || !d[*jt][k-2-l]) continue;

                r += d[*it][l] * d[*jt][k-2-l];
            }
        }
//            printf("%d : (%d,%d) => r = %l ld\n", v+1, *it+1, *jt+1, r);

//        printf("%d : sai %d\n", v+1, *it+1);
    }

    s[v] = 0;
    r += d[v][k];

//    printf("%d : r = %l ld\n", v+1, r);
    return r;
}

int main () {
    scanf("%d %d", &n, &k);

    for (int i = 0; i < n; i++) {
        s[i] = 0;
        for (int j = 0; j <= k; j++) d[i][j] = 0;

        if (i) {
            scanf("%d %d", &a, &b);
            a--;
            b--;

            g[a].push_back(b);
            g[b].push_back(a);
            if (i == 1) a = root;
        }
    }

/*
    for (int i = 0; i < n; i++) {
        printf("g[%d] : ", i+1);
        for (vector<unsigned int>::iterator jt = g[i].begin(); jt != g[i].end(); jt++) {
            printf("%d ", *jt+1);
        }
        printf("\n");
    }
*/

    printf("%I64d\n", contaPares(root));
}


#include <bits/stdc++.h>

using namespace std;

#define N 50000
#define K 500

unsigned int d[N][K+1];
vector<unsigned int> g[N];
bool s[N];
int n, k, a, b, root, p;

long long int  contaPares (int v) {
    long long int r = 0;
    if (d[v][0]) return 0;
    d[v][0] = 1;
    s[v] = 1;

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (d[*it][0]) continue;
        r += contaPares(*it);
    }

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (s[*it]) continue;

        for (int j = 0; j < k && d[*it][j]; j++) d[v][j+1] += d[*it][j];

        for (int l = 0; l <= k-2; l++) {
            for (vector<unsigned int>::iterator jt = it + 1; jt != g[v].end(); jt++) {
                if (s[*jt]) continue;

                r += d[*it][l] * d[*jt][k-2-l];
            }
        }
    }

    s[v] = 0;
    r += d[v][k];

    return r;
}

int main () {
    scanf("%d %d", &n, &k);

    for (int i = 0; i < n; i++) {
        s[i] = 0;
        for (int j = 0; j <= k; j++) d[i][j] = 0;

        if (i) {
            scanf("%d %d", &a, &b);
            a--;
            b--;

            g[a].push_back(b);
            g[b].push_back(a);
            if (i == 1) a = root;
        }
    }

/*
    for (int i = 0; i < n; i++) {
        printf("g[%d] : ", i+1);
        for (vector<unsigned int>::iterator jt = g[i].begin(); jt != g[i].end(); jt++) {
            printf("%d ", *jt+1);
        }
        printf("\n");
    }
*/

    printf("%I64d\n", contaPares(root));
}


#include <bits/stdc++.h>

using namespace std;

#define N 50000
#define K 500

unsigned int d[N][K+1];
vector<unsigned int> g[N];
bool s[N];
int n, k, a, b, root;

long long int  contaPares (int v) {
    long long int r = 0;
    if (d[v][0]) return 0;
    d[v][0] = 1;
    s[v] = 1;

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (d[*it][0]) continue;
        r += contaPares(*it);
    }

    for (vector<unsigned int>::iterator it = g[v].begin(); it != g[v].end(); it++) {
        if (s[*it]) continue;

//        printf("%d : entra %d\n", v+1, *it+1);

//        printf("%d : ", v+1);
        for (int j = 0; j < k; j++) d[v][j+1] += d[*it][j];
//        printf("\n");
        for (vector<unsigned int>::iterator jt = it + 1; jt != g[v].end(); jt++) {
            if (s[*jt]) continue;

            for (int l = 0; l <= k-2 && d[*it][l]; l++) {
                r += d[*it][l] * d[*jt][k-2-l];
                if (d[*it][l] == 0) break;
            }
//            printf("%d : (%d,%d) => r = %lld\n", v+1, *it+1, *jt+1, r);
        }

//        printf("%d : sai %d\n", v+1, *it+1);
    }

    s[v] = 0;
    r += d[v][k];

//    printf("%d : r = %lld\n", v+1, r);
    return r;
}

int main () {
    scanf("%d %d", &n, &k);

    for (int i = 0; i < n; i++) {
        s[i] = 0;
        for (int j = 0; j <= k; j++) d[i][j] = 0;

        if (i) {
            scanf("%d %d", &a, &b);
            a--;
            b--;

            g[a].push_back(b);
            g[b].push_back(a);
            if (i == 1) a = root;
        }
    }

/*
    for (int i = 0; i < n; i++) {
        printf("g[%d] : ", i+1);
        for (vector<unsigned int>::iterator jt = g[i].begin(); jt != g[i].end(); jt++) {
            printf("%d ", *jt+1);
        }
        printf("\n");
    }
*/

    printf("%I64d\n", contaPares(root));
}


#include<iostream>
#include<vector>
#include<stack>
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<int> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  vector< vector<int> > graph2(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<int> > pd(n,vector<int>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  double resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  int div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
//  imprime(pd,n,k);
  div=div/2;
  cout<<resposta+div<<endl;
  return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
#define li long long int
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<li> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph2(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<li> > pd(n,vector<li>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  long long int resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  int div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
//  imprime(pd,n,k);
  div=div/2;
  resposta=resposta+div;
  cout<<resposta<<endl;
  return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
#define li long
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<li> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  vector< vector<int> > graph2(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<li> > pd(n,vector<li>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  long long int resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  int div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
//  imprime(pd,n,k);
  div=div/2;
  resposta=resposta+div;
  cout<<resposta<<endl;
  return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<int> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  vector< vector<int> > graph2(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<int> > pd(n,vector<int>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  long long int resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  int div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
//  imprime(pd,n,k);
  div=div/2;
  resposta=resposta+div;
  cout<<resposta<<endl;
  return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
#define li int
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<li> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<li> > pd(n,vector<li>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  long long int resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  long long int div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
  div=div/2;
  resposta=resposta+div;
  cout<<resposta<<endl;
  return 0;
}


#include<iostream>
#include<vector>
#include<stack>
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<int> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  vector< vector<int> > graph2(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<int> > pd(n,vector<int>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  long double resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  int div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
//  imprime(pd,n,k);
  div=div/2;
  cout<<resposta+div<<endl;
  return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
#define li long long int
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<li> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<li> > pd(n,vector<li>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  long long int resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  int div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
//  imprime(pd,n,k);
  div=div/2;
  resposta=resposta+div;
  cout<<resposta<<endl;
  return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
#define li long long int
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<li> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  vector< vector<int> > graph2(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<li> > pd(n,vector<li>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  long long int resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  int div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
//  imprime(pd,n,k);
  div=div/2;
  resposta=resposta+div;
  cout<<resposta<<endl;
  return 0;
}


#include<iostream>
#include<vector>
#include<stack>
using namespace std;
void dfs(vector< vector<int> >&graph2,vector<bool> usados, int atual,int *raiz)
{
  usados[atual]=true;
  if(graph2[atual].size()==0)
  {
     *raiz=atual;
     return;
  }
  for(int i=0;i<graph2[atual].size();i++)
  {
     if(!usados[graph2[atual][i]])
       dfs(graph2,usados,i,raiz);
  }
  return;
}
void dfs2(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<int> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs2(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}

int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  vector< vector<int> > graph2(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph2[y-1].push_back(x-1);
  }
  vector<bool> usados(n,false);
  int raiz=n-1;
  dfs(graph2,usados,n-1,&raiz);
  vector< vector<int> > pd(n,vector<int>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs2(graph,usados2,raiz,pd,pai,k);
  double resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        resposta+=pd[pai[j]][i]*pd[pai[j]][k-i];
        resposta-=pd[j][k-i]*pd[pai[j]][k];
      }
   }
  }
  resposta=resposta/2;
  for(int j=0;j<n;j++)
  {
    for(int i=0;i<=k;i++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
  cout<<resposta<<endl;
  return 0;
}


#include<cstdio>
#include<iostream>
#include<vector>
#include<stack>
#define li double
using namespace std;
void dfs(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<li> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}
void imprime(vector< vector<int> >&pd,int n, int k)
{
  for(int i=0;i<=k;i++)
  {
    for(int j=0;j<n;j++)
    {
      cout<<pd[j][i]<<" ";
    }
    cout<<endl;
  }
}
int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph[y-1].push_back(x-1);
  }
  vector< vector<li> > pd(n,vector<li>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs(graph,usados2,0,pd,pai,k);
  int resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  double div=0;
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        div+=pd[j][i-1]*pd[pai[j]][k-i];
        div-=pd[j][i-1]*pd[j][k-i-1];
      }
   }
  }
  div=div/2;
  resposta=resposta+div;
  cout<<resposta<<endl;
  return 0;
}


#include <cstring>
#include <iostream>
#include <bitset>
#include <cstdlib>
#include <set>
#include <map>
#include <vector>
#include <string>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <utility>
#include <algorithm>
#include <iomanip>
#define sc(a) scanf("%d", &a)
#define sc2(a, b) scanf("%d%d", &a, &b)
#define sc3(a, b, c) scanf("%d%d%d", &a, &b, &c)
#define scs(s) scanf("%s", s)
#define pri(x) printf("%d\n", x)
const int INF = 0x3f3f3f3f;
#define ll long long int
#define ld long double
#define endl "\n"
using namespace std;
int n, k;
void dfs(vector<vector<int> > &g, vector<int> &u, int atual, vector<int> &pai,
         int last, vector<vector<ll> > &dp)
{
  u[atual] = 1;
  pai[atual] = last;
  for (int i = 0; i < g[atual].size(); i++) {
    if (!u[g[atual][i]]) {
      dfs(g, u, g[atual][i], pai, atual, dp);
    }
  }
  dp[atual][0] = 1;
  for (int i = 1; i <= k; i++) {
    if (last != -1) {
      dp[last][i] += dp[atual][i - 1];
    }
  }
}
int main()
{
  cin >> n >> k;
  vector<vector<int> > g(n);
  for (int i = 1; i < n; i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  vector<int> u(n, 0);
  vector<int> pai(n, 0);
  vector<vector<ll> > dp(n, vector<ll>(k + 1, 0));
  ll resp = 0;
  dfs(g, u, 0, pai, -1, dp);
  ll x = 0;
  for (int i = 0; i < n; i++) x += dp[i][k];
  for (int i = 0; i < n; i++) {
    for (int j = 1; j < k; j++) {
      if (pai[i] != -1) {
        resp += dp[i][j-1] * dp[pai[i]][k - j];
        resp -= dp[i][j-1] * dp[i][k -j-1];
      }
    }
  }
  cout << resp/2+x << endl;
  return 0;
}


#include<iostream>
#include<vector>
#include<stack>
using namespace std;
void dfs(vector< vector<int> >&graph2,vector<bool> usados, int atual,int *raiz)
{
  usados[atual]=true;
  if(graph2[atual].size()==0)
  {
     *raiz=atual;
     return;
  }
  for(int i=0;i<graph2[atual].size();i++)
  {
     if(!usados[graph2[atual][i]])
       dfs(graph2,usados,i,raiz);
  }
  return;
}
void dfs2(vector< vector<int> >&graph,vector<bool> usados2, int atual,vector< vector<int> > &pd,vector<int> &pai,int k)
{
  usados2[atual]=true;
  for(int i=0;i<graph[atual].size();i++)
  {
    if(!usados2[graph[atual][i]])
    {
        pai[graph[atual][i]]=atual;
        dfs2(graph,usados2,graph[atual][i],pd,pai,k);
    }
  }
  for(int i=1;i<=k;i++)
  {
    if(pai[atual]!=-1)
    {
      pd[pai[atual]][i]+=pd[atual][i-1];
    }
  }
}

int main()
{
  int n,k;
  cin>>n>>k;
  vector< vector<int> > graph(n);
  vector< vector<int> > graph2(n);
  for(int i=0;i<n-1;i++)
  {
    int x,y;
    cin>>x>>y;
    graph[x-1].push_back(y-1);
    graph2[y-1].push_back(x-1);
  }
  vector<bool> usados(n,false);
  int raiz=n-1;
  dfs(graph2,usados,n-1,&raiz);
  vector< vector<int> > pd(n,vector<int>(k+1,0));
  vector<bool> usados2(n,false);
  vector<int> pai(n,-1);
  for(int i=0;i<n;i++) pd[i][0]=1;
  dfs2(graph,usados2,raiz,pd,pai,k);
  double resposta=0;
  for(int i=0;i<n;i++) resposta+=pd[i][k];
  for(int j=0;j<n;j++)
  {
    for(int i=1;i<k;i++)
    {
      if(pai[j]!=-1)
      {
        resposta+=pd[pai[j]][i]*pd[pai[j]][k-i];
        resposta-=pd[j][k-i]*pd[pai[j]][k];
      }
   }
  }
  resposta=resposta/2;
  cout<<resposta<<endl;
  return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstring>
#include <cctype>
typedef unsigned long long ULL;
typedef long long LL;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FO(i,a,b) for(int i=a;i<b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define FOD(i,a,b) for(int i=a;i>b;i--)
#define FORV(i,a) for(typeof(a.begin()) i = a.begin(); i != a.end(); i++)
#define Set(a,c) memset(a, c, sizeof(a))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define VI vector <int>
#define PII pair<int,int>
#define maxn 50001
#define maxk 501
using namespace std;
int n,k;
int p[maxn],h[maxn];
LL d[maxn][maxk];
bool isLeaf[maxn];
vector <int> a[maxn];
vector <int> child[maxn];
struct cmp {
    bool operator() (int a,int b) {
        return h[a] > h[b] || (h[a] == h[b] && a>b);
    }
};
set <int,cmp> S;
void buildTree(int u) {
    FO (i,0,a[u].size()) {
        int v = a[u][i];
        if (h[v]==0) {
            child[u].pb(v);
            p[v] = u;
            h[v] = h[u] + 1;
            isLeaf[u] = 0;
            buildTree(v);
        }
    }
}
int main() {
	//freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
    scanf("%d %d",&n,&k);
    int u,v;
    FOR (i,1,n-1) {
        scanf("%d %d",&u,&v);
        a[u].pb(v);
        a[v].pb(u);
    }
    Set(isLeaf,1);
    h[1] = 1;
    buildTree(1);
    FOR (i,1,n)
        S.insert(i);
    FORV(it,S) {
        //cout << *it << endl;
        int u = *it;
        d[u][0] = 1;
        int v = p[u];
        FOR (i,0,k-1)
            if (d[u][i]) d[v][i+1] += d[u][i];
    }
    LL ans = 0;
    FOR (u,1,n) {
        ans += d[u][k];
        LL tmp = 0;
        FO (i,0,child[u].size()) {
            v = child[u][i];
            FOR (j,0,k-2)
                tmp += d[v][j] * (d[u][k-j-1] - d[v][k-j-2]);
        }
        ans += tmp / 2;
    }
    /*FOR (i,1,n) {
        FOR (j,0,5) cout << d[i][j] << " ";
        cout << endl;
    }*/
    cout << ans;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstring>
#include <cctype>
typedef unsigned long long ULL;
typedef long long LL;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FO(i,a,b) for(int i=a;i<b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define FOD(i,a,b) for(int i=a;i>b;i--)
#define FORV(i,a) for(typeof(a.begin()) i = a.begin(); i != a.end(); i++)
#define Set(a,c) memset(a, c, sizeof(a))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define VI vector <int>
#define PII pair<int,int>
#define maxn 50001
#define maxk 501
using namespace std;
int n,k;
int p[maxn],h[maxn],d[maxn][maxk];
bool isLeaf[maxn];
vector <int> a[maxn];
vector <int> child[maxn];
struct cmp {
    bool operator() (int a,int b) {
        return h[a] > h[b] || (h[a] == h[b] && a>b);
    }
};
set <int,cmp> S;
void buildTree(int u) {
    FO (i,0,a[u].size()) {
        int v = a[u][i];
        if (h[v]==0) {
            child[u].pb(v);
            p[v] = u;
            h[v] = h[u] + 1;
            isLeaf[u] = 0;
            buildTree(v);
        }
    }
}
int main() {
	//freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
    scanf("%d %d",&n,&k);
    int u,v;
    FOR (i,1,n-1) {
        scanf("%d %d",&u,&v);
        a[u].pb(v);
        a[v].pb(u);
    }
    Set(isLeaf,1);
    h[1] = 1;
    buildTree(1);
    FOR (i,1,n)
        S.insert(i);
    FORV(it,S) {
        //cout << *it << endl;
        int u = *it;
        d[u][0] = 1;
        int v = p[u];
        FOR (i,0,k-1)
            if (d[u][i]) d[v][i+1] += d[u][i];
    }
    LL ans = 0;
    FOR (u,1,n) {
        ans += d[u][k];
        int tmp = 0;
        FO (i,0,child[u].size()) {
            v = child[u][i];
            FOR (j,0,k-2)
                tmp += d[v][j] * (d[u][k-j-1] - d[v][k-j-2] > 0);
        }
        ans += tmp / 2;
    }
    /*FOR (i,1,n) {
        FOR (j,0,5) cout << d[i][j] << " ";
        cout << endl;
    }*/
    cout << ans;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstring>
#include <cctype>
typedef unsigned long long ULL;
typedef long long LL;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FO(i,a,b) for(int i=a;i<b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define FOD(i,a,b) for(int i=a;i>b;i--)
#define FORV(i,a) for(typeof(a.begin()) i = a.begin(); i != a.end(); i++)
#define Set(a,c) memset(a, c, sizeof(a))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define VI vector <int>
#define PII pair<int,int>
#define maxn 50001
#define maxk 501
using namespace std;
int n,k;
int p[maxn],h[maxn],d[maxn][maxk];
bool isLeaf[maxn];
vector <int> a[maxn];
vector <int> child[maxn];
struct cmp {
    bool operator() (int a,int b) {
        return h[a] > h[b] || (h[a] == h[b] && a>b);
    }
};
set <int,cmp> S;
void buildTree(int u) {
    FO (i,0,a[u].size()) {
        int v = a[u][i];
        if (h[v]==0) {
            child[u].pb(v);
            p[v] = u;
            h[v] = h[u] + 1;
            isLeaf[u] = 0;
            buildTree(v);
        }
    }
}
int main() {
	//freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
    scanf("%d %d",&n,&k);
    int u,v;
    FOR (i,1,n-1) {
        scanf("%d %d",&u,&v);
        a[u].pb(v);
        a[v].pb(u);
    }
    Set(isLeaf,1);
    h[1] = 1;
    buildTree(1);
    FOR (i,1,n)
        S.insert(i);
    FORV(it,S) {
        //cout << *it << endl;
        int u = *it;
        d[u][0] = 1;
        int v = p[u];
        FOR (i,0,k-1)
            if (d[u][i]) d[v][i+1] += d[u][i];
    }
    LL ans = 0;
    FOR (u,1,n) {
        ans += d[u][k];
        int tmp = 0;
        FO (i,0,child[u].size()) {
            v = child[u][i];
            FOR (j,0,k-2)
                tmp += d[v][j] * (d[u][k-j-1] - d[v][k-j-2]);
        }
        ans += tmp / 2;
    }
    /*FOR (i,1,n) {
        FOR (j,0,5) cout << d[i][j] << " ";
        cout << endl;
    }*/
    cout << ans;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstring>
#include <cctype>
typedef unsigned long long ULL;
typedef long long LL;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FO(i,a,b) for(int i=a;i<b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define FOD(i,a,b) for(int i=a;i>b;i--)
#define FORV(i,a) for(typeof(a.begin()) i = a.begin(); i != a.end(); i++)
#define Set(a,c) memset(a, c, sizeof(a))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define VI vector <int>
#define PII pair<int,int>
#define maxn 50001
#define maxk 501
using namespace std;
int n,k;
int p[maxn],h[maxn],d[maxn][maxk];
bool isLeaf[maxn];
vector <int> a[maxn];
vector <int> child[maxn];
struct cmp {
    bool operator() (int a,int b) {
        return h[a] > h[b] || (h[a] == h[b] && a>b);
    }
};
set <int,cmp> S;
void buildTree(int u) {
    FO (i,0,a[u].size()) {
        int v = a[u][i];
        if (h[v]==0) {
            child[u].pb(v);
            p[v] = u;
            h[v] = h[u] + 1;
            isLeaf[u] = 0;
            buildTree(v);
        }
    }
}
int main() {
	/*freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
    scanf("%d %d",&n,&k);
    int u,v;
    FOR (i,1,n-1) {
        scanf("%d %d",&u,&v);
        a[u].pb(v);
        a[v].pb(u);
    }
    Set(isLeaf,1);
    h[1] = 1;
    buildTree(1);
    FOR (i,1,n)
        S.insert(i);
    FORV(it,S) {
        //cout << *it << endl;
        int u = *it;
        d[u][0] = 1;
        int v = p[u];
        FOR (i,0,k-1)
            if (d[u][i]) d[v][i+1] += d[u][i];
    }
    LL ans = 0;
    FOR (u,1,n) {
        ans += d[u][k];
        int tmp = 0;
        FO (i,0,child[u].size()) {
            v = child[u][i];
            FOR (j,0,k-2)
                tmp += d[v][j] * (d[u][k-j-1] - d[v][k-j-2] > 0);
        }
        ans += tmp / 2;
    }
    /*FOR (i,1,n) {
        FOR (j,0,5) cout << d[i][j] << " ";
        cout << endl;
    }*/
    //cout << ans;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstring>
#include <cctype>
typedef unsigned long long ULL;
typedef long long LL;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FO(i,a,b) for(int i=a;i<b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define FOD(i,a,b) for(int i=a;i>b;i--)
#define FORV(i,a) for(typeof(a.begin()) i = a.begin(); i != a.end(); i++)
#define Set(a,c) memset(a, c, sizeof(a))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define VI vector <int>
#define PII pair<int,int>
#define maxn 500010
#define maxk 501
using namespace std;
int n,k;
int p[maxn],h[maxn],d[maxn][maxk];
bool Free[maxn],isLeaf[maxn];
vector <int> a[maxn];
vector <int> child[maxn];
struct cmp {
    bool operator() (int a,int b) {
        return h[a] > h[b] || (h[a] == h[b] && a>b);
    }
};
set <int,cmp> S;
void buildTree(int u) {
    Free[u] = 0;
    FO (i,0,a[u].size()) {
        int v = a[u][i];
        if (Free[v]) {
            child[u].pb(v);
            p[v] = u;
            h[v] = h[u] + 1;
            isLeaf[u] = 0;
            buildTree(v);
        }
    }
}
int main() {
	freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
    scanf("%d %d",&n,&k);
    int u,v;
    FOR (i,1,n-1) {
        scanf("%d %d",&u,&v);
        a[u].pb(v);
        a[v].pb(u);
    }
    Set(Free,1);
    Set(isLeaf,1);
    h[1] = 1;
    buildTree(1);
    FOR (i,1,n) {
        //cout << h[i] << " ";
        //if (isLeaf[i]) cout << i<< " ";
        S.insert(i);
    }
    FORV(it,S) {
        //cout << *it << endl;
        int u = *it;
        d[u][0] = 1;
        int v = p[u];
        FOR (i,0,k-1)
            if (d[u][i]) d[v][i+1] += d[u][i];
    }
    LL ans = 0;
    FOR (u,1,n) {
        ans += d[u][k];
        int tmp = 0;
        FO (i,0,child[u].size()) {
            v = child[u][i];
            FOR (j,0,k-2)
                tmp += d[v][j] * (d[u][k-j-1] - d[v][k-j-2] > 0);
        }
        ans += tmp / 2;
    }
    /*FOR (i,1,n) {
        FOR (j,0,5) cout << d[i][j] << " ";
        cout << endl;
    }*/
    cout << ans;
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <cstring>
#include <cctype>
typedef unsigned long long ULL;
typedef long long LL;
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define FO(i,a,b) for(int i=a;i<b;i++)
#define FORD(i,a,b) for(int i=a;i>=b;i--)
#define FOD(i,a,b) for(int i=a;i>b;i--)
#define FORV(i,a) for(typeof(a.begin()) i = a.begin(); i != a.end(); i++)
#define Set(a,c) memset(a, c, sizeof(a))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define VI vector <int>
#define PII pair<int,int>
#define maxn 50001
#define maxk 501
using namespace std;
int n,k;
int p[maxn],h[maxn],d[maxn][maxk];
bool isLeaf[maxn];
vector <int> a[maxn];
vector <int> child[maxn];
struct cmp {
    bool operator() (int a,int b) {
        return h[a] > h[b] || (h[a] == h[b] && a>b);
    }
};
set <int,cmp> S;
void buildTree(int u) {
    FO (i,0,a[u].size()) {
        int v = a[u][i];
        if (h[v]==0) {
            child[u].pb(v);
            p[v] = u;
            h[v] = h[u] + 1;
            isLeaf[u] = 0;
            buildTree(v);
        }
    }
}
int main() {
	/*freopen("test.in","r",stdin);
	//freopen("test.out","w",stdout);
    scanf("%d %d",&n,&k);
    int u,v;
    FOR (i,1,n-1) {
        scanf("%d %d",&u,&v);
        a[u].pb(v);
        a[v].pb(u);
    }
    Set(isLeaf,1);
    h[1] = 1;
    buildTree(1);
    FOR (i,1,n)
        S.insert(i);
    FORV(it,S) {
        //cout << *it << endl;
        int u = *it;
        d[u][0] = 1;
        int v = p[u];
        FOR (i,0,k-1)
            if (d[u][i]) d[v][i+1] += d[u][i];
    }
    LL ans = 0;
    FOR (u,1,n) {
        ans += d[u][k];
        int tmp = 0;
        FO (i,0,child[u].size()) {
            v = child[u][i];
            FOR (j,0,k-2)
                tmp += d[v][j] * (d[u][k-j-1] - d[v][k-j-2] > 0);
        }
        ans += tmp / 2;
    }
    /*FOR (i,1,n) {
        FOR (j,0,5) cout << d[i][j] << " ";
        cout << endl;
    }*/
    cout << ans;
	return 0;
}


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

const int MAXN = 50 * 1000 + 10, MAXK = 500 + 10;
vector <int> vec[MAXN];
long long d[MAXN][MAXK];
bool mark[MAXN];
long long ans = 0;
int n, k;

void DFS(int v)
{
	mark[v] = true;
	d[v][0] = 1;
	for(int i = 0; i < vec[v].size(); i s++)
	if(!mark[vec[v][i]])
		{
			DFS(vec[v][i]);

			for(int j = 1; j <= k; j ++)
				ans += d[vec[v][i]][j - 1] * d[v][k - j];

			for(int j = 1; j < k; j ++)
				d[v][j] += d[vec[v][i]][j - 1];
		}

}

int main()
{
	cin>> n >> k;

	for(int i = 0; i < n - 1; i ++)
	{
		int a, b;
		cin>> a >> b;
		a --;	b --;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}

	DFS(0);

	cout<< ans << endl;
}


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

//time 23

const int MAXN = 50 * 1000 + 10, MAXK = 500 + 10;
vector <int> vec[MAXN];
int dist[MAXN][MAXK];
bool chck[MAXN];
int n, k, ans = 0;

void F(int v)
{
	chck[v] = true;

	int pdr = -1;
	for(int i = 0; i < vec[v].size(); i++)
	{
		if(chck[vec[v][i]])
			pdr = vec[v][i];
		else
			F(vec[v][i]);
	}

	dist[v][0] = 1;

	for(int j = 1; j <= k; j++)
		for(int i = 0; i < vec[v].size(); i++)
			if(vec[v][i] != pdr)
			{
				dist[v][j] += dist[vec[v][i]][j - 1];
			}

	int masir = 0;
	for(int j = 0; j < k / 2; j++)
	{
		for(int i = 0; i < vec[v].size(); i++)
		{
//cout<< j << " " << vec[v][i] << " " << dist[vec[v][i]][k - j - 2] << " " << sum << endl;
			masir += dist[vec[v][i]][k - j - 1] * (dist[v][j] - dist[vec[v][i]][j - 1]);

		}
	}
	masir /= 2;

//	cout<< masir << endl;
	masir += dist[v][k];
// 	cout<< "vertex " << v + 1 << ": " << masir <<endl;
//	for(int i  = 0; i <= k ; i++)
//		cout<< i << ", " << dist[v][i] << endl;
 	ans += masir;

}

int main()
{

	cin>> n >> k;

	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin>> a >> b;
		a --;
		b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}

	F(0);
	cout<< ans << endl;
}


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

//wrong answer test 7

const int MAXN = 50 * 1000 + 10, MAXK = 500 + 10;
vector <int> vec[MAXN];
int dist[MAXN][MAXK];
bool chck[MAXN];
int n, k, ans = 0;

void F(int v)
{
	chck[v] = true;

	int pdr = -1;
	for(int i = 0; i < vec[v].size(); i++)
	{
		if(chck[vec[v][i]])
			pdr = vec[v][i];
		else
			F(vec[v][i]);
	}

	dist[v][0] = 1;

	int masir = 0;
	for(int j = 0; j <= k; j++)
	{
		for(int i = 0; i < vec[v].size(); i++)
		{
			int sum = 0;
			if(vec[v][i] != pdr)
				for(int p = 0; p < vec[v].size(); p++)
				{
					if(vec[v][p] != pdr && i != p)
						sum += dist[vec[v][p]][j];
				}
//cout<< j << " " << vec[v][i] << " " << dist[vec[v][i]][k - j - 2] << " " << sum << endl;
			masir += dist[vec[v][i]][k - j - 2] * sum;

		}
	}
	masir /= 2;

//	cout<< endl;
//	cout<< masir << endl;
	for(int j = 1; j <= k; j++)
		for(int i = 0; i < vec[v].size(); i++)
			if(vec[v][i] != pdr)
			{
				dist[v][j] += dist[vec[v][i]][j - 1];
			}

//	cout<< masir << endl;
	masir += dist[v][k];
// 	cout<< "vertex " << v + 1 << ": " << masir <<endl;
//	for(int i  = 0; i <= k ; i++)
//		cout<< i << ", " << dist[v][i] << endl;
 	ans += masir;

}

int main()
{

	cin>> n >> k;

	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin>> a >> b;
		a --;
		b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	F(0);
	cout<< ans << endl;
}


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

const int MAXN = 50 * 1000 + 10, MAXK = 500 + 10;
vector <int> vec[MAXN];
int dist[MAXN][MAXK];
bool chck[MAXN];
int n, k, ans = 0;

void F(int v)
{
	chck[v] = true;

	int pdr = -1;
	for(int i = 0; i < vec[v].size(); i++)
	{
		if(chck[vec[v][i]])
			pdr = vec[v][i];
		else
			F(vec[v][i]);
	}

	dist[v][0] = 1;

	int masir = 0;
	for(int j = 0; j < k / 2; j++)
	{
		for(int i = 0; i < vec[v].size(); i++)
		{
			int sum = 0;
			if(vec[v][i] != pdr)
				for(int p = 0; p < vec[v].size(); p++)
				{
					if(vec[v][p] != pdr && i != p)
						sum += dist[vec[v][p]][j];
				}
//cout<< j << " " << vec[v][i] << " " << dist[vec[v][i]][k - j - 2] << " " << sum << endl;
			masir += dist[vec[v][i]][k - j - 2] * sum;

		}
					if(k - j - 2 == j)
				masir /= 2;
	}
	for(int j = 1; j <= k; j++)
		for(int i = 0; i < vec[v].size(); i++)
			if(vec[v][i] != pdr)
			{
				dist[v][j] += dist[vec[v][i]][j - 1];
			}
//	cout<< masir << endl;
	masir += dist[v][k];
// 	cout<< v + 1 << ": " << masir <<endl;
	ans += masir;

}

int main()
{

	cin>> n >> k;

	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin>> a >> b;
		a --;
		b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	F(0);
	cout<< ans << endl;
}


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

//wrong answer test 7

const int MAXN = 50 * 1000 + 10, MAXK = 500 + 10;
vector <int> vec[MAXN];
int dist[MAXN][MAXK];
bool chck[MAXN];
int n, k, ans = 0;

void F(int v)
{
	chck[v] = true;

	int pdr = -1;
	for(int i = 0; i < vec[v].size(); i++)
	{
		if(chck[vec[v][i]])
			pdr = vec[v][i];
		else
			F(vec[v][i]);
	}

	dist[v][0] = 1;

	int masir = 0;
	for(int j = 0; j <= k; j++)
	{
		for(int i = 0; i < vec[v].size(); i++)
		{
			int sum = 0;
			if(vec[v][i] != pdr)
				for(int p = 0; p < vec[v].size(); p++)
				{
					if(vec[v][p] != pdr && i != p)
						sum += dist[vec[v][p]][j];
				}
//cout<< j << " " << vec[v][i] << " " << dist[vec[v][i]][k - j - 2] << " " << sum << endl;
			masir += dist[vec[v][i]][k - j - 2] * sum;

		}
	}
	masir /= 2;

//	cout<< endl;
//	cout<< masir << endl;
	for(int j = 1; j <= k; j++)
		for(int i = 0; i < vec[v].size(); i++)
			if(vec[v][i] != pdr)
			{
				dist[v][j] += dist[vec[v][i]][j - 1];
			}

//	cout<< masir << endl;
	masir += dist[v][k];
// 	cout<< "vertex " << v + 1 << ": " << masir <<endl;
//	for(int i  = 0; i <= k ; i++)
//		cout<< i << ", " << dist[v][i] << endl;
 	ans += masir;

}

int main()
{

	cin>> n >> k;

	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin>> a >> b;
		a --;
		b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}
	if(k == 1)
	{
		cout<< n - 1 << endl;
		return 0;
	}
	F(0);
	cout<< ans << endl;
}


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

const int MAXN = 50 * 1000 + 10, MAXK = 500 + 10;
int ans = 0;
vector <int> vec[MAXN];
int dist[MAXN][MAXK], k, n;
int chck[MAXN];

void DFS(int v)
{
	chck[v] = true;
	for(int i = 0; i < vec[v].size(); i++)
	{
		if(chck[vec[v][i]] == false)
		{
			for(int j = 1; j <= k; j++)
			{
				dist[vec[v][i]][j] = dist[v][j - 1];
			}
			dist[v][1] ++;
			dist[vec[v][i]][1] ++;

			ans += dist[vec[v][i]][k];
			DFS(vec[v][i]);
		}
	}
}

int main()
{
	cin>> n >> k;

	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin>> a >> b;
		a--;
		b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}

	DFS(0);

	cout<< ans << endl;
}


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

const int MAXN = 50 * 1000 + 10;
vector <int> vec[MAXN];
vector <int> dist[MAXN];
int n, k, ans = 0;
bool chck[MAXN];

void F(int v)
{
	chck[v] = true;
	for(int i = 0; i < vec[v].size(); i++)
	{
		//cerr << v << "," << i << "  ";
		if(chck[vec[v][i]] == false)
		{
			dist[v][vec[v][i]] = 1;
			dist[vec[v][i]][v] = 1;
			if(k == 1)
				ans ++;
			for(int j = 0; j < n; j++)
			{
				if(dist[v][j] != 0 && j != vec[v][i])
				{
					dist[vec[v][i]][j] = dist[v][j] + 1;
					dist[j][vec[v][i]] = dist[v][j] + 1;

					if(dist[vec[v][i]][j] == k)
						ans++;
				}
			}

			F(vec[v][i]);
		}
	}

}

int main()
{
	cin>> n >> k;

	for(int i = 0; i < n - 1; i++)
	{
		int a, b;
		cin>> a >> b;
		a--;
		b--;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}

	for(int i = 0; i < n; i++)
		for(int j = 0; j < n; j++)
			dist[i].push_back(0);

	F(0);

	cout<< /*"HEY THE ANS IS HERE! " <<*/ ans << endl;
}


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

const int MAXN = 50 * 1000 + 10, MAXK = 500 + 10;
vector <int> vec[MAXN];
long long d[MAXN][MAXK];
bool mark[MAXN];
long long ans = 0;
int n, k;

void DFS(int v)
{
	mark[v] = true;
	d[v][0] = 1;
	for(int i = 0; i < vec[v].size(); i ++)
	if(!mark[vec[v][i]])
		{
			DFS(vec[v][i]);

			for(int j = 1; j <= k; j ++)
				ans += d[vec[v][i]][j - 1] * d[v][k - j];

			for(int j = 1; j < k; j ++)
				d[v][j] += d[vec[v][i]][j - 1];
		}

}

int main()
{
	cin>> n >> k;

	for(int i = 0; i < n - 1; i ++)
	{
		int a, b;
		cin>> a >> b;
		a --;	b --;
		vec[a].push_back(b);
		vec[b].push_back(a);
	}

	DFS(0);

	cout<< ans << endl;
}


#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

int dist[50001][31],vis[50001],lim[50001];
vector<int> adj[50001];

void dfs(int i)
{
	vis[i]=1;
	int j,l,x;
	for(j=0;j<adj[i].size();j++)
		if(!vis[adj[i][j]])
		{
			dfs(adj[i][j]);
			dist[i][1]++;
			for(l=1;l<=lim[adj[i][j]];l++)
				dist[i][l+1]+=dist[adj[i][j]][l];
			lim[i]=max(lim[adj[i][j]],x+1);
		}
}
int main()
{
	int i,n,x,y,j,k;
	long long int ans,val;
	cin>>n;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
		vis[i+1]=0;
	}

	vis[1]=1;
	dfs(1);
	//	for(i=1;i<=10;i++)
	//	cout<<dist[2][i]<<" ";
	cin>>k;
	ans=0;
	for(i=1;i<=n;i++)
	{
		vis[i]=0;
		dist[i][0]=0;
		ans+=dist[i][k];
	//	cout<<ans;
		for(j=0;j<adj[i].size();j++)
		{
			if(!vis[adj[i][j]])
				continue;
			for(y=1;y<k-1;y++)
			{
				ans+=0.5*(dist[adj[i][j]][y-1]*(dist[i][x-y]-dist[adj[i][j]][x-y-1]));
			}
			if(k!=2&&y==k-1)
				ans+=dist[adj[i][j]][y-1]*(dist[i][k-y]-1);

		}
		if(k==2)
			ans+=(dist[i][1]*(dist[i][1]-1))/2;
	}
	cout<<ans;
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

int vis[50001];
vector<int> adj[50001];
int k;
long long int ans, dist[50001][31];
void dfs(int i)
{
	vis[i]=1;
	int j,v;
	dist[i][0]=1;
	for(j=0;j<adj[i].size();j++)
		if(!vis[adj[i][j]])
		{
			dfs(adj[i][j]);
			v=adj[i][j];
			for(int x=1;x<=k;x++)
				ans+=dist[i][x-1]*dist[v][k-x];
			for(int x=1;x<=k;x++)
				dist[i][x]+=dist[v][x-1];
		}
}
int main()
{
	int i,n,x,y,j;
	cin>>n>>k;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
		vis[i+1]=0;
	}
	ans=0;
	dfs(1);
/*	for(j=1;j<=n;j++)
	{
		cout<<lim[j]<<" ";
		for(i=1;i<=10;i++)
			cout<<dist[j][i]<<" ";
		cout<<"\n";
	}*/

/*	for(i=1;i<=n;i++)
	{
		vis[i]=0;
		dist[i][0]=0;
		ans+=dist[i][k];
	//	cout<<ans;
		for(j=0;j<adj[i].size();j++)
		{
			if(!vis[adj[i][j]])
				continue;
			for(y=1;y<k-1;y++)
			{
				ans+=0.5*(dist[adj[i][j]][y-1]*(dist[i][x-y]-dist[adj[i][j]][x-y-1]));
			}
			if(k!=2&&y==k-1)
				ans+=dist[adj[i][j]][y-1]*(dist[i][k-y]-1);

		}
		if(k==2)
			ans+=(dist[i][1]*(dist[i][1]-1))/2;
	}*/
	cout<<ans;
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

int dist[50001][31],vis[50001],lim[50001];
vector<int> adj[50001];

void dfs(int i)
{
	vis[i]=1;
	int j,l,x;
	for(j=0;j<adj[i].size();j++)
		if(!vis[adj[i][j]])
		{
			dfs(adj[i][j]);
			dist[i][1]++;
			for(l=1;l<=lim[adj[i][j]];l++)
				dist[i][l+1]+=dist[adj[i][j]][l];
			lim[i]=max(lim[adj[i][j]]+1,lim[i]);
		}
}
int main()
{
	int i,n,x,y,j,k;
	long long int ans,val;
	cin>>n>>k;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
		vis[i+1]=0;
	}
	dfs(1);
/*	for(j=1;j<=n;j++)
	{
		cout<<lim[j]<<" ";
		for(i=1;i<=10;i++)
			cout<<dist[j][i]<<" ";
		cout<<"\n";
	}*/
	ans=0;
	for(i=1;i<=n;i++)
	{
		vis[i]=0;
		dist[i][0]=0;
		ans+=dist[i][k];
	//	cout<<ans;
		for(j=0;j<adj[i].size();j++)
		{
			if(!vis[adj[i][j]])
				continue;
			for(y=1;y<k-1;y++)
			{
				ans+=0.5*(dist[adj[i][j]][y-1]*(dist[i][x-y]-dist[adj[i][j]][x-y-1]));
			}
			if(k!=2&&y==k-1)
				ans+=dist[adj[i][j]][y-1]*(dist[i][k-y]-1);

		}
		if(k==2)
			ans+=(dist[i][1]*(dist[i][1]-1))/2;
	}
	cout<<ans;
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

int vis[50001];
vector<int> adj[50001];
int k;
long long int ans, dist[50001][501];
void dfs(int i)
{
	vis[i]=1;
	int j,v;
	dist[i][0]=1;
	for(j=0;j<adj[i].size();j++)
		if(!vis[adj[i][j]])
		{
			dfs(adj[i][j]);
			v=adj[i][j];
			for(int x=1;x<=k;x++)
				ans+=dist[i][x-1]*dist[v][k-x];
			for(int x=1;x<=k;x++)
				dist[i][x]+=dist[v][x-1];
		}
}
int main()
{
	int i,n,x,y,j;
	cin>>n>>k;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
		vis[i+1]=0;
	}
	ans=0;
	dfs(1);
/*	for(j=1;j<=n;j++)
	{
		cout<<lim[j]<<" ";
		for(i=1;i<=10;i++)
			cout<<dist[j][i]<<" ";
		cout<<"\n";
	}*/

/*	for(i=1;i<=n;i++)
	{
		vis[i]=0;
		dist[i][0]=0;
		ans+=dist[i][k];
	//	cout<<ans;
		for(j=0;j<adj[i].size();j++)
		{
			if(!vis[adj[i][j]])
				continue;
			for(y=1;y<k-1;y++)
			{
				ans+=0.5*(dist[adj[i][j]][y-1]*(dist[i][x-y]-dist[adj[i][j]][x-y-1]));
			}
			if(k!=2&&y==k-1)
				ans+=dist[adj[i][j]][y-1]*(dist[i][k-y]-1);

		}
		if(k==2)
			ans+=(dist[i][1]*(dist[i][1]-1))/2;
	}*/
	cout<<ans;
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

int dist[50001][31],vis[50001];
vector<int> adj[50001];
int k;
long long int ans;
void dfs(int i)
{
	vis[i]=1;
	int j,v;
	dist[i][0]=1;
	for(j=0;j<adj[i].size();j++)
		if(!vis[adj[i][j]])
		{
			dfs(adj[i][j]);
			v=adj[i][j];
			for(int x=1;x<=k;x++)
				ans+=dist[i][x-1]*dist[v][k-x];
			for(int x=1;x<=k;x++)
				dist[i][x]+=dist[v][x-1];
		}
}
int main()
{
	int i,n,x,y,j;
	cin>>n>>k;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
		vis[i+1]=0;
	}
	ans=0;
	dfs(1);
/*	for(j=1;j<=n;j++)
	{
		cout<<lim[j]<<" ";
		for(i=1;i<=10;i++)
			cout<<dist[j][i]<<" ";
		cout<<"\n";
	}*/

/*	for(i=1;i<=n;i++)
	{
		vis[i]=0;
		dist[i][0]=0;
		ans+=dist[i][k];
	//	cout<<ans;
		for(j=0;j<adj[i].size();j++)
		{
			if(!vis[adj[i][j]])
				continue;
			for(y=1;y<k-1;y++)
			{
				ans+=0.5*(dist[adj[i][j]][y-1]*(dist[i][x-y]-dist[adj[i][j]][x-y-1]));
			}
			if(k!=2&&y==k-1)
				ans+=dist[adj[i][j]][y-1]*(dist[i][k-y]-1);

		}
		if(k==2)
			ans+=(dist[i][1]*(dist[i][1]-1))/2;
	}*/
	cout<<ans;
	return 0;
}


#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;

int dist[50001][31],vis[50001],lim[50001];
vector<int> adj[50001];

void dfs(int i)
{
	vis[i]=1;
	int j,l,x;
	for(j=0;j<adj[i].size();j++)
		if(!vis[adj[i][j]])
		{
			dfs(adj[i][j]);
			dist[i][1]++;
			for(l=1;l<=lim[adj[i][j]];l++)
				dist[i][l+1]+=dist[adj[i][j]][l];
			lim[i]=max(lim[adj[i][j]],x+1);
		}
}
int main()
{
	int i,n,x,y,j,k;
	long long int ans,val;
	cin>>n>>k;
	for(i=1;i<n;i++)
	{
		cin>>x>>y;
		adj[x].push_back(y);
		adj[y].push_back(x);
		vis[i+1]=0;
	}

	vis[1]=1;
	dfs(1);
	//	for(i=1;i<=10;i++)
	//	cout<<dist[2][i]<<" ";

	ans=0;
	for(i=1;i<=n;i++)
	{
		vis[i]=0;
		dist[i][0]=0;
		ans+=dist[i][k];
	//	cout<<ans;
		for(j=0;j<adj[i].size();j++)
		{
			if(!vis[adj[i][j]])
				continue;
			for(y=1;y<k-1;y++)
			{
				ans+=0.5*(dist[adj[i][j]][y-1]*(dist[i][x-y]-dist[adj[i][j]][x-y-1]));
			}
			if(k!=2&&y==k-1)
				ans+=dist[adj[i][j]][y-1]*(dist[i][k-y]-1);

		}
		if(k==2)
			ans+=(dist[i][1]*(dist[i][1]-1))/2;
	}
	cout<<ans;
	return 0;
}


#include<bits/stdc++.h>

#define cinn ios_base::sync_with_stdio(false)
#define pb push_back
#define pp pop_back
#define f first
#define s second
#define pii pair<int,int>
#define FPR(i,a,b) for(int i=a;i<=b;i++)
#define FI(it,a,b) for(it = a ; it != b ;it ++)
#define ROF(i,b,a) for(int i=b;i>=a;i--)
#define wait getchar("")
#define bo " "
#define lint
#define MAXN 50005
#define MAXK 505

using namespace std;

int D[50005][505] , res = 0 , n , k;
bool H[50005];
vector <int> V[50005] ;

void ff(int ver){		// vertex

	int i , j , m = V[ver].size() ;

	D[ver][0] = 1 ;
	H[ver] = 1 ;

	FPR(i,0,m-1)
	{
		if(H[V[ver][i]]) continue ;
		ff(V[ver][i]) ;
		FPR(j,0,k-1)
			res += D[V[ver][i]][j] * D[ver][k-j-1] ;
		FPR(j,1,k)
			D[ver][j] += D[V[ver][i]][j-1] ;
	}
}
int main(){

	int i,j,a,b;

	cin >> n >> k ;

	FPR(i,1,n-1)
	{
		scanf("%d %d",&a,&b) ;
		V[b].pb(a) ;
		V[a].pb(b) ;
	}

	ff(1) ;

	cout << res << endl ;

	return 0;
}


#include<bits/stdc++.h>

#define cinn ios_base::sync_with_stdio(false)
#define pb push_back
#define pp pop_back
#define f first
#define s second
#define pii pair<int,int>
#define FPR(i,a,b) for(int i=a;i<=b;i++)
#define FI(it,a,b) for(it = a ; it != b ;it ++)
#define ROF(i,b,a) for(int i=b;i>=a;i--)
#define wait getchar("")
#define bo " "
#define lint
#define MAXN 50005
#define MAXK 505

using namespace std;

int D[50005][505] , res = 0 , n , k;
bool H[50005];
vector <int> V[50005] ;

void ff(int ver){		// vertex

	int i , j , m = V[ver].size() ;

	D[ver][0] = 1 ;
	H[ver] = 1 ;

	FPR(i,0,m-1)
	{
		if(H[V[ver][i]]) continue ;
		ff(V[ver][i]) ;
		FPR(j,0,k-1)
			res += D[V[ver][i]][j] * D[ver][k-j-1] ;
		FPR(j,1,k)
			D[ver][j] += D[V[ver][i]][j-1] ;
	}
}
int main(){

	cinn;

	int i,j,a,b;

	cin >> n >> k ;

	FPR(i,1,n-1)
	{
		scanf("%d %d",&a,&b) ;
		V[b].pb(a) ;
		V[a].pb(b) ;
	}

	ff(1) ;

	cout << res << endl ;

	return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define pp pop_back
#define mkp make_pair
#define f first
#define s second
#define pii pair<int,int>

using namespace std;

int n , k , zim;
vector <int> V[50005] ;
map < pii , int > c ;
map < pii , bool > D ;
map < int , int > o ;
map < pii , int > :: iterator  it ;
bool H[50005];

void ff(int node,int mal){

	if(mal > n) return ;
	int i,j,t;
	t = V[node].size() ;
	for(i=0;i<t;i++)
	{
		if(!V[node][i]) continue;
		if(zim == V[node][i]) continue ;
		if(c[mkp(zim,V[node][i])]) continue ;
		c[mkp(zim,V[node][i])] = mal ;
		if(!H[V[node][i]])
		{
			H[V[node][i]] = 1 ;
			ff(V[node][i] , mal+1) ;
			H[V[node][i]] = 0 ;
		}
	}
	return  ;
}

void APSP(){

	int i,j;
	int st = 1 ,res=0;
	pii t , t2 ;

	for(i=1;i<=n;i++)
	{
		zim = i ;
		ff(i,1) ;
	}

	for(it = c.begin();it!=c.end();it++)
	{
		t = (*it).f ;
		if(c[t]!=k) continue ;
		t2.s = t.f ; t2.f = t.s ;
		if(!D[t] && !D[t2])
		{
			D[t] = D[t2] = 1;
			res++;
		}

	}
	cout << res << endl ;

}
int main(){

	int i,j,a,b;
	cin >> n >> k ;
	for(i=1;i<n;i++)
	{
		scanf("%d %d",&a,&b) ;
		V[a].pb(b) ;
		V[b].pb(a) ;
	}

	APSP();

	return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define pp pop_back
#define mkp make_pair
#define f first
#define s second
#define pii pair<int,int>

using namespace std;

int n , k , zim;
vector <int> V[50005] ;
map < pii , int > c ;
map < pii , bool > D ;
map < int , int > o ;
map < pii , int > :: iterator  it ;
bool H[50005];

void ff(int node,int mal){

	if(mal > k) return ;
	int i,j,t;
	t = V[node].size() ;
	for(i=0;i<t;i++)
	{
		if(!V[node][i]) continue;
		if(zim == V[node][i]) continue ;
		if(c[mkp(zim,V[node][i])]) continue ;
		c[mkp(zim,V[node][i])] = mal ;
		if(!H[V[node][i]])
		{
			H[V[node][i]] = 1 ;
			ff(V[node][i] , mal+1) ;
			H[V[node][i]] = 0 ;
		}
	}
	return  ;
}

void APSP(){

	int i,j;
	int st = 1 ,res=0;
	pii t , t2 ;

	for(i=1;i<=n;i++)
	{
		zim = i ;
		ff(i,1) ;
	}

	for(it = c.begin();it!=c.end();it++)
	{
		t = (*it).f ;
		if(c[t]!=k) continue ;
		t2.s = t.f ; t2.f = t.s ;
		if(!D[t] && !D[t2])
		{
			D[t] = D[t2] = 1;
			res++;
		}

	}
	cout << res << endl ;

}
int main(){

	int i,j,a,b;
	cin >> n >> k ;
	for(i=1;i<n;i++)
	{
		scanf("%d %d",&a,&b) ;
		V[a].pb(b) ;
		V[b].pb(a) ;
	}

	APSP();

	return 0;
}


#include<bits/stdc++.h>

#define cinn ios_base::sync_with_stdio(false)
#define pb push_back
#define pp pop_back
#define f first
#define s second
#define pii pair<int,int>
#define FPR(i,a,b) for(int i=a;i<=b;i++)
#define FI(it,a,b) for(it = a ; it != b ;it ++)
#define ROF(i,b,a) for(int i=b;i>=a;i--)
#define wait getchar("")
#define bo " "
#define lint
#define MAXN 50005
#define MAXK 505

using namespace std;

int D[MAXN][MAXK] , res = 0 , n , k;
bool H[MAXN];
vector <int> V[MAXN] ;

void ff(int ver){		// vertex

	int i , j , m = V[ver].size() ;

	D[ver][0] = 1 ;
	H[ver] = 1 ;

	FPR(i,0,m-1)
	{
		if(H[V[ver][i]]) continue ;
		ff(V[ver][i]) ;
		FPR(j,0,k-1)
			res += D[V[ver][i]][j] * D[ver][k-j-1] ;
		FPR(j,1,k)
			D[ver][j] += D[V[ver][i]][j-1] ;
	}
}
int main(){

	cinn;

	int i,j,a,b;

	cin >> n >> k ;

	FPR(i,1,n-1)
	{
		scanf("%d %d",&a,&b) ;
		V[b].pb(a) ;
		V[a].pb(b) ;
	}

	ff(1) ;

	cout << res << endl ;

	return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define pp pop_back
#define mkp make_pair
#define f first
#define s second
#define pii pair<int,int>

using namespace std;

int n , k , zim;
vector <int> V[50005] ;
map < pii , int > c ;
map < pii , bool > D ;
map < int , int > o ;
map < pii , int > :: iterator  it , ii , h;
bool H[50005];

void APSP(){

	int i,j,sd;
	int st = 1 ,res=0,mal,ut;
	pii t , t2 ,tt,as;

	for(i=1;i<=n;i++)
	{
		sd = V[i].size();
		for(j=0;j<sd;j++)
			c[mkp(i,V[i][j])] = 1;
	}
	for(it = c.begin() ; it!=c.end() ; it++)
	{
		t = (*it).f; mal = (*it).s  ;
		ut = V[t.s].size() ;

		for(j=0;j<ut;j++)
			if( c[mkp(t.f,V[t.s][j])] == 0)
				c[mkp(t.f,V[t.s][j])] = mal+1 ;
			else
				c[mkp(t.f,V[t.s][j])] = min(c[mkp(t.f,V[t.s][j])],mal+1);
	}
	for(it = c.begin();it!=c.end();it++)
	{
		t = (*it).f ;
		if(c[t]!=k) continue ;
		t2.s = t.f ; t2.f = t.s ;
		if(t.f == t.s) continue ;
		if(!D[t] && !D[t2])
		{
			D[t] = D[t2] = 1;
			res++;
		}

	}
	cout << res << endl ;

}
int main(){

	int i,j,a,b;
	cin >> n >> k ;
	for(i=1;i<n;i++)
	{
		scanf("%d %d",&a,&b) ;
		V[a].pb(b) ;
		V[b].pb(a) ;
	}

	APSP();

	return 0;
}


#include<bits/stdc++.h>

#define pb push_back
#define pp pop_back
#define mkp make_pair
#define f first
#define s second
#define pii pair<int,int>

using namespace std;

int n , k , zim;
vector <int> V[50005] ;
map < pii , int > c ;
map < pii , bool > D ;
map < int , int > o ;
map < pii , int > :: iterator  it ;
bool H[50005];

void ff(int node,int mal){

	if(mal > n) return ;
	int i,j,t;
	t = V[node].size() ;
	for(i=0;i<t;i++)
	{
		if(!V[node][i]) continue;
		if(zim == V[node][i]) continue ;
		if(c[mkp(zim,V[node][i])]) continue ;
		c[mkp(zim,V[node][i])] = mal ;
		ff(V[node][i] , mal+1) ;
	}
	return  ;
}

void APSP(){

	int i,j;
	int st = 1 ,res=0;
	pii t , t2 ;

	for(i=1;i<=n;i++)
	{
		zim = i ;
		ff(i,1) ;
	}

	for(it = c.begin();it!=c.end();it++)
	{
		t = (*it).f ;
		if(c[t]!=k) continue ;
		t2.s = t.f ; t2.f = t.s ;
		if(!D[t] && !D[t2])
		{
			D[t] = D[t2] = 1;
			res++;
		}

	}
	cout << res << endl ;

}
int main(){

	int i,j,a,b;
	cin >> n >> k ;
	for(i=1;i<n;i++)
	{
		scanf("%d %d",&a,&b) ;
		V[a].pb(b) ;
		V[b].pb(a) ;
	}

	APSP();

	return 0;
}


#include<vector>
#include<cstdio>
using namespace std;

const int maxn = 50 * 1000, maxk = 501;
int n, parent[maxn], dist[maxn], k;
vector<int> v[maxn], q;
long long javab = 0, dp[maxn][maxk];

void bfs(int x)
{
	int y = 0;
	q.push_back(x);
	parent[x] = x;
	dist[x] = 0;
	while(y < q.size())
	{
		x = q[y];
		y++;
		for(int i = 0; i < v[x].size(); i++)
			if(v[x][i] != parent[x])
			{
				q.push_back(v[x][i]);
				parent[v[x][i]] = x;
				dist[v[x][i]] = dist[x] + 1;
			}
	}
}

int main()
{
	int x, y;
	long long z;
	scanf("%d %d", &n, &k);
	for(int i = 0; i < n - 1; i++)
	{
		scanf("%d %d", &x, &y);
		x--;
		y--;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	if(k == 1)
	{
		printf("%d", n - 1);
		return 0;
	}
	bfs(0);
	for(int i = q.size() - 1; i >= 0; i--)
	{
		x = q[i];
		dp[x][0] += 1;
		for(int j = 0; j < v[x].size(); j++)
			if(v[x][j] != parent[x])
				for(int l = 1; l <= k; l++)
					dp[x][l] += dp[v[x][j]][l - 1];
	}
	for(int i = 0; i < n; i++)
	{
		javab += dp[i][k];
		z = 0;
		for(int j = 1; j < k; j++)
		{
			x = j - 1;
			y = k - j - 1;
			for(int l = 0; l < v[i].size(); l++)
				if(v[i][l] != parent[i])
					z += dp[v[i][l]][x];
			for(int l = 0; l < v[i].size(); l++)
				if(v[i][l] != parent[i])
				{
					z -= dp[v[i][l]][x];
					javab += dp[v[i][l]][y] * z;
				}
		}
	}
	printf("%I64d", javab);
	return 0;
}


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

const int maxn = 50 * 1000 + 2, maxk = 500 + 2;
int n, k, a[maxn][maxk], dist[maxn], javab = 0;
bool check[maxn];
vector<int> v[maxn], l[maxn], child[maxn];

int bfs(int x)
{
	queue<int> q;
	q.push(x);
	check[x] = true;
	dist[x] = 0;
	l[0].push_back(x);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(check[v[x][i]] == false)
			{
				check[v[x][i]] = true;
				q.push(v[x][i]);
				child[x].push_back(v[x][i]);
				dist[v[x][i]] = dist[x] + 1;
				l[dist[v[x][i]]].push_back(v[x][i]);
			}
		}
	}
	return x;
}

int main()
{
	int x, y;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> x >> y;
		x--;
		y--;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	x = bfs(0);
	x = dist[x];
	int e[k + 1];
	for(int i = x; i >= 0; i--)
	{
		for(int j = 0; j < (int) l[i].size(); j++)
		{
			for(int h = 0; h <= k; h++)
				e[h] = 0;
			a[l[i][j]][0] = 1;
			for(int s = 0; s < (int) child[l[i][j]].size(); s++)
			{
				e[0] += a[child[l[i][j]][s]][0];
				for(int f = 1; f <= k; f++)
				{
					a[l[i][j]][f] += a[child[l[i][j]][s]][f - 1];
					e[f] += a[child[l[i][j]][s]][f];
				}
				for(int f = 2; f <= k; f++)
					a[child[l[i][j]][s]][f] += e[f - 2] - a[child[l[i][j]][s]][f - 2];
			}
		}
	}
	for(int i = 0; i < n; i++)
	{
		javab += a[i][k];
	}
	cout << javab << endl;
	return 0;
}


#include<vector>
#include<cstdio>
using namespace std;

const int maxn = 50 * 1000, maxk = 501;
int n, parent[maxn], k;
vector<int> v[maxn], q;
long long javab = 0, dp[maxn][maxk];

void bfs(int x)
{
	int y = 0;
	q.push_back(x);
	parent[x] = x;
	while(y < q.size())
	{
		x = q[y];
		y++;
		for(int i = 0; i < v[x].size(); i++)
			if(v[x][i] != parent[x])
			{
				q.push_back(v[x][i]);
				parent[v[x][i]] = x;
			}
	}
}

int main()
{
	int x, y;
	long long z;
	scanf("%d %d", &n, &k);
	for(int i = 0; i < n - 1; i++)
	{
		scanf("%d %d", &x, &y);
		x--;
		y--;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	if(k == 1)
	{
		printf("%d", n - 1);
		return 0;
	}
	bfs(0);
	for(int i = q.size() - 1; i >= 0; i--)
	{
		x = q[i];
		dp[x][0] += 1;
		for(int j = 0; j < v[x].size(); j++)
			if(v[x][j] != parent[x])
				for(int l = 1; l <= k; l++)
					dp[x][l] += dp[v[x][j]][l - 1];
	}
	for(int i = 0; i < n; i++)
	{
		javab += dp[i][k];
		z = 0;
		for(int j = 1; j < k; j++)
		{
			x = j - 1;
			y = k - j - 1;
			for(int l = 0; l < v[i].size(); l++)
				if(v[i][l] != parent[i])
					z += dp[v[i][l]][x];
			for(int l = 0; l < v[i].size(); l++)
				if(v[i][l] != parent[i])
				{
					z -= dp[v[i][l]][x];
					javab += dp[v[i][l]][y] * z;
				}
		}
	}
	printf("%I64d", javab);
	return 0;
}


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

const int maxn = 50000;
int n, k, javab = 0;
vector<int> v[maxn], t[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(x);
				t[v[x][i]].push_back(1);
				t[x].push_back(v[x][i]);
				t[x].push_back(1);
				for(int j = 0; j < (int) t[x].size(); j += 2)
				{
					if(t[x][j] == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(t[x][j]);
					t[v[x][i]].push_back(t[x][j + 1] + 1);
					t[t[x][j]].push_back(v[x][i]);
					t[t[x][j]].push_back(t[x][j + 1] + 1);
					if(t[x][j + 1] + 1 == k)
						javab++;
				}
			}
		}
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	cout << javab << endl;
	return 0;
}


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

int main()
{
	const int maxn = 50000;
	vector<int> v[maxn], t[maxn];
	bool chek[maxn];
	int a, b, x, n, k, javab = 0;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		chek[a] = false;
		chek[b] = false;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	queue<int> q;
	chek[0] = true;
	q.push(0);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(x);
				t[v[x][i]].push_back(1);
				t[x].push_back(v[x][i]);
				t[x].push_back(1);
				for(int j = 0; j < (int) t[x].size(); j += 2)
				{
					if(t[x][j] == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(t[x][j]);
					t[v[x][i]].push_back(t[x][j + 1] + 1);
					t[t[x][j]].push_back(v[x][i]);
					t[t[x][j]].push_back(t[x][j + 1] + 1);
					if(t[x][j + 1] + 1 == k)
						javab++;
				}
			}
		}
	}
	cout << javab << endl;
	return 0;
}


#include<iostream>
#include<vector>
#include<queue>
#include<stdio.h>
using namespace std;

const int maxn = 500 * 1000 + 5;
int n, k, javab = 0;
vector<int> v[maxn];
vector<pair<int, int> > t[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(make_pair(x, 1));
				t[x].push_back(make_pair(v[x][i], 1));
				for(int j = 0; j < (int) t[x].size(); j++)
				{
					if(t[x][j].first == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(make_pair(t[x][j].first, t[x][j].second + 1));
					t[t[x][j].first].push_back(make_pair(v[x][i], t[x][j].second + 1));
					if(t[x][j].second + 1 == k)
						javab++;
				}
			}
		}
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	cout << javab << endl;
	return 0;
}


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

const int maxn = 50 * 1000, maxk = 501;
int n, parent[maxn], dist[maxn], k;
vector<int> v[maxn], q;
long long javab = 0, dp[maxn][maxk];

void bfs(int x)
{
	int y = 0;
	q.push_back(x);
	parent[x] = x;
	dist[x] = 0;
	while(y < q.size())
	{
		x = q[y];
		y++;
		for(int i = 0; i < v[x].size(); i++)
			if(v[x][i] != parent[x])
			{
				q.push_back(v[x][i]);
				parent[v[x][i]] = x;
				dist[v[x][i]] = dist[x] + 1;
			}
	}
}

int main()
{
	int x, y;
	long long z;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> x >> y;
		x--;
		y--;
		v[x].push_back(y);
		v[y].push_back(x);
	}
	if(k == 1)
	{
		cout << n - 1 << endl;
		return 0;
	}
	bfs(0);
	for(int i = q.size() - 1; i >= 0; i--)
	{
		x = q[i];
		dp[x][0] += 1;
		for(int j = 0; j < v[x].size(); j++)
			if(v[x][j] != parent[x])
				for(int l = 1; l <= k; l++)
					dp[x][l] += dp[v[x][j]][l - 1];
	}
	for(int i = 0; i < n; i++)
	{
		javab += dp[i][k];
		z = 0;
		for(int j = 1; j < k; j++)
		{
			x = j - 1;
			y = k - j - 1;
			for(int l = 0; l < v[i].size(); l++)
				if(v[i][l] != parent[i])
					z += dp[v[i][l]][x];
			for(int l = 0; l < v[i].size(); l++)
				if(v[i][l] != parent[i])
				{
					z -= dp[v[i][l]][x];
					javab += dp[v[i][l]][y] * z;
				}
		}
	}
	cout << javab << endl;
	return 0;
}


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

const int maxn = 500 * 1000 + 5;
int n, k, javab = 0;
vector<int> v[maxn];
vector<pair<int, int> > t[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(make_pair(x, 1));
				t[x].push_back(make_pair(v[x][i], 1));
				for(int j = 0; j < (int) t[x].size(); j++)
				{
					if(t[x][j].first == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(make_pair(t[x][j].first, t[x][j].second + 1));
					if(t[x][j].second + 1 == k)
						javab++;
				}
			}
		}
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	cout << javab << endl;
	return 0;
}


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

const int maxn = 500 * 1000 + 1;
int n, k, javab = 0;
vector<int> v[maxn];
vector<pair<int, int> > t[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(make_pair(x, 1));
				t[x].push_back(make_pair(v[x][i], 1));
				for(int j = 0; j < (int) t[x].size(); j++)
				{
					if(t[x][j].first == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(make_pair(t[x][j].first, t[x][j].second + 1));
					t[t[x][j].first].push_back(make_pair(v[x][i], t[x][j].second + 1));
					if(t[x][j].second + 1 == k)
						javab++;
				}
			}
		}
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	cout << javab << endl;
	return 0;
}


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

const int maxn = 50000 + 2, maxk = 500 + 2;
int n, k, javab = 0, t[maxn][maxk];
vector<int> v[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		t[x][0]++;
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				for(int j = 0; j < k; j++)
					t[v[x][i]][j + 1] = t[x][j];
				t[x][1]++;
			}
		}
		q.pop();
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	for(int i = 0; i < n; i++)
		javab += t[i][k];
	cout << javab << endl;
	return 0;
}


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

int main()
{
	const int maxn = 50000 + 5;
	vector<int> v[maxn], t[maxn];
	bool chek[maxn];
	int a, b, x, n, k, javab = 0;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		chek[a] = false;
		chek[b] = false;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	queue<int> q;
	chek[0] = true;
	q.push(0);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(x);
				t[v[x][i]].push_back(1);
				t[x].push_back(v[x][i]);
				t[x].push_back(1);
				for(int j = 0; j < (int) t[x].size(); j += 2)
				{
					if(t[x][j] == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(t[x][j]);
					t[v[x][i]].push_back(t[x][j + 1] + 1);
					t[t[x][j]].push_back(v[x][i]);
					t[t[x][j]].push_back(t[x][j + 1] + 1);
					if(t[x][j + 1] + 1 == k)
						javab++;
				}
			}
		}
	}
	cout << javab << endl;
	return 0;
}


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

const int maxn = 500 * 1000 + 1;
int n, k, javab = 0;
vector<int> v[maxn];
vector<int> t[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(x);
				t[v[x][i]].push_back(1);
				t[x].push_back(v[x][i]);
				t[x].push_back(1);
				for(int j = 0; j < (int) t[x].size(); j += 2)
				{
					if(t[x][j] == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(t[x][j]);
					t[v[x][i]].push_back(t[x][j + 1] + 1);
					t[t[x][j]].push_back(v[x][i]);
					t[t[x][j]].push_back(t[x][j + 1] + 1);
					if(t[x][j + 1] + 1 == k)
						javab++;
				}
			}
		}
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	cout << javab << endl;
	return 0;
}


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

const int maxn = 50000 + 2, maxk = 500 + 2;
int n, k, javab = 0, t[maxn][maxk];
vector<int> v[maxn];
bool chek[maxn];

void bfs(int x)
{
	int p = 0;
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		p = 0;
		t[x][0]++;
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				for(int j = 0; j < k; j++)
					t[v[x][i]][j + 1] = t[x][j];
				t[v[x][i]][2] += p;
				p++;
			}
		}
		q.pop();
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	for(int i = 0; i < n; i++)
		javab += t[i][k];
	cout << javab << endl;
	return 0;
}


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

const int maxn = 50000 + 2, maxk = 500 + 2;
int n, k, javab = 0, t[maxn][maxk];
vector<int> v[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	t[x][0]++;
	while(! q.empty())
	{
		x = q.front();
		t[x][0]++;
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				for(int j = 0; j < k; i++)
					t[v[x][i]][j + 1] = t[x][j];
			}
		}
		q.pop();
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	for(int i = 0; i < n; i++)
		javab += t[i][k];
	cout << javab << endl;
	return 0;
}


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

const int maxn = 50 * 1000 + 3;
int n, k, javab = 0;
vector<int> v[maxn], t[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		q.pop();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(x);
				t[v[x][i]].push_back(1);
				t[x].push_back(v[x][i]);
				t[x].push_back(1);
				for(int j = 0; j < (int) t[x].size(); j += 2)
				{
					if(t[x][j] == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(t[x][j]);
					t[v[x][i]].push_back(t[x][j + 1] + 1);
					t[t[x][j]].push_back(v[x][i]);
					t[t[x][j]].push_back(t[x][j + 1] + 1);
					if(t[x][j + 1] + 1 == k)
						javab++;
				}
			}
		}
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	cout << javab << endl;
	return 0;
}


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

const int maxn = 50000;
int n, k, javab = 0;
vector<int> v[maxn], t[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(x);
				t[v[x][i]].push_back(1);
				t[x].push_back(v[x][i]);
				t[x].push_back(1);
				for(int j = 0; j < (int) t[x].size(); j += 2)
				{
					if(t[x][j] == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(t[x][j]);
					t[v[x][i]].push_back(t[x][j + 1] + 1);
					t[t[x][j]].push_back(v[x][i]);
					t[t[x][j]].push_back(t[x][j + 1] + 1);
					if(t[x][j + 1] + 1 == k)
						javab++;
				}
			}
		}
		v[x].clear();
		t[x].clear();
		q.pop();
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	cout << javab << endl;
	return 0;
}


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

const int maxn = 50000;
int n, k, javab = 0;
vector<int> v[maxn], t[maxn];
bool chek[maxn];

void bfs(int x)
{
	queue<int> q;
	chek[x] = true;
	q.push(x);
	while(! q.empty())
	{
		x = q.front();
		for(int i = 0; i < (int) v[x].size(); i++)
		{
			if(chek[v[x][i]] == false)
			{
				q.push(v[x][i]);
				chek[v[x][i]] = true;
				t[v[x][i]].push_back(x);
				t[v[x][i]].push_back(1);
				t[x].push_back(v[x][i]);
				t[x].push_back(1);
				for(int j = 0; j < (int) t[x].size(); j += 2)
				{
					if(t[x][j] == v[x][i])
					{
						if(k == 1)
							javab++;
						continue;
					}
					t[v[x][i]].push_back(t[x][j]);
					t[v[x][i]].push_back(t[x][j + 1] + 1);
					t[t[x][j]].push_back(v[x][i]);
					t[t[x][j]].push_back(t[x][j + 1] + 1);
					if(t[x][j + 1] + 1 == k)
						javab++;
				}
			}
		}
		v[x].clear();
		q.pop();
	}
}

int main()
{
	int a, b;
	cin >> n >> k;
	for(int i = 0; i < n - 1; i++)
	{
		cin >> a >> b;
		a--;
		b--;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	bfs(0);
	cout << javab << endl;
	return 0;
}


#pragma GCC optimize("O3")
#include<bit/stdc++.h>
#define N 50005
using namespace std;
int n,K,rt,sz[N];
int cnt[505],tmp[505];
vector<int> lin[N];
int vis[N],f[N];
int size;
long long ans;
inline int getrt(int x,int fa)
{
    sz[x]=1;
    f[x]=0;
    for(register int i=0;i<lin[x].size();++i)
    {
        int u=lin[x][i];
        if(u==fa||vis[u])
			continue;
        getrt(u,x);
        sz[x]+=sz[u];
        f[x]=max(f[x],sz[u]);
    }
    f[x]=max(f[x],size-f[x]);
    if(f[rt]>f[x])
		rt=x;

}
inline void getdis(int x,int fa,int dis)
{
    sz[x]=1;
    if(dis<=K)
    {
        ans+=cnt[K-dis];
        ++tmp[dis];
    }
    for(register int i=0;i<lin[x].size();++i)
    {
        int u=lin[x][i];
        if(vis[u]||u==fa)
			continue;
        getdis(u,x,dis+1);
        sz[x]+=sz[u];
    }
}
inline void cal(int x)
{
    memset(cnt,0,sizeof(cnt));
    int ret=0;
    cnt[0]=1;
    for(register int i=0;i<lin[x].size();++i)
    {
        int u=lin[x][i];
        if(vis[u])
			continue;
        memset(tmp,0,sizeof(tmp));
        getdis(u,u,1);
        for(int j=1;j<=K;j++)
        	cnt[j]+=tmp[j];
    }
}
inline void solve(int x)
{
    vis[x]=1;
    cal(x);
    for(register int i=0;i<lin[x].size();++i)
    {
        int u=lin[x][i];
        if(vis[u])
			continue;
        f[0]=size=sz[u];
        getrt(u,rt=0);
        solve(rt);
    }
}
int main()
{
    int aa,bb;
    scanf("%d%d",&n,&K);
    for(register int i=1;i<n;++i)
    {
        scanf("%d%d",&aa,&bb);
        lin[aa].push_back(bb);
        lin[bb].push_back(aa);
    }
    f[0]=size=n;
    getrt(1,rt=0);
    solve(rt);
    cout<<ans<<endl;
    return 0;
}


#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define N 50005
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0' || ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    while ('0'<=ch && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*f;
}
inline int Max(register int a,register int b)
{
	if(a>b)
		return a;
	return b;
}
int n,k;
long long ans;
struct edge{
	int to,next;
}e[N<<1];
int head[N],tot=0;
int num,rt,size,siz[N],f[N];
bool vis[N];
struct node{
	int d,w;
}dis[N];
inline void add(register int x,register int y)
{
	e[++tot].to=y;
	e[tot].next=head[x];
	head[x]=tot;
}
inline void getroot(register int x,register int fa)
{
	f[x]=0;
	siz[x]=1;
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p]||p==fa)
			continue;
		getroot(p,x);
		f[x]=Max(f[x],siz[p]);
		siz[x]+=siz[p];
	}
	f[x]=Max(f[x],size-siz[x]);
	if(f[x]<f[rt])
		rt=x;
}
inline bool cmp(register node a,register node b)
{
	return a.d<b.d;
}
inline int search(register int x)
{
    register int ret=0;
    register int l=1,r=num;
    while(l<=r)
	{
        register int mid = l+r>>1;
        if(dis[mid].d<x)
			l=mid+1;
        else
			ret=mid,r=mid-1;
    }
    return ret;
}
inline void dfs(register int x,register int fa,register int wh,register int d)
{
    dis[++num] = (node){d,wh};
    for(register int i=head[x]; i; i=e[i].next)
    {
        register int p=e[i].to;
        if(vis[p]||p==fa)
			continue;
        dfs(p,x,wh,d+1);
    }
}
inline void work(register int x)
{
	num=0;
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p])
			continue;
		dfs(p,x,p,1);
	}
	dis[++num]=(node){0,0};
	sort(dis+1,dis+num+1,cmp);
	register int l=1;
	while(l<num&&dis[l].d+dis[num].d<k)
		l++;
	while(l<num)
	{
		if(k-dis[l].d<dis[l].d)
			break;
		register int pot=search(k-dis[l].d);
        while(l<=num&&dis[pot].d+dis[l].d==k&&dis[pot].w==dis[l].w)
			++pot;
        if(dis[pot].d+dis[l].d==k)
			ans+=pot;
        l++;
	}
}
inline void solve(register int x)
{
	vis[x]=1;
	work(x);
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p])
			continue;
		rt=0;
		siz[rt]=size=siz[p];
		getroot(p,0);
		solve(rt);
	}
}
int main()
{
	n=read(),k=read();
	for(register int i=1;i<n;++i)
	{
		int x=read(),y=read();
		add(x,y);
		add(y,x);
	}
	f[rt]=size=n;
	getroot(1,0);
	solve(rt);
	printf("%d\n",ans);
	return 0;
}


#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define N 50005
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0' || ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    while ('0'<=ch && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*f;
}
inline int Max(register int a,register int b)
{
	if(a>b)
		return a;
	return b;
}
int n,k;
long long ans;
struct edge{
	int to,next;
}e[N<<1];
int head[N],tot=0;
int num,rt,size,siz[N],f[N];
bool vis[N];
struct node{
	int d,w;
}dis[N];
inline void add(register int x,register int y)
{
	e[++tot].to=y;
	e[tot].next=head[x];
	head[x]=tot;
}
inline void getroot(register int x,register int fa)
{
	f[x]=0;
	siz[x]=1;
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p]||p==fa)
			continue;
		getroot(p,x);
		f[x]=Max(f[x],siz[p]);
		siz[x]+=siz[p];
	}
	f[x]=Max(f[x],size-siz[x]);
	if(f[x]<f[rt])
		rt=x;
}
inline int search(register int x)
{
    register int ret=0;
    register int l=1,r=num;
    while(l<=r)
	{
        register int mid = l+r>>1;
        if(dis[mid].d<x)
			l=mid+1;
        else
			ret=mid,r=mid-1;
    }
    return ret;
}
inline bool cmp(register node a,register node b)
{
	return a.d<b.d;
}
inline void dfs(register int x,register int fa,register int wh,register int d)
{
    dis[++num] = (node){d,wh};
    for(register int i=head[x]; i; i=e[i].next)
    {
        register int p=e[i].to;
        if(vis[p]||p==fa)
			continue;
        dfs(p,x,wh,d+1);
    }
}
inline void work(register int x)
{
	num=0;
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p])
			continue;
		dfs(p,x,p,1);
	}
	dis[++num]=(node){0,0};
	sort(dis+1,dis+num+1,cmp);
	register int l=1;
	while(l<num&&dis[l].d+dis[num].d<k)
		l++;
	while(l<num)
	{
		if(k-dis[l].d<dis[l].d)
			break;
		register int pot=search(k-dis[l].d);
        while(l<=num&&dis[pot].d+dis[l].d==k&&dis[pot].w==dis[l].w)
			pot++;
        if(dis[pot].d+dis[l].d==k)
			++ans;
        l++;
	}
}
inline void solve(register int x)
{
	vis[x]=1;
	work(x);
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p])
			continue;
		rt=0;
		siz[rt]=size=siz[p];
		getroot(p,0);
		solve(rt);
	}
}
int main()
{
	n=read(),k=read();
	for(register int i=1;i<n;++i)
	{
		int x=read(),y=read();
		add(x,y);
		add(y,x);
	}
	f[rt]=size=n;
	getroot(1,0);
	solve(rt);
	printf("%d\n",ans);
	return 0;
}


#pragma GCC optimize("O3")
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
using namespace std;
const int MaxN = 100005;
struct Node
{
	int key, cnt, size, ls, rs, fa;
}	tree[MaxN*20];
struct Node2
{
	int tail, ls, next;
}	tr[MaxN];
int n, m, k, size[MaxN], Q[10000000], ans, e[MaxN*2], next[MaxN*2], lis[MaxN], cost[MaxN], dist[MaxN], tot;
int root[MaxN], l, fa[MaxN];
bool mark[MaxN];
inline void Renew(int x)
{
	tree[x].size = tree[tree[x].ls].size + tree[tree[x].rs].size + tree[x].cnt;
}
inline void Zig(int x)
{
	int y = tree[x].fa, z = tree[y].fa;
	tree[y].ls = tree[x].rs, tree[tree[x].rs].fa = y;
	tree[x].fa = z;
	if (tree[z].ls == y) tree[z].ls = x;
	else tree[z].rs = x;
	tree[y].fa = x, tree[x].rs = y;
	Renew(y);
}
inline void Zag(int x)
{
	int y = tree[x].fa, z = tree[y].fa;
	tree[y].rs = tree[x].ls, tree[tree[x].ls].fa = y;
	tree[x].fa = z;
	if (tree[z].ls == y) tree[z].ls = x;
	else tree[z].rs = x;
	tree[y].fa = x, tree[x].ls = y;
	Renew(y);
}
inline void Splay(int x, int &root)
{
	for (; tree[x].fa != 0; )
	{
		int y = tree[x].fa, z = tree[y].fa;
		if (z == 0){
			if (tree[y].ls == x) Zig(x);
			else Zag(x);
		}
		else{
			if (tree[z].ls == y){
				if (tree[y].ls == x) Zig(y), Zig(x);
				else Zag(x), Zig(x);
			}
			else{
				if (tree[y].rs == x) Zag(y), Zag(x);
				else Zig(x), Zag(x);
			}
		}
	}
	root = x;
	Renew(x);
}
inline void Find(int &root, int x)
{
	int p = root;
	for (; ; ){
		if (x == tree[p].key) break;
		if (x>tree[p].key)
			if (tree[p].rs != 0) p = tree[p].rs;
			else break;
		else
			if (tree[p].ls != 0) p = tree[p].ls;
			else break;
	}
	Splay(p, root);
	if (tree[p].key == x)
		ans += tree[p].cnt;
}
inline void Insert(int x, int &root)
{
	int p = root;
	for (; ; ){
		if (x == tree[p].key) break;
		if (x>tree[p].key)
			if (tree[p].rs != 0) p = tree[p].rs;
			else {tree[p].rs = tot + 1; break; }
		else
			if (tree[p].ls != 0) p = tree[p].ls;
			else {tree[p].ls = tot + 1; break; }
	}
	if (tree[p].key == x) tree[p].cnt ++ , Splay(p, root);
	else{
		tot ++ ;
		tree[tot].cnt = 1;
		tree[tot].key = x;
		tree[tot].fa = p;
		Splay(tot, root);
	}
}
void Dfs(int u)
{
	mark[u] = true;
	for (int v = tr[u].ls; v != 0; v = tr[v].next)
		Dfs(v);
	int max = 0, maxv = -1;
	for (int v = tr[u].ls; v != 0; v = tr[v].next)
	if (size[v]>max) max = size[v], maxv = v;
	if (maxv != -1){
		for (int v = tr[u].ls; v != 0; v = tr[v].next)
		if (v != maxv){
			int head = 0, tail = 1; Q[1] = v;
			while (head<tail)
			{
				head ++ ;
				for (int i = tr[Q[head]].ls; i != 0; i = tr[i].next)
					Q[ ++ tail] = i;
			}
			for (int i = 1; i <= tail; i ++ )
				Find(root[maxv], k + 2*dist[u]-dist[Q[i]]);
			for (int i = 1; i <= tail; i ++ )
				Insert(dist[Q[i]], root[maxv]);
		}
		Find(root[maxv], k + 2*dist[u]-dist[u]);
		Insert(dist[u], root[maxv]);
		root[u] = root[maxv];
		}
	else
	{
		root[u] =  ++ tot;
		tree[tot].key = dist[u];
		tree[tot].cnt = 1;
		tree[tot].size = 1;
	}
}
int main()
{
	scanf("%d%d", &n, &k);
	int x, y, z; char c;
	for (int i = 1; i<n; i ++ )
	{
		scanf("%d%d", &x, &y);
		e[ ++ l] = y, next[l] = lis[x], lis[x] = l; cost[l] = 1;
		e[ ++ l] = x; next[l] = lis[y], lis[y] = l; cost[l] = 1;
	}
	int u, v, head = 0, tail = 1; Q[1] = 1; mark[1] = true; dist[1] = 0;
	while (head<tail)
	{
		u = Q[ ++ head];
		for (int i = lis[u]; i != 0; i = next[i])
		{
			v = e[i];
			if (!mark[v])
			{
				if (!tr[u].ls) tr[u].ls = v;
				else tr[tr[u].tail].next = v;
				dist[v] = dist[u] + cost[i];
				tr[u].tail = v;
				Q[ ++ tail] = v;
				fa[v] = u;
				mark[v] = true;
			}
		}
	}
	for (int i = tail; i>0; i--)
		size[Q[i]] ++ , size[fa[Q[i]]] += size[Q[i]];
	ans = 0; tot = 0;
	Dfs(1);
	printf("%d\n", ans);
	return 0;
}


#pragma GCC optimize("O3")
#include<bits/stdc++.h>
#define N 50005
using namespace std;
int n,K,rt,sz[N];
int cnt[505],tmp[505];
vector<int> lin[N];
int vis[N],f[N];
int size;
long long ans;
inline int getrt(int x,int fa)
{
    sz[x]=1;
    f[x]=0;
    for(register int i=0;i<lin[x].size();++i)
    {
        int u=lin[x][i];
        if(u==fa||vis[u])
			continue;
        getrt(u,x);
        sz[x]+=sz[u];
        f[x]=max(f[x],sz[u]);
    }
    f[x]=max(f[x],size-f[x]);
    if(f[rt]>f[x])
		rt=x;

}
inline void getdis(int x,int fa,int dis)
{
    sz[x]=1;
    if(dis<=K)
    {
        ans+=cnt[K-dis];
        ++tmp[dis];
    }
    for(register int i=0;i<lin[x].size();++i)
    {
        int u=lin[x][i];
        if(vis[u]||u==fa)
			continue;
        getdis(u,x,dis+1);
        sz[x]+=sz[u];
    }
}
inline void cal(int x)
{
    memset(cnt,0,sizeof(cnt));
    int ret=0;
    cnt[0]=1;
    for(register int i=0;i<lin[x].size();++i)
    {
        int u=lin[x][i];
        if(vis[u])
			continue;
        memset(tmp,0,sizeof(tmp));
        getdis(u,u,1);
        for(int j=1;j<=K;j++)
        	cnt[j]+=tmp[j];
    }
}
inline void solve(int x)
{
    vis[x]=1;
    cal(x);
    for(register int i=0;i<lin[x].size();++i)
    {
        int u=lin[x][i];
        if(vis[u])
			continue;
        f[0]=size=sz[u];
        getrt(u,rt=0);
        solve(rt);
    }
}
int main()
{
    int aa,bb;
    scanf("%d%d",&n,&K);
    for(register int i=1;i<n;++i)
    {
        scanf("%d%d",&aa,&bb);
        lin[aa].push_back(bb);
        lin[bb].push_back(aa);
    }
    f[0]=size=n;
    getrt(1,rt=0);
    solve(rt);
    cout<<ans<<endl;
    return 0;
}


#pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define N 50005
using namespace std;
inline int read(){
    int x=0,f=1;char ch=getchar();
    while (ch<'0' || ch>'9'){if (ch=='-')f=-1;ch=getchar();}
    while ('0'<=ch && ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
    return x*f;
}
inline int Max(register int a,register int b)
{
	if(a>b)
		return a;
	return b;
}
int n,k;
long long ans;
struct edge{
	int to,next;
}e[N<<1];
int head[N],tot=0;
int num,rt,size,siz[N],f[N];
bool vis[N];
struct node{
	int d,w;
}dis[N];
inline void add(register int x,register int y)
{
	e[++tot].to=y;
	e[tot].next=head[x];
	head[x]=tot;
}
inline void getroot(register int x,register int fa)
{
	f[x]=0;
	siz[x]=1;
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p]||p==fa)
			continue;
		getroot(p,x);
		f[x]=Max(f[x],siz[p]);
		siz[x]+=siz[p];
	}
	f[x]=Max(f[x],size-siz[x]);
	if(f[x]<f[rt])
		rt=x;
}
inline bool cmp(register node a,register node b)
{
	return a.d<b.d;
}
inline int search(register int x)
{
    register int ret=0;
    register int l=1,r=num;
    while(l<=r)
	{
        register int mid = l+r>>1;
        if(dis[mid].d<x)
			l=mid+1;
        else
			ret=mid,r=mid-1;
    }
    return ret;
}
inline void dfs(register int x,register int fa,register int wh,register int d)
{
    dis[++num] = (node){d,wh};
    for(register int i=head[x]; i; i=e[i].next)
    {
        register int p=e[i].to;
        if(vis[p]||p==fa)
			continue;
        dfs(p,x,wh,d+1);
    }
}
inline void work(register int x)
{
	num=0;
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p])
			continue;
		dfs(p,x,p,1);
	}
	dis[++num]=(node){0,0};
	sort(dis+1,dis+num+1,cmp);
	register int l=1;
	while(l<num&&dis[l].d+dis[num].d<k)
		l++;
	while(l<num)
	{
		if(k-dis[l].d<dis[l].d)
			break;
		register int pot=search(k-dis[l].d);
        while(l<=num&&dis[pot].d+dis[l].d==k&&dis[pot].w==dis[l].w)
			++pot;
        if(dis[pot].d+dis[l].d==k)
			++ans;
        l++;
	}
}
inline void solve(register int x)
{
	vis[x]=1;
	work(x);
	for(register int i=head[x];i;i=e[i].next)
	{
		register int p=e[i].to;
		if(vis[p])
			continue;
		rt=0;
		siz[rt]=size=siz[p];
		getroot(p,0);
		solve(rt);
	}
}
int main()
{
	n=read(),k=read();
	if(k==1)
	{
		printf("%d\n",n-1);
		return 0;
	}
	for(register int i=1;i<n;++i)
	{
		int x=read(),y=read();
		add(x,y);
		add(y,x);
	}
	f[rt]=size=n;
	getroot(1,0);
	solve(rt);
	printf("%d\n",ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int oo = 0x7fffffff;

int n, k, x, y, par[50005];
long long f[50005][505];
vector<int> a[50005];
long long ans = 0;

void dfs(int u, int pa) {
    f[u][0] = 1;
    par[u] = pa;
    for (int i = 0; i < a[u].size(); ++i) {
        if (a[u][i] == pa)
            continue;
        dfs(a[u][i], u);
        for (int j = 0; j < k; ++j)
            f[u][j + 1] += f[a[u][i]][j];
    }
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif // ONLINE_JUDGE
    ios_base::sync_with_stdio(false);
    cin >> n >> k;
    for (int i = 0; i + 1 < n; ++i) {
        cin >> x >> y;
        a[x].push_back(y);
        a[y].push_back(x);
    }

    dfs(1, 0);
    for (int u = 1; u <= n; ++u) {
        ans += f[u][k] * 1LL * 2;
        for (int i = 0; i < a[u].size(); ++i) {
            int v = a[u][i];
            if (v == par[u])
                continue;
            for (int d = 1; d < k; ++d) {
                ans += f[v][d - 1] * 1LL * (f[u][k - d] - f[v][k - d - 1]);
//                cout << u << ' ' << v << ' ' << f[v][d - 1] * 1LL * (f[u][k - d] - f[v][k - d - 1]) << endl;
            }
        }
    }
    cout << ans / 2;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int oo = 0x7fffffff;

int n, k, x, y, par[505];
long long f[50005][505];
vector<int> a[50005];
long long ans = 0;

void dfs(int u, int pa) {
    f[u][0] = 1;
    par[u] = pa;
    for (int i = 0; i < a[u].size(); ++i) {
        if (a[u][i] == pa)
            continue;
        dfs(a[u][i], u);
        for (int j = 0; j < k; ++j)
            f[u][j + 1] += f[a[u][i]][j];
    }
}

int main() {
    #ifndef ONLINE_JUDGE
        freopen("input.txt", "r", stdin);
        freopen("output.txt", "w", stdout);
    #endif // ONLINE_JUDGE
    ios_base::sync_with_stdio(false);
    cin >> n >> k;
    for (int i = 0; i + 1 < n; ++i) {
        cin >> x >> y;
        a[x].push_back(y);
        a[y].push_back(x);
    }

    dfs(1, 0);
    for (int u = 1; u <= n; ++u) {
        ans += f[u][k] * 2;
        for (int i = 0; i < a[u].size(); ++i) {
            int v = a[u][i];
            if (v == par[u])
                continue;
            for (int d = 1; d < k; ++d) {
                ans += f[v][d - 1] * 1LL * (f[u][k - d] - f[v][k - d - 1]);
//                cout << u << ' ' << v << ' ' << f[v][d - 1] * 1LL * (f[u][k - d] - f[v][k - d - 1]) << endl;
            }
        }
    }
    cout << ans / 2;
    return 0;
}