#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <array>
#include <vector>
#include <queue>
#include <set>
#include <cmath> // 変数名にy1が使えなくなるかも…。
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <limits>
#include <string>

typedef __int128_t int128_t;
std::istream &operator>>(std::istream& input, int128_t& value) { // int128_tの入力。入力が64bitに収まる前提。
    long long tmp; input >> tmp; value = tmp;
    return input;
}
std::ostream &operator<<(std::ostream& output, const int128_t value) { // int128_tの出力。出力が64bitに収まる前提。
    output << (long long)value;
    return output;
}

int128_t cal_mod(const int128_t n, const int128_t mod) {
    // n % modを計算する。ただしmod <= 0 ならば何もしない。nが負の場合、正にして補正する。
    if (mod <= 0) {
        return n;
    } else if (0 <= n) {
        return n % mod;
    } else {
        int128_t tmp = (-n) / mod + 1;
        return (n + tmp * mod) % mod;
    }
}

int128_t pow_mod(int128_t x, int128_t n, const int128_t mod) {
    // 累乗の計算。mod <= 0ならば余りの計算は行わない。
    int128_t ret = 1;
    while (n > 0) {
        if (n & 1) { ret = cal_mod(ret * x, mod); }
        x = cal_mod(x * x, mod);
        n = (n >> 1);
    }
    return ret;
}

class Combi_Num {
    // 「組み合わせ数 % 素数」を、前処理を行ったうえでO(1)で求める。modは32bitに収まることが前提。
    public:
    int128_t mod;
    std::vector<int128_t> factorial, factorial_inv, inv;
    Combi_Num() {}
    Combi_Num(const int n, const int128_t mod_in) {
        mod = mod_in;
        factorial.resize(n+1, 0);
        factorial_inv.resize(n+1, 0);
        inv.resize(n+1, 0);
        factorial[0] = 1;
        factorial_inv[0] = 1;
        inv[0] = 1;
        for (int i = 1; i <= n; i++) {
            factorial[i] = (factorial[i-1] * i) % mod;
            inv[i] = pow_mod(i, mod - 2, mod);
            factorial_inv[i] = (factorial_inv[i-1] * inv[i]) % mod;
        }
    }

    int128_t combi(const int n, const int r) {
        return (factorial[n] * ((factorial_inv[r] * factorial_inv[n-r]) % mod)) % mod;
    }

    int128_t perm(const int n, const int r) {
        return (factorial[n] * factorial_inv[n-r]) % mod;
    }

    // n個の要素をr個のグループに分ける場合の数。ただし各グループに最低でもm個の要素を入れる。
    // mとしては主に0か1を想定している。
    // 0個の要素を0個のグループに分ける場合の数は1とし、正の個数の要素を0個のグループに分ける場合の数は0とする。
    int128_t separate(const int n, const int r, const int m) {
        if (n < r * m) { return 0; }
        if (0 < m) { return separate(n - r*m, r, 0); }
        if (n == 0) { return 1; }
        if (r == 0) { return 0; }
        return combi(n + r - 1, r - 1);
    }
};

class Tree {
    public:
    struct Node {
        std::vector<int> edge;
        int rank; // ある頂点を根としたときのランク
        int partial_size; // ある頂点を根として、対象となる頂点を根とする部分木を構成した時のサイズ。
    };
    std::vector<Node> node;
    Tree() {}
    Tree(const int node_num_max) {
        node.resize(node_num_max);
    }
    void add_directed_edge(const int from, const int to) {
        node[from].edge.push_back(to);
    }
    void add_undirected_edge(const int node1, const int node2) {
        add_directed_edge(node1, node2);
        add_directed_edge(node2, node1);
    }
    void set_rank(int n, int rank, int parent) { // 辺が有向でも無向でも使える。呼び出すとき、parentは-1にしておくとよい。
        node[n].rank = rank;
        for (int c : node[n].edge) {
            if (c != parent) {
                set_rank(c, rank + 1, n);
            }
        }
    }
    void set_partial_size(int n, int parent) {
        node[n].partial_size = 1;
        for (int c : node[n].edge) {
            if (c != parent) {
                set_partial_size(c, n);
                node[n].partial_size += node[c].partial_size;
            }
        }
    }
    std::vector<int> get_children(int n) { // rankがセットされた前提で、頂点nの子
        std::vector<int> ret;
        for (int c : node[n].edge) {
            if (node[c].rank > node[n].rank) {
                ret.push_back(c);
            }
        }
        return ret;
    }
    std::vector<int> rank_descending_ids(int l, int r) { // [l, r]の数列を、ランクの高い順にまとめたベクトル。set_rankをした後であることが前提。
        std::vector<int> ret;
        for (int i = l; i <= r; i++) {
            ret.push_back(i);
        }
        std::sort(ret.begin(), ret.end(),
            [&](const int a, const int b) { return node[a].rank > node[b].rank; }
        );
        return ret;
    }
};

const int MAX_N = 1e5 + 10;
const int MOD = 1e9 + 7;
int N, K;
int a[MAX_N], b[MAX_N];

Tree tree = Tree(MAX_N);
Combi_Num combi_num = Combi_Num(MAX_N, MOD);

int main(int argc, char **argv) {
    std::cin >> N >> K;

    for (int i = 1; i <= N-1; i++) {
        std::cin >> a[i] >> b[i];
        tree.add_undirected_edge(a[i], b[i]);
    }

    tree.set_rank(1, 0, -1);
    std::vector<int> vec = tree.rank_descending_ids(1, N);

    int128_t ret = K;
    for (int i = vec.size() - 1; 0 <= i; i--) {
        int edge_size = tree.node[vec[i]].edge.size();
        if (tree.node[vec[i]].rank == 0) {
            if (edge_size == 0) {
                // nothing 
            } else if (K - 1 < edge_size) {
                ret = 0;
            } else {
                ret = ret * combi_num.perm(K-1, edge_size);
            }
        } else {
            if (edge_size == 1) {
                // nothing;
            } else if (K - 2 < edge_size - 1) {
                ret = 0;
            } else {
                ret = ret * combi_num.perm(K-2, edge_size-1);
            }
        }
        ret %= MOD;
    }

    std::cout << ret << std::endl;
    
    return 0;
}

Measured memory_bytes: 14844