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.*;

public class Main {

	// global
	static int mod = 1_000_000_007;
	static long fact[];
	static long inverse[];

	static long pow(long a,int n) {
	    long res=1;
	    while (n>0) {
	        if ((n-n/2*2)==1) {
	            res=res*a%mod;
	        }
	        a=a*a%mod;
	        n>>=1;
	    }
	    return res;
	}

	static long modinv(long n) {
	    return pow(n, mod-2);
	}

	static long comb(int n,int k){
	    if(n<0 || k<0 || n<k)return 0;
	    return fact[n]*(inverse[k]*inverse[n-k]%mod) %mod;
	}

	static long perm(int n, int k) {
	    if(n<0 || k<0 || n<k)return 0;
	    return fact[n]*inverse[n-k]%mod;
	}

	public static void main(String[] args) {// main method
		fact=new long[600000];
		fact[0]=1;
		inverse=new long[600000];
		inverse[0]=1;
		for(int i=1;i<600000;i++){
		    fact[i]=(fact[i-1]*(long)i)%mod;
		    inverse[i]=modinv(fact[i]);
		}
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int M = sc.nextInt();
		long ans = 0L;
		for (int i=0;i<=N;i++) {
			ans = (ans + comb(N, i)*pow(-1, i)%mod*perm(M, i)%mod*perm(M-i, N-i)%mod*perm(M-i, N-i)%mod)%mod;
			ans = (ans+mod)%mod;
		}
		System.out.println(ans);
	}
}