import java.io.BufferedReader
import java.io.InputStreamReader
import java.io.PrintWriter
import java.util.*
import java.lang.Double.parseDouble as parseDoubleJVM
import java.lang.Integer.parseInt as parseIntJVM
import java.lang.Long.parseLong as parseLongJVM

fun main(args: Array<String>) = yorukatsu14e()

fun yorukatsu14e() = IO_yorukatsu14e().exec {
    val (n, k) = readLine().split(' ').map { it.toInt() }
    val edges = Array(n - 1) {
        readLine().split(' ').map { it.toInt() - 1 }.let { Edge(it[0], it[1]) }
    }

    val graph = Array(n) { Vertex(it) }
    edges.forEach {
        val (from, to) = it
        graph[from].neighbor.add(to)
        graph[to].neighbor.add(from)
    }

    val visited = mutableSetOf(0)
    val biCoef = BiCoef(100010)
    var answer = k.toLong()

    fun dfs(currIndex: Int) {
        val neighbor = graph[currIndex].neighbor
        answer *= when (currIndex) {
            0 -> biCoef.nPr(k - 1, neighbor.size)
            else -> biCoef.nPr(k - 2, neighbor.size - 1)
        }
        answer %= MOD
        neighbor.filter { visited.add(it) }.forEach { dfs(it) }
    }

    dfs(0)

    println(answer)
}

private const val MOD = (1e9 + 7).toLong()

private data class Edge(val from: Int, val to: Int)
private data class Vertex(val index: Int, val neighbor: MutableSet<Int> = mutableSetOf())

@Suppress("unused")
private class BiCoef(max: Int) {
    private val fact = LongArray(max + 1)
    private val fInv = LongArray(max + 1)
    private val inv = LongArray(max + 1)

    init {
        fact[0] = 1
        fact[1] = 1
        fInv[0] = 1
        fInv[1] = 1
        inv[1] = 1
        for (i in 2..max) {
            fact[i] = fact[i - 1] * i % MOD
            inv[i] = MOD - inv[(MOD % i).toInt()] * (MOD / i) % MOD
            fInv[i] = fInv[i - 1] * inv[i] % MOD
        }
    }

    fun fact(n: Int): Long = if (n < 0) 0 else fact[n]
    fun inv(n: Int): Long = if (n < 0) 0 else inv[n]
    fun fInv(n: Int): Long = if (n < 0) 0 else fInv[n]
    fun comb(n: Int, k: Int): Long = nCr(n, k)
    fun nCr(n: Int, k: Int): Long = if (n < k || n < 0 || k < 0) 0 else fact[n] * (fInv[k] * fInv[n - k] % MOD) % MOD
    fun perm(n: Int, k: Int): Long = nPr(n, k)
    fun nPr(n: Int, k: Int): Long = if (n < k || n < 0 || k < 0) 0 else fact[n] * fInv[n - k] % MOD % MOD
}

@Suppress("unused", "ClassName", "SpellCheckingInspection")
class IO_yorukatsu14e {
    val br = BufferedReader(InputStreamReader(System.`in`))
    var st = StringTokenizer("")
    val pw = PrintWriter(System.out)

    fun readString() = run { while (!st.hasMoreTokens()) st = StringTokenizer(br.readLine()) }
        .run { st.nextToken()!! }

    fun readInt() = parseIntJVM(readString())
    fun readLong() = parseLongJVM(readString())
    fun readDouble() = parseDoubleJVM(readString())
//    fun readStringList(size: Int) = readList(size) { readString() }
//    fun readIntList(size: Int) = readList(size) { readInt() }
//    fun readLongList(size: Int) = readList(size) { readLong() }
//    fun readDoubleList(size: Int) = readList(size) { readDouble() }
    fun readIntArray(size: Int) = IntArray(size) { readInt() }
    fun readLongArray(size: Int) = LongArray(size) { readLong() }
    fun readDoubleArray(size: Int) = DoubleArray(size) { readDouble() }
    inline fun <reified T> readArray(size: Int, init: () -> T) = Array(size) { init() }
//    inline fun <T> readList(size: Int, init: () -> T) = List(size) { init() }
    fun readLine() = br.readLine()!!
    fun println() = pw.println()
    fun print(o: Any?) = pw.print(o)
    fun println(o: Any?) = pw.println(o)
    inline fun exec(code: IO_yorukatsu14e.() -> Unit) = run { code() }.run { pw.flush() }
}


Measured memory_bytes: 118040