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

trait ModValue:
    std::ops::Add<Output = Self>
    + std::ops::Sub<Output = Self>
    + std::ops::Mul<Output = Self>
    + std::ops::Div<Output = Self>
    + std::ops::Rem<Output = Self>
    + std::ops::AddAssign
    + std::ops::SubAssign
    + std::ops::MulAssign
    + std::ops::DivAssign
    + std::cmp::Ord
    + Clone
    + Copy
    + std::fmt::Debug
    + Sized
{
    fn modulus() -> Self;
    fn zero() -> Self;
    fn one() -> Self;
}

#[derive(Clone, Copy, Debug)]
struct Modint<Value: ModValue>(Value);

impl<Value: ModValue> Modint<Value> {
    #[allow(dead_code)]
    pub fn with_value(x: Value) -> Self {
        Self(Self::normalize(x))
    }

    #[allow(dead_code)]
    pub fn with_value_unchecked(x: Value) -> Self {
        Self(x)
    }

    #[allow(dead_code)]
    pub fn validate(&self) -> &Self {
        assert!(Value::zero() <= self.0 && self.0 < Value::modulus());
        &self
    }

    fn normalize(x: Value) -> Value {
        let x = x % Value::modulus();
        if x < Value::zero() {
            x + Value::modulus()
        } else {
            x
        }
    }

    fn add_unchecked(x: Value, y: Value) -> Value {
        let z = x + y;
        if Value::modulus() <= z {
            z - Value::modulus()
        } else {
            z
        }
    }

    fn sub_unchecked(x: Value, y: Value) -> Value {
        let z = x - y;
        if x < Value::zero() {
            z + Value::modulus()
        } else {
            z
        }
    }

    fn neg_unchecked(x: Value) -> Value {
        if x == Value::zero() {
            Value::zero()
        } else {
            Value::modulus() - x
        }
    }

    fn mul_unchecked(x: Value, y: Value) -> Value {
        x * y % Value::modulus()
    }

    fn div_unchecked(x: Value, y: Value) -> Value {
        Self::mul_unchecked(x, Self::inv_unchecked(y))
    }

    fn inv_unchecked(mut x: Value) -> Value {
        let mut y: Value = Value::modulus();
        let mut u: Value = Value::one();
        let mut v: Value = Value::zero();
        while x != Value::zero() {
            let q = y / x;
            y -= x * q;
            v -= u * q;
            swap(&mut x, &mut y);
            swap(&mut u, &mut v);
        }
        if v < Value::zero() {
            v + Value::modulus()
        } else {
            v
        }
    }
}

macro_rules! impl_bop {
    (
        $(
            $bop_trait: ident::$bop_fn: ident, $bop_assign_trait: ident::$bop_assign_fn: ident, $impl: ident;
        )*
    ) => {
        $(
            impl<Value: ModValue> std::ops::$bop_trait for Modint<Value> {
                type Output = Self;
                fn $bop_fn(self, rhs: Self) -> Self::Output {
                    Modint(Self::$impl(self.0, rhs.0))
                }
            }
            impl<Value: ModValue> std::ops::$bop_assign_trait for Modint<Value> {
                fn $bop_assign_fn(&mut self, rhs: Self) {
                    use std::ops::$bop_trait;
                    *self = Modint::$bop_fn(*self, rhs)
                }
            }
        )*
    };
}

impl_bop! {
    Add::add, AddAssign::add_assign, add_unchecked;
    Sub::sub, SubAssign::sub_assign, sub_unchecked;
    Mul::mul, MulAssign::mul_assign, mul_unchecked;
    Div::div, DivAssign::div_assign, div_unchecked;
}

impl<Value: ModValue> std::ops::Neg for Modint<Value> {
    type Output = Self;
    fn neg(self) -> Self::Output {
        Modint(Self::neg_unchecked(self.0))
    }
}

impl<Value: ModValue> std::iter::Sum<Self> for Modint<Value> {
    fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
        iter.fold(Self::with_value(Value::zero()), std::ops::Add::add)
    }
}

impl<Value: ModValue> std::convert::From<Value> for Modint<Value> {
    fn from(x: Value) -> Self {
        Self::with_value(x)
    }
}

#[allow(unused_macros)]
macro_rules! modint {
    ($x: expr) => {
        Modint::with_value($x)
    };
}

#[allow(unused_macros)]
macro_rules! impl_modvalue {
    ($(const $mod_name: ident: $ty: ty = $mod_value: expr;)*) => {
        $(
            const $mod_name: $ty = $mod_value;
            impl ModValue for $ty {
                fn modulus() -> Self {
                    $mod_name
                }
                fn zero() -> Self {
                    0
                }
                fn one() -> Self {
                    1
                }
            }
        )*
    };
}

impl_modvalue! {
    const MOD: i64 = 1_000_000_007;
}

fn main() {
    input!(n: usize, m: usize);
    let fact = once(modint!(1))
        .chain((1..=m as i64).scan(1.into(), |acc, x| {
            *acc = *acc * x.into();
            Some(*acc)
        }))
        .collect_vec();

    println!(
        "{}",
        (0..=n)
            .map(
                |i| modint!(if i % 2 == 0 { 1 } else { -1 }) * fact[n] * fact[m] * fact[m - i]
                    / (fact[m - n] * fact[m - n] * fact[i] * fact[n - i])
            )
            .sum::<Modint<i64>>()
            .0
    );
}


Measured memory_bytes: 6080