import std.stdio, std.conv, std.string, std.range, std.algorithm, std.array,
  std.functional, std.container, std.typecons;

import std.stdio, std.conv, std.string, std.range, std.algorithm, std.array,
  std.functional, std.container, std.typecons;

enum MOD = 1000000007;

ulong _f(ulong n) {
  if(n == 0) return 1;
  return (n * f(n-1)) % MOD;
}

alias f = memoize!_f;

// a^{-1}
ulong _r(ulong a) {
  ulong r = 1, b = a, k = MOD - 2;
  while(k > 0) {
    if(k & 1) r = (r * b) % MOD;
    b = (b * b) % MOD;
    k >>= 1;
  }
  return r;
}
alias r = memoize!_r;

ulong p(ulong n, ulong k) {
  return (f(n) * r(f(n-k))) % MOD;
}

void main() {
  auto input = readln.split.to!(int[]);
  int N = input[0], K = input[1];

  int[][] tree = new int[][N];
  foreach(i; 0..(N-1)) {
    input = readln.split.to!(int[]);
    int a = input[0], b = input[1];
    tree[a-1] ~= b-1;
    tree[b-1] ~= a-1;
  }

  bool[] seen = new bool[N];
  ulong dfs(ulong n, ulong k) {
    seen[n] = true;
    int[] children = tree[n].filter!(c => !seen[c]).array;
    ulong ck = K - tree[n].length;
    ulong ptns = 1;
    foreach(c; children) {
      ptns = (ptns * dfs(c, ck)) % MOD; 
    }
    ulong one = (ptns * p(children.length + (ck - 1), children.length)) % MOD;
    return one;
  }

  writeln((dfs(0, K) * K) % MOD);
}
