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 Java (OpenJDK 11.0.6) (judge verdict: Accepted)

import java.util.Scanner;
import java.util.stream.IntStream;

/**
 * 解説通りに実装したソースコード
 */
public class Main {

	private static final long MOD = 1_000_000_007L;

	public static void main(String[] args) {
		try (Scanner scanner = new Scanner(System.in)) {
			int n = scanner.nextInt(), m = scanner.nextInt();
			// 階乗を保存する配列
			long[] factorial = new long[m + 1];
			factorial[0] = 1;
			IntStream.rangeClosed(1, m).forEach(i -> factorial[i] = factorial[i - 1] * i % MOD);
			// 階乗^-1を保存する配列
			long[] revFactorial = new long[m + 1];
			revFactorial[m] = modPow(factorial[m], MOD - 2);
			IntStream.rangeClosed(1, m).map(i -> m - i)
					.forEach(i -> revFactorial[i] = revFactorial[i + 1] * (i + 1) % MOD);
			long answer = 0L;
			for (int i = 0; i <= n; i++) {
				// (−1)^i × n_C_i
				long result = ((0 == (i & 1)) ? 1 : -1) * factorial[n] % MOD * revFactorial[i] % MOD
						* revFactorial[n - i] % MOD;
				if (result < 0) {
					result += MOD;
				}
				// m_P_i × (m-i_P_n-i)^2
				result = result * factorial[m] % MOD * revFactorial[m - i] % MOD * factorial[m - i] % MOD
						* factorial[m - i] % MOD * revFactorial[m - n] % MOD * revFactorial[m - n] % MOD;
				answer = (answer + result) % MOD;
			}
			System.out.println(answer);
		}
	}

	/**
	 * n^m mod MOD を計算する
	 * 
	 * @param n
	 * @param m
	 * @return n^m mod MOD
	 */
	private static long modPow(long n, long m) {
		long result = 1L;
		while (m > 0) {
			if (1 == (m & 1)) {
				result = result * n % MOD;
			}
			n = n * n % MOD;
			m >>= 1;
		}
		return result;
	}
}