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 Rust (1.42.0) (judge verdict: Accepted)

use itertools::Itertools;
use proconio::input;
use std::{iter::once, mem::swap};

const MOD: i64 = 1_000_000_007;

fn main() {
    let mul = |x: i64, y: i64| x * y % MOD;
    let inv = |mut x: i64| {
        let mut y: i64 = MOD;
        let mut u: i64 = 1;
        let mut v: i64 = 0;
        while x != 0 {
            let q = y / x;
            y -= x * q;
            v -= u * q;
            swap(&mut x, &mut y);
            swap(&mut u, &mut v);
        }
        if 0 <= v {
            v
        } else {
            v + MOD
        }
    };
    let div = |x: i64, y: i64| mul(x, inv(y));

    input!(n: usize, m: usize);
    let fact = once(1)
        .chain((1..=m as i64).scan(1, |acc, x| {
            *acc = mul(*acc, x);
            Some(*acc)
        }))
        .collect_vec();
    let binom = |x: usize, y: usize| div(fact[x], mul(fact[y], fact[x - y]));

    println!(
        "{}",
        (0..=n)
            .map(|i| mul(
                if i % 2 == 0 { 1 } else { MOD - 1 },
                mul(
                    binom(n, i),
                    mul(
                        fact[m],
                        mul(fact[m - i], mul(inv(fact[m - n]), inv(fact[m - n])))
                    )
                )
            ))
            .fold(0, |x, y| (x + y) % MOD)
    );
}