Problem:
Score : 500 points

Problem Statement

Count the pairs of length-N sequences consisting of integers between 1 and M (inclusive), A_1, A_2, \cdots, A_{N} and B_1, B_2, \cdots, B_{N}, that satisfy all of the following conditions:

A_i \neq B_i, for every i such that 1\leq i\leq N.

A_i \neq A_j and B_i \neq B_j, for every (i, j) such that 1\leq i < j\leq N.

Since the count can be enormous, print it modulo (10^9+7).

Constraints

1\leq N \leq M \leq 5\times10^5

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M

Output

Print the count modulo (10^9+7).

Sample Input 1

2 2

Sample Output 1

2

A_1=1,A_2=2,B_1=2,B_2=1 and A_1=2,A_2=1,B_1=1,B_2=2 satisfy the conditions.

Sample Input 2

2 3

Sample Output 2

18

Sample Input 3

141421 356237

Sample Output 3

881613484

Solution in Kotlin (1.3.71) (judge verdict: Accepted)

fun main() {
    val (n, m) = nextIntList()
    val mod = 1_000_000_007L
    val factList = sizedArray(m + 1, 0L)
    val modInvList = sizedArray(m + 1, 0L)

    var a = 1L
    repeat(m + 1) {
        factList[it] = a
        modInvList[it] = modinv(a, mod)
        a = a.times(it.plus(1)).rem(mod)
    }
    var res = 0L
    repeat(n + 1) { k ->
        val c = factList[n].times(modInvList[k]).rem(mod).times(modInvList[n - k]).rem(mod)
        val p1 = factList[m].times(modInvList[m - k]).rem(mod)
        val p2 = factList[m - k].times(modInvList[m - n]).rem(mod)
        val t = c.times(p1).rem(mod).times(p2).rem(mod).times(p2).rem(mod)
        if (k % 2 == 0) {
            res = res.plus(t).rem(mod)
        } else {
            res -= t
            if (res < 0) {
                res += mod
            }
        }
    }
    println(res)
}

// # Utils
// ## Input
fun next() = readLine()!!
fun nextInt() = next().toInt()
fun nextLong() = next().toLong()
fun nextDouble() = next().toDouble()
fun nextList() = next().split(" ")
fun nextIntList() = next().split(" ").map(String::toInt)
fun nextLongList() = next().split(" ").map(String::toLong)
fun nextDoubleList() = next().split(" ").map(String::toDouble)

// ## Array
inline fun <reified T> sizedArray(size: Int, default: T) = Array(size) { default }

// ## mod^-1
//    [NOTE] CANNOT use this for 0, mod, 2mod, 3mod ...(return wrong value)
fun modinv(num: Long, mod: Long): Long {
    var a = num
    var b = mod
    var u = 1L
    var v = 0L
    while (b > 0) {
        val t = a.div(b)
        a -= t * b
        a = b.also { b = a } // swap a and b
        u -= t * v
        u = v.also { v = u } // swap u and v
    }
    u %= mod
    if (u < 0) u += mod
    return u
}