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-----
2 2

-----Sample Output-----
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.

Difficulty: interview

Starter code:

Solutions:
class Factorial:
    def __init__(self, max_fact, mod):
        #mod should be prime number
        #using homogeneous_product(n,r), max_fact ≧ max(n+r-1)
        f = [1] * (max_fact + 1)
        for idx in range(2, max_fact + 1):
            f[idx] = f[idx - 1] * idx
            f[idx] %= mod
        fi = [pow(f[-1], mod - 2, mod)]
        for idx in range(max_fact, 0, -1):
            fi += [fi[-1] * idx % mod]
        fi = fi[::-1]
        self.mod = mod
        self.f = f
        self.fi = fi

    def factorial(self, n):
        return self.f[n]

    def factorial_inverse(self, n):
        return self.fi[n]

    def combination(self, n, r):
        f = self.f
        fi = self.fi
        return f[n] * fi[r] * fi[n - r] % self.mod

    def permutation(self, n, r):
        return self.f[n] * self.fi[n - r] % self.mod

    def homogeneous_product(self, n, r):
        f = self.f
        fi = self.fi
        return f[n + r - 1] * fi[r] * fi[n - 1] % self.mod


max_fact = 5*10**5
mod = 10**9 + 7
fact_instance = Factorial(max_fact, mod)
comb = fact_instance.combination
perm = fact_instance.permutation

N, M = [int(_) for _ in input().split()]
ans = 0
for p in range(N + 1):
    ans += (-1)**p * comb(N, p) * perm(M - p, N - p)
    ans %= mod
ans *= perm(M, N)
ans %= mod
print(ans)


class Factorial:
    def __init__(self, max_fact, mod):
        #mod should be prime number
        #using homogeneous_product(n,r), max_fact ≧ max(n+r-1)
        f = [1] * 2
        for idx in range(2, max_fact + 1):
            f += [f[idx - 1] * idx % mod]
        fi = [pow(f[-1], mod - 2, mod)]
        for idx in range(max_fact, 0, -1):
            fi += [fi[-1] * idx % mod]
        fi = fi[::-1]
        self.mod = mod
        self.f = f
        self.fi = fi

    def factorial(self, n):
        return self.f[n]

    def factorial_inverse(self, n):
        return self.fi[n]

    def combination(self, n, r):
        f = self.f
        fi = self.fi
        return f[n] * fi[r] * fi[n - r] % self.mod

    def permutation(self, n, r):
        return self.f[n] * self.fi[n - r] % self.mod

    def homogeneous_product(self, n, r):
        f = self.f
        fi = self.fi
        return f[n + r - 1] * fi[r] * fi[n - 1] % self.mod


max_fact = 5 * 10**5
mod = 10**9 + 7
fact_instance = Factorial(max_fact, mod)
comb = fact_instance.combination
perm = fact_instance.permutation

N, M = [int(_) for _ in input().split()]
ans = 0
for p in range(N + 1):
    ans += (-1)**p * comb(N, p) * perm(M - p, N - p)
    ans %= mod
ans *= perm(M, N)
ans %= mod
print(ans)


import sys
import math

sys.setrecursionlimit(10 ** 8)

input = sys.stdin.readline


def main():
    N, M = [int(x) for x in input().split()]

    MOD = 10 ** 9 + 7

    fact = [1, 1]
    factinv = [1, 1]
    inv = [0, 1]

    def cmb(n, k, p):
        if (k < 0) or (n < k):
            return 0
        r = min(k, n - k)
        return fact[n] * factinv[k] * factinv[n - k] % p

    for i in range(2, 10 ** 6 + 1):
        fact.append((fact[-1] * i) % MOD)
        inv.append((-inv[MOD % i] * (MOD // i)) % MOD)
        factinv.append((factinv[-1] * inv[-1]) % MOD)

    X = fact[M] * factinv[M - N]

    ans = 0
    for i in range(N + 1):
        c = fact[M - i] * factinv[(M - i) - (N - i)]
        if i % 2 == 0:
            ans += X * c * cmb(N, i, MOD)
        else:
            ans -= X * c * cmb(N, i, MOD)

        ans %= MOD

    print((ans % MOD))


def __starting_point():
    main()

__starting_point()

import sys
if sys.argv[-1] == 'ONLINE_JUDGE':
    import os
    import re
    with open(__file__) as f:
        source = f.read().split('###''nbacl')
    for s in source[1:]:
        s = re.sub("'''.*", '', s)
        sp = s.split(maxsplit=1)
        if os.path.dirname(sp[0]):
            os.makedirs(os.path.dirname(sp[0]), exist_ok=True)
        with open(sp[0], 'w') as f:
            f.write(sp[1])
    from nbmodule import cc
    cc.compile()
from nbmodule import solve

N, M = [int(x) for x in input().split()]
ans = solve(N, M)
print(ans)
'''
###nbacl nbmodule.py
import numpy as np
from numpy import int64
from numba import njit
from numba.types import i8
from numba.pycc import CC

cc = CC('nbmodule')
MOD = 1000000007


@njit
def inv_mod(x, mod):
    old_t, t = 0, 1
    old_r, r = mod, x

    while r != 0:
        quotient = old_r // r

        old_r, r = r, old_r - quotient * r
        old_t, t = t, old_t - quotient * t

    return old_t % mod


@njit
def calc_fac(fac):
    fac[0] = 1
    for i in range(1, fac.shape[0]):
        fac[i] = fac[i - 1] * i % MOD


@njit
def calc_inv_fac(inv_fac):
    inv_fac[0] = 1
    for i in range(1, inv_fac.shape[0]):
        inv_fac[i] = inv_fac[i - 1] * inv_mod(i, MOD) % MOD


@njit((i8, i8), cache=True)
@cc.export('solve', (i8, i8))
def solve(N, M):
    fac = np.empty(M + 1, dtype=int64)
    inv_fac = np.empty(M + 1, dtype=int64)

    def p(m, n):
        return fac[m] * inv_fac[m - n] % MOD
    def c(m, n):
        return fac[m] * inv_fac[n] % MOD * inv_fac[m - n] % MOD

    calc_fac(fac)
    calc_inv_fac(inv_fac)

    ret = 0
    for r in range(N + 1):
        if r & 1:
            ret = (ret - c(N, r) * p(M - r, N - r)) % MOD
        else:
            ret = (ret + c(N, r) * p(M - r, N - r)) % MOD
    return ret * p(M, N) % MOD


def __starting_point():
    cc.compile()

'''

__starting_point()

N, M = map(int, input().split())
mod = 10 ** 9 + 7

def calc(n):
    f = 1
    factorials = [1]
    for m in range(1, n + 1):
        f *= m
        f %= mod
        factorials.append(f)
    inv = pow(f, mod - 2, mod)
    invs = [1] * (n + 1)
    invs[n] = inv
    for m in range(n, 1, -1):
        inv *= m
        inv %= mod
        invs[m - 1] = inv
    return factorials, invs

factorials, invs = calc(M)
mPn = (factorials[M] * invs[M - N]) % mod
ans = (mPn * mPn) % mod
for k in range(1, N + 1):
    v = pow(-1, k - 1) * factorials[N] * factorials[M - k] * invs[N - k] * invs[k] * invs[M - N] % mod
    ans -= v * mPn
print(ans % mod)

def prepare(n):
    nonlocal MOD
    modFacts = [0] * (n + 1)
    modFacts[0] = 1
    for i in range(n):
        modFacts[i + 1] = (modFacts[i] * (i + 1)) % MOD

    invs = [1] * (n + 1)
    invs[n] = pow(modFacts[n], MOD - 2, MOD)
    for i in range(n, 1, -1):
        invs[i - 1] = (invs[i] * i) % MOD

    return modFacts, invs
        

N, M = map(int, input().split())

MOD = 10 ** 9 + 7
modFacts, invs = prepare(max(N, M))

ans = 0
for i in range(N + 1):
    Ti = (modFacts[N] * invs[i] * invs[N - i]) % MOD
    Ti *= (modFacts[M] * invs[M - i]) % MOD
    Ti %= MOD
    Ti *= pow(modFacts[M - i] * invs[(M - i) - (N - i)], 2, MOD)
    Ti %= MOD
    ans += pow(-1, i) * Ti
    ans %= MOD

print(ans)

n, m = map(int,input().split())
mod = 10**9 + 7

def cmb(n, r, mod):
	if (r < 0) or (n < r):
		return 0
	r = min(r, n-r)
	return fact[n]*factinv[r]*factinv[n-r]%mod

N = 10**6  # N は必要分だけ用意する
fact = [1, 1]  # fact[n] = (n! mod p)
factinv = [1, 1]  # factinv[n] = ((n!)^(-1) mod p)
inv = [0, 1]  # factinv 計算用

for i in range(2, N+1):
	fact.append((fact[-1]*i)%mod)
	inv.append((-inv[mod%i]*(mod//i))%mod)
	factinv.append((factinv[-1]*inv[-1])%mod)

"""
1つ当たっている→Freeはn-1個→m-1 C n-1
同様に2つ→m-2 C n-2
数は？→ n C 2
包除原理
"""
mode = -1
ans = 0
for i in range(n+1):
	mode = -mode
	ans = (ans + mode * cmb(n, i, mod) * cmb(m-i, n-i, mod) * fact[n-i]) % mod
print(ans * cmb(m, n, mod) * fact[n] % mod)

n,m=map(int,input().split())
mod=10**9+7
fact=[1]*(m+1)
inv=[1]*(m+1)
for i in range(2,m+1):
    fact[i]=i*fact[i-1]%mod
inv[-1]=pow(fact[-1],mod-2,mod)
for i in range(m,1,-1):
    inv[i-1]=inv[i]*i%mod
def comb(x,y):return fact[x]*inv[y]%mod*inv[x-y]%mod if x>=y>=0 else 0
def p(x,y):return fact[x]*inv[x-y]%mod if x>=y>=0 else 0
ans=p(m,n)**2%mod
a=-1
for i in range(1,n+1):
    ans=(ans+a*(p(m,i)*comb(n,i)*p(m-i,n-i)**2%mod))%mod
    a*=-1
print(ans)


class Combination:
    def __init__(self, n_max, mod=10 ** 9 + 7):
        # O(n_max + log(mod))
        self.mod = mod
        f = 1
        self.fac = fac = [f]
        for i in range(1, n_max + 1):
            f = f * i % mod
            fac.append(f)
        f = pow(f, mod - 2, mod)
        self.facinv = facinv = [f]
        for i in range(n_max, 0, -1):
            f = f * i % mod
            facinv.append(f)
        facinv.reverse()

    # "n 要素" は区別できる n 要素
    # "k グループ" はちょうど k グループ

    def __call__(self, n, r):  # self.C と同じ
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n - r] % self.mod

    def nCr(self, n, r):
        if not 0 <= r <= n:
            return 0
        return self.fac[n] * self.facinv[r] % self.mod * self.facinv[n - r] % self.mod

    def nPr(self, n, r):
        if not 0 <= r <= n:
            return 0
        return self.fac[n] * self.facinv[n - r] % self.mod

MOD = 10**9+7
def resolve():
    N, M = list(map(int, input().split()))
    cmb = Combination(5 * 10**5)

    ans = 0
    for p in range(N+1):
        ans += (-1)**p * cmb.nCr(N, p) * cmb.nPr(M-p, N-p)
        ans %= MOD

    ans *= cmb.nPr(M, N)
    ans %= MOD

    print(ans)


def __starting_point():
    resolve()

__starting_point()

n,m=list(map(int,input().split()))
mod=pow(10,9)+7
# n<=m
# コンビネーション、さらに高速。あらかじめO(N)の計算をすることでのちの計算が早くなる
def cmb(n,r,mod):
  if (r<0 or r>n):
    return 0
  r=min(r,n-r)
  return g1[n]*g2[r]*g2[n-r]%mod
g1=[1,1] # g1[i]=i! % mod
g2=[1,1] # g2[i]=(i!)^(-1) % mod
inverse=[0,1]
for i in range(2,m+1):
  g1.append((g1[-1]*i)%mod)
  inverse.append((-inverse[mod%i]*(mod//i))%mod)
  g2.append((g2[-1]*inverse[-1])%mod)

# 数列aの作り方
ans_a=g1[m]*g2[m-n]

# 数列bの作り方
ans_b=0
for i in range(n+1):
  tmp=cmb(n,i,mod)
  tmp*=(g1[m-i]*g2[m-n])%mod
  tmp%=mod
  ans_b+=tmp*(-1)**i
  ans_b%=mod
  #print(i,tmp,ans_b)

print(((ans_a*ans_b)%mod))
#print(ans_a,ans_b)



'''
Let g(x) = 序列內數字唯一，且最多 x 個位置不同。
Let f(x) = 序列內數字唯一，且給定 x 個位置時，使這些位置不同的方法數。

題目所求是 C(N, N) f(N)。

其中 g(x) 代表有至少 N - x 個位置是相同。可以分三個部份填數字，注意順序會影響，所以要乘上全排序：
(1) N - x 個位置（數字必需相同）：C(M, N - x) * (N - x)! = P(M, N - x)
(2) 序列 A 其餘位置（可以隨便填，但不能用到 (1) 的數字）：C(M - (N - x), x) * x! = P(M - (N - x), x)
(3) 序列 B 其餘位置（可以隨便填，但不能用到 (1) 的數字）：C(M - (N - x), x) * x! = P(M - (N - x), x)
g(x) = (1) * (2) * (3)

g(x) 是「選定 0 個位置，使這些位置不同的方法數」、「選定 1 個位置，使這些位置不同的方法數」、…、「選定 N 個位置，使這些位置不同的方法數」，即

g(x) = C(x, 0) f(0) + C(x, 1) f(1) + ... + C(x, x) f(x)
     = sum( C(x, i) * f(i) for i in [0, x] )
根據二項式反演，得到
f(x) = sum( (-1) ** (x - i) * C(x, i) * g(i) for i in [0, x] )
'''

class CombMod:
    def __init__(self, V, p):
        self.fact = [1] * V
        self.finv = [1] * V
        for i in range(1, V):
            self.fact[i] = self.fact[i - 1] * i % p
        self.finv[-1] = pow(self.fact[-1], p - 2, p)
        for i in range(V - 2, 0, -1):
            self.finv[i] = self.finv[i + 1] * (i + 1) % p
        self.p = p
        
    def fact(self, a):
        return self.fact[a]
    
    def finv(self, a):
        return self.finv[a]

    def comb(self, a, b):
        return self.fact[a] * self.finv[b] % self.p * self.finv[a - b] % self.p
        
    def perm(self, a, b):
        return self.fact[a] * self.finv[a - b] % self.p
    
    def hcomb(self, a, b):
        return self.comb(a + b - 1, b)


N, M = list(map(int, input().split()))
mod = 10**9 + 7
tool = CombMod(max(N, M) + 10, mod)

ans = 0
for i in range(0, N + 1):
    p1 = tool.perm(M, N - i)
    p2 = tool.perm(M - (N - i), i)
    g_i = p1 * p2 % mod * p2 % mod
    val = pow(-1, N - i, mod) * tool.comb(N, i) % mod * g_i % mod
    ans = (ans + val) % mod
print(ans)


class Factorial:
    def __init__(self, max_fact, mod):
        #mod should be prime number
        #using homogeneous_product(n,r), max_fact ≧ max(n+r-1)
        f = [1] * (max_fact + 1)
        for idx in range(2, max_fact + 1):
            f[idx] = f[idx - 1] * idx
            f[idx] %= mod
        fi = [pow(f[-1], mod - 2, mod)]
        for idx in range(max_fact, 0, -1):
            fi += [fi[-1] * idx % mod]
        fi = fi[::-1]
        self.mod = mod
        self.f = f
        self.fi = fi

    def factorial(self, n):
        return self.f[n]

    def factorial_inverse(self, n):
        return self.fi[n]

    def combination(self, n, r):
        f = self.f
        fi = self.fi
        return f[n] * fi[r] * fi[n - r] % self.mod

    def permutation(self, n, r):
        return self.f[n] * self.fi[n - r] % self.mod

    def homogeneous_product(self, n, r):
        f = self.f
        fi = self.fi
        return f[n + r - 1] * fi[r] * fi[n - 1] % self.mod


max_fact = 5 * 10**5
mod = 10**9 + 7
fact_instance = Factorial(max_fact, mod)
comb = fact_instance.combination
perm = fact_instance.permutation

N, M = [int(_) for _ in input().split()]
ans = 0
for p in range(N + 1):
    ans += (-1)**p * comb(N, p) * perm(M - p, N - p)
    ans %= mod
ans *= perm(M, N)
ans %= mod
print(ans)


n,m=map(int,input().split())
a,M,d=1,10**9+7,[1]*(n+1)
for i in range(n):
  d[i+1]=((m-n+i)*d[i]+i*d[i-1])%M
  a=a*(m-i)%M
print(a*d[-1]%M)

#atcoder template
def main():
    import sys
    imput = sys.stdin.readline
    if sys.argv[-1] == 'ONLINE_JUDGE':
        import numba
        from numba.pycc import CC
        i8 = numba.int64
        cc = CC('my_module')
 
        def cc_export(f, signature):
            cc.export(f.__name__, signature)(f)
            return numba.njit(f)
 
            fact_table = cc_export(fact_table, (i8, i8))
            main = cc_export(main, (i8, i8, i8))
            cc.compile()

    #文字列入力の時は上記はerrorとなる。
    #ここにコード
    #input
    n, m = list(map(int, input().split()))

    #output
    mod = pow(10, 9) + 7

    n_ = 5 * pow(10, 5) + 5
    fun = [1] * (n_+1)
    for i in range(1, n_+1):
        fun[i] = fun[i-1] * i % mod
    rev = [1] * (n_+1)
    rev[n_] = pow(fun[n_], mod-2, mod)
    for i in range(n_-1, 0, -1):
        rev[i] = rev[i+1] * (i+1) % mod
    def cmb(n,r):
        if n < 0 or r < 0 or r > n: return 0
        return fun[n] * rev[r] % mod * rev[n-r] % mod
    def perm(n, r):
        if n < 0 or r < 0 or r > n: return 0
        return fun[n] * rev[n-r] % mod

    #Aを1, 2, ..., nとする。
    #求める写像の総数をs(n, m)とする。
    #s(n, m) = sum(k=0, n)(cmb(n, k)* (-1)^k * cmb(m-k, n-k)*(n-k)!)

    import math
    answer = 0
    for i in range(n+1):
        temp = perm(n, i) * cmb(m, i) * pow(perm(m-i, n-i), 2)
        temp %= mod
        if i % 2 == 0:
            answer += temp
        else:
            answer -= temp
    print((answer % mod))

    #N = 1のときなどcorner caseを確認！
def __starting_point():
    main()

__starting_point()

n, m = map(int, input().split())
mod = 10**9+7
nums = 5*(10**5) # 制約に合わせよう

g1, g2, inverse = [1, 1] , [1, 1], [0, 1]
 
for num in range(2, nums + 1):
    g1.append((g1[-1] * num) % mod)
    inverse.append((-inverse[mod % num] * (mod//num)) % mod)
    g2.append((g2[-1] * inverse[-1]) % mod)
    
def nPr(n, r):
    return g1[n] * g2[n-r] % mod

def nCr(n, r):
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

ans = 0
for r in range(n+1):
    tmp = nCr(n, r)*nPr(m, r)*(nPr(m-r, n-r)**2)%mod
    ans = (ans+(-1)**r*tmp)%mod
print(ans)

# E - NEQ
import sys
sys.setrecursionlimit(10**6)
MOD = 10**9+7
mon_l = dict({})

def mon(m,n):
    if (m,n) in mon_l:
        return mon_l[(m,n)]
    if n==1:
        mon_l[(m,n)] = m-1
        return mon_l[(m,n)]
    if n==2:
        mon_l[(m,n)] = ((m-1)+(m-2)**2)%MOD
        return mon_l[(m,n)]
    else:
        mon_l[(m,n)] = ((n-1)*(mon(m-1,n-1)+mon(m-2,n-2)) + (m-n)*mon(m-1,n-1))%MOD
        return mon_l[(m,n)]
    
def permu(m,n):
    ans = 1
    for _ in range(n):
        ans = m*ans%MOD
        m -= 1
    return ans

N,M = map(int,input().split())
ans = permu(M,N)*mon(M,N)%MOD
print(ans)

max_fact = 5 * 10**5
mod = 10**9 + 7

f = [1] * (max_fact + 1)
for idx in range(2, max_fact + 1):
    f[idx] = f[idx - 1] * idx
    f[idx] %= mod
fi = [pow(f[-1], mod - 2, mod)]
for idx in range(max_fact, 0, -1):
    fi += [fi[-1] * idx % mod]
fi = fi[::-1]

def factorial(n):
    return f[n]

def factorial_inverse(n):
    return fi[n]

def combination(n, r):
    return f[n] * fi[r] * fi[n - r] % mod

def permutation(n, r):
    return f[n] * fi[n - r] % mod

def homogeneous_product(n, r):
    return f[n + r - 1] * fi[r] * fi[n - 1] % mod


comb = combination
perm = permutation

N, M = [int(_) for _ in input().split()]
ans = 0
for p in range(N + 1):
    ans += (-1)**p * comb(N, p) * perm(M - p, N - p)
    ans %= mod
ans *= perm(M, N)
ans %= mod
print(ans)


M=10**9+7
n,m=map(int,input().split())
F=[1]
for i in range(1,m+1): F+=[i*F[-1]%M]
a=0
for k in range(n+1):
  a+=(-1)**k*F[m-k]*pow(F[k]*F[n-k],-1,M)%M
print(a*F[n]*F[m]*pow(F[m-n]**2,-1,M)%M)

N, M = map(int, input().split())

mod = 10 ** 9 + 7
#L = 5 * 10**5
fac = [1, 1]
finv = [1, 1]
inv = [0, 1]

def comb(n, r):
  return fac[n] * ( finv[r] * finv[n-r] % mod ) % mod

def perm(n, r):
  return  fac[n] * finv[n-r] % mod
 
for i in range(2, M + 1):
  fac.append( ( fac[-1] * i ) % mod )
  inv.append( mod - ( inv[mod % i] * (mod // i) % mod ) )
  finv.append( finv[-1] * inv[-1]  % mod )

ans = 0

for K in range(N+1):
  ans += comb(N, K) * (-1)**(K%2) % mod * perm(M, K) % mod * pow(perm(M-K, N-K), 2, mod)
  ans %= mod

print(ans)

n,m=map(int,input().split())
i,a,b=0,1,0
while i<n:c=((m-i)*((m-n+i)*a+i*b*(m-i+1)))%(10**9+7);i+=1;a,b=c,a
print(a)

n,m=list(map(int,input().split()))
d=[1]*(n+1)
for i in range(n):
  d[i+1]=((m-i)*((m-n+i)*d[i]+i*d[i-1]*(m-i+1)))%(10**9+7)
print((d[-1]))


from sys import stdin
import sys
import math
from functools import reduce
import functools
import itertools
from collections import deque,Counter
from operator import mul
from functools import reduce


N = 10**6
mod = 10**9+7

inv_t = [0] + [1]
for i in range(2, N):
    inv_t += [inv_t[mod % i] * (mod - int(mod / i)) % mod]

kai = [1, 1]
rev_kai = [1, inv_t[1]]
for i in range(2, N):
    kai.append(kai[-1] * i % mod)
    rev_kai.append(rev_kai[-1] * inv_t[i] % mod)

def cmb(n, r):
    return kai[n] * rev_kai[r] * rev_kai[n - r] % mod

def prm(n, r):
    return kai[n] * rev_kai[n - r] % mod

n,m = list(map(int, input().split()))

a = 0
for k in range(n+1):
    a += prm(m, k)*prm(m-k,n-k)**2*(-1)**k*cmb(n,k) % mod

print(a % mod)

#!/usr/bin/env python3
import sys
sys.setrecursionlimit(10**8)
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
def ZIP(n): return list(zip(*(MAP() for _ in range(n))))


INF = float("inf")
MOD = 10**9 + 7

class Combination(object):
    def __init__(self, N, mod=MOD):
        fac, finv, inv = [0] * (N + 1), [0] * (N + 1), [0] * (N + 1)
        fac[:2] = 1, 1
        finv[:2] = 1, 1
        inv[1] = 1
        for i in range(2, N + 1):
            fac[i] = fac[i - 1] * i % mod
            inv[i] = -inv[mod % i] * (mod // i) % mod
            finv[i] = finv[i - 1] * inv[i] % mod
        self.N = N
        self.MOD = mod
        self.fac = fac
        self.finv = finv
        self.inv = inv

    def __call__(self, n, k):
        return self.C(n, k)

    def C(self, n, k):
        if n < k:
            return 0
        if n < 0 or k < 0:
            return 0
        fac = self.fac
        finv = self.finv
        mod = self.MOD
        return fac[n] * (finv[k] * finv[n - k] % mod) % mod

    def P(self, n, k):
        if n < k:
            return 0
        if n < 0 or k < 0:
            return 0
        return self.fac[n] * self.finv[n - k]


def main():
    N, M = MAP()
    cmb = Combination(M)

    ans = 0
    for i in range(N + 1):
        buf = (-1) ** i * cmb(N, i)
        buf %= MOD
        buf *= cmb.P(M, i)
        buf %= MOD
        buf *= pow(cmb.P(M - i, N - i), 2, MOD)
        buf %= MOD
        ans += buf
        ans %= MOD
    print(ans)

    return


def __starting_point():
    main()

__starting_point()

def prepare(n, MOD):
 
    # n! の計算
    f = 1
    fn=[1]*(n+1)
    for m in range(1, n + 1):
        f *= m
        f %= MOD
        fn[m]=f
     
    # n!^-1 の計算
    inv = pow(f, MOD - 2, MOD)
    # n!^-1 - 1!^-1 の計算
    invs = [1] * (n + 1)
    invs[n] = inv
    for m in range(n, 1, -1):
        inv *= m
        inv %= MOD
        invs[m - 1] = inv
     
    return fn, invs

def main():
    n,m=map(int,input().split())
    MOD=10**9+7
    fn,invs=prepare(m,MOD)
    ans=0
    for i in range(n+1):
        x=(fn[m-i]*invs[m-n])%MOD
        x=(x*fn[n]*invs[i]*invs[n-i])%MOD
        x*=(-1)**i
        ans+=x
    ans=(ans*fn[m]*invs[m-n])%MOD
    print(ans)

def __starting_point():
    main()
__starting_point()

n,m=map(int,input().split())
a = 1
Mod=10**9+7
d = [1]*(n+1)
for i in range(n):
  d[i+1]=((m-n+i)*d[i]+i*d[i-1])%Mod
  a=a*(m-i)%Mod
print(a*d[n]%Mod)

#!/usr/bin/env python3
import sys
sys.setrecursionlimit(10**8)
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
def ZIP(n): return list(zip(*(MAP() for _ in range(n))))


INF = float("inf")
MOD = 10**9 + 7

class Combination(object):
    def __init__(self, N, mod=MOD):
        fac, finv, inv = [0] * (N + 1), [0] * (N + 1), [0] * (N + 1)
        fac[:2] = 1, 1
        finv[:2] = 1, 1
        inv[1] = 1
        for i in range(2, N + 1):
            fac[i] = fac[i - 1] * i % mod
            inv[i] = -inv[mod % i] * (mod // i) % mod
            finv[i] = finv[i - 1] * inv[i] % mod
        self.N = N
        self.MOD = mod
        self.fac = fac
        self.finv = finv
        self.inv = inv

    def __call__(self, n, k):
        return self.C(n, k)

    def C(self, n, k):
        if n < k:
            return 0
        if n < 0 or k < 0:
            return 0
        fac = self.fac
        finv = self.finv
        mod = self.MOD
        return fac[n] * (finv[k] * finv[n - k] % mod) % mod

    def P(self, n, k):
        if n < k:
            return 0
        if n < 0 or k < 0:
            return 0
        return self.fac[n] * self.finv[n - k]


def main():
    N, M = MAP()
    ans = 0

    cmb = Combination(M)

    sign = +1
    for i in range(N+1):
        ans += sign * cmb.P(M-i, N-i) * cmb(N, i)
        ans %= MOD
        sign *= -1
    ans *= cmb.P(M, N)
    ans %= MOD
    print(ans)
    return


def __starting_point():
    main()

__starting_point()

N, M = map(int, input().split())
MOD = 10 ** 9 + 7

n = N + M
fac = [1] * (n + 1) 
inv = [1] * (n + 1)
for j in range(1, n + 1):
    fac[j] = (fac[j - 1] * j) % MOD

inv[n] = pow(fac[n], MOD-2, MOD)
for j in range(n - 1, -1, -1):
    inv[j] = (inv[j + 1] * (j + 1)) % MOD

def comb(n, r):
    if r > n or n < 0 or r < 0:
        return 0
    return (fac[n] * inv[n - r] * inv[r]) % MOD

def perm(n, r):
    if r > n or n < 0 or r < 0:
        return 0
    return comb(n, r) * fac[r] % MOD

ans = pow(perm(M, N), 2, MOD)
# r: AiとBiが一致する個数
for r in range(1, N + 1):
    p = comb(M, r) * perm(N, r) * pow(perm(M - r, N - r), 2, MOD) % MOD
    p *= -(-1) ** (r % 2)
    ans -= p
    ans %= MOD

print(ans)

# E - NEQ

N, M = map(int, input().split())
MOD = 10 ** 9 + 7

fac = [1, 1]
inv = [0, 1]
finv = [1, 1]

for i in range(2, M+1):
    fac.append(fac[-1] * i % MOD)
    inv.append(MOD - inv[MOD%i] * (MOD//i) % MOD)
    finv.append(finv[-1] * inv[-1] % MOD)

fixed = (fac[N] * fac[M] * pow(finv[M-N], 2, MOD)) % MOD

def f(k):
    return (fac[M-k] * finv[k] * finv[N-k]) % MOD

ans = 0
for i in range(N+1):
    ans = (ans + f(i) * pow(-1, i)) % MOD

print((fixed * ans) % MOD)

class Combination():
    def __init__(self, n, mod=10**9+7):
        self.mod = mod
        self.fac = [1]*(n+1)
        for i in range(1,n+1):
            self.fac[i] = self.fac[i-1] * i % self.mod
        self.invfac = [1]*(n+1)
        self.invfac[n] = pow(self.fac[n], self.mod - 2, self.mod)
        for i in range(n-1, 0, -1):
            self.invfac[i] = self.invfac[i+1] * (i+1) % self.mod

    def combination(self, n, r):
        return self.fac[n] * self.invfac[r] % self.mod * self.invfac[n-r] % self.mod

    def permutation(self, n, r):
        return self.factorial(n) * self.invfactorial(n-r) % self.mod

    def factorial(self, i):
        return self.fac[i]

    def invfactorial(self, i):
        return self.invfac[i]

def main():
    import sys
    def input(): return sys.stdin.readline().rstrip()
    n, m = map(int, input().split())
    c = Combination(m)
    mod = 10**9 + 7
    ans = 0
    for i in range(n+1):
        tmp = c.combination(n,i)*pow(-1,i%2)*c.permutation(m, i)%mod
        tmp *= c.permutation(m-i, n-i)**2
        tmp %= mod
        ans += tmp
        ans %= mod
    print(ans)



def __starting_point():
    main()
__starting_point()

import sys

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007


def main():
    N, M = list(map(int, readline().split()))

    COM_MAX = M

    fac, finv, inv = [0] * (COM_MAX + 1), [0] * (COM_MAX + 1), [0] * (COM_MAX + 1)
    fac[0] = fac[1] = finv[0] = finv[1] = inv[1] = 1

    for i in range(2, COM_MAX + 1):
        fac[i] = fac[i - 1] * i % MOD
        inv[i] = MOD - inv[MOD % i] * (MOD // i) % MOD
        finv[i] = finv[i - 1] * inv[i] % MOD

    def com(n, r):
        if n < 0 or r < 0 or n < r:
            return 0
        return fac[n] * (finv[r] * finv[n - r] % MOD) % MOD

    def perm(n, r):
        if n < 0 or r < 0 or n < r:
            return 0
        return fac[n] * finv[n - r] % MOD

    ans = 0
    for k in range(N + 1):
        tmp = perm(M - k, N - k) * com(N, k) % MOD
        if k & 1:
            tmp *= -1
        ans = (ans + tmp) % MOD

    ans = ans * perm(M, N) % MOD

    print(ans)
    return


def __starting_point():
    main()

__starting_point()

import sys 
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
mod = 10**9+7
N, M = map(int, readline().split())
 
fact = [1] * (M+1)
fact_inv = [1] * (M+1)
for i in range(1,M+1):
    fact[i] = fact[i-1] * i % mod 
fact_inv[M] = pow(fact[M],mod-2,mod)
for i in range(M,0,-1):
    fact_inv[i-1] = (i * fact_inv[i]) % mod 
 
def comb(n,r):
  return fact[n] * fact_inv[r] * fact_inv[n-r] % mod
total = 0
for k in range(N+1):
    a = fact[M-k] * fact_inv[M-N] * comb(N,k) % mod
    if k % 2 == 0:
        total += a
    else:
        total -= a
ans = (comb(M,N) * fact[N]) % mod * total 
print(ans%mod)

mod = 10 ** 9 + 7

def mod_prepare(N):
    fac = [1, 1]
    finv = [1, 1]
    inv = [0, 1]
    for i in range(2, N + 1):
        fac.append(fac[i - 1] * i % mod)
        inv.append(mod - inv[mod % i] * (mod // i) % mod)
        finv.append(finv[i - 1] * inv[i] % mod)
    return fac, finv

N, M = map(int, input().split())

fac, inv = mod_prepare(M)

ans = 0
sign = 1
for k in range(N + 1):
    ans += sign * fac[M - k] * inv[k] * inv[N - k]
    sign *= -1
    ans %= mod

print(ans * fac[N] * fac[M] * inv[M - N] * inv[M - N] % mod)

import sys
input = sys.stdin.readline

N,M=map(int,input().split())
mod=10**9+7

FACT=[1]
for i in range(1,5*10**5+1):
    FACT.append(FACT[-1]*i%mod)

FACT_INV=[pow(FACT[-1],mod-2,mod)]
for i in range(5*10**5,0,-1):
    FACT_INV.append(FACT_INV[-1]*i%mod)

FACT_INV.reverse()

def Combi(a,b):
    if 0<=b<=a:
        return FACT[a]*FACT_INV[b]*FACT_INV[a-b]%mod
    else:
        return 0

ANS=0
for i in range(N+1):
    if i%2==0:
        ANS=(ANS+Combi(N,i)*FACT[M-i]*FACT_INV[M-N])%mod
    else:
        ANS=(ANS-Combi(N,i)*FACT[M-i]*FACT_INV[M-N])%mod

print(ANS*FACT[M]*FACT_INV[M-N]%mod)

n,m = map(int,input().split())
mod = 10**9+7

fact = [1,1]
finv = [1,1]
inv = [0,1]
 
for i in range(2,max(n,m)+5):
    fact.append((fact[-1]*i)%mod)
    inv.append((inv[mod%i]*(mod-mod//i))%mod)
    finv.append((finv[-1]*inv[-1])%mod)
 
def nCr(n,r,mod):
    if r > n:
        return 0
    else: 
        return fact[n]*finv[r]*finv[n-r]%mod

def nPr(n,r,mod):
    if r > n:
        return 0
    else: 
        return fact[n]*finv[n-r]%mod


ans = 0
for i in range(n+1):
    now = nCr(n,i,mod)
    now *= nPr(m-i,n-i,mod)
    now %= mod
    if i%2:
        now = -now
    ans += now
    ans % mod
ans *= nPr(m,n,mod)
ans %= mod
print(ans)

def cmb(n, r, mod):#コンビネーションの高速計算　
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod
mod = 10**9+7 #出力の制限
N = 5*10**5 #Nの最大値
g1 = [1, 1] #元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル
for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )

N, M = map(int, input().split())
ans = 0
for i in range(N+1):
    ans += cmb(N,i,mod)*((-1)**i)*g1[M]*g2[M-i]*((g1[M-i]*g2[M-N])**2)
    ans %= mod
print(ans)

import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians, gcd
from itertools import accumulate, permutations, combinations, product, groupby, combinations_with_replacement
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return list(map(int, input().split()))
def LIST(): return list(map(int, input().split()))
def ZIP(n): return list(zip(*(MAP() for _ in range(n))))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

N, M = MAP()

lim = M+10  # 必要そうな階乗の限界を入れる
fact = [1] * (lim+1)
fact_inv = [1] * (lim+1)
for n in range(1, lim+1):
    fact[n] = (fact[n-1] * n) % mod
fact_inv[lim] = pow(fact[lim], mod-2, mod)
for n in range(lim, 0, -1):
    fact_inv[n-1] = (n * fact_inv[n]) % mod
def C(n, r):
    return (((fact[n] * fact_inv[r]) % mod) * fact_inv[n-r]) % mod

def P(n, r):
    return fact[n]*fact_inv[n-r]%mod

ans = 0
for k in range(N+1):
    ans += (-1)**(k%2) * C(N, k) * P(M-k, N-k)
    ans %= mod

ans *= P(M, N)
print((ans%mod))


N,M=map(int, input().split())

md=1000000007
fac=[0]*(M+1)
inv=[0]*(M+1)
ifac=[0]*(M+1)
inv[1]=1
for i in range(2,M+1):
	inv[i] = (md - (md//i) * inv[md%i] % md) % md;
fac[0]=1
ifac[0]=1
for i in range(1,M+1):
    fac[i]=fac[i-1]*i%md;
    ifac[i]=ifac[i-1]*inv[i]%md;

def choose(n,k):
    return fac[n]*ifac[k]*ifac[n-k]%md
def perm(m,n):
    return fac[m]*ifac[m-n]%md
ans=0
for k in range(N+1):
    if k%2==0:
        ans+=choose(N,k)*perm(M,k)*perm(M-k,N-k)**2
        ans%=md
    else:
        ans-=choose(N,k)*perm(M,k)*perm(M-k,N-k)**2
        ans%=md
print(ans)

# coding: utf-8
import sys
# from operator import itemgetter
sysread = sys.stdin.readline
read = sys.stdin.read
sys.setrecursionlimit(10 ** 7)
#from heapq import heappop, heappush
#from collections import OrderedDict, defaultdict
#import math
#from itertools import product, accumulate, combinations, product
#import bisect# lower_bound etc
import numpy as np
#from copy import deepcopy
from collections import deque
#import numba

def generate_inv(n,mod):
    """
    逆元行列
    n >= 2
    Note: mod must bwe a prime number
    """
    ret = [0, 1]
    for i in range(2,n+1):
        next = -ret[mod%i] * (mod // i)
        next %= mod
        ret.append(next)
    return ret

def generate_comb_m_i(M, N, inv, mod):
    ret = [1, M]
    for i in range(2, N+1):
        tmp = (ret[-1] * (M-(i-1)) * inv[i]) % mod
        ret.append(tmp)
    return ret
def generate_p_N_i(N, mod):
    ret = [1]
    for i in range(1, N+1):
        tmp = (ret[-1] * (N - (i-1))) % mod
        ret.append(tmp)
    return ret

def generate_p_mi_ni(M, N, mod):
    ret = deque([1])
    cache = deque([1])
    for i in range(1, N+1):
        tmp = (cache[0] * (M-N+i)) % mod
        cache.appendleft(tmp)
        ret.appendleft((tmp ** 2) % mod)
    return ret


def run():
    N, M = map(int, input().split())
    mod = 10 ** 9 + 7

    inv = generate_inv(M, mod)

    comb_m_i = generate_comb_m_i(M, N, inv, mod)
    #print(comb_m_i[0])
    p_N_i = generate_p_N_i(N, mod)
    #print(p_N_i[0])
    p_mi_ni = generate_p_mi_ni(M, N, mod)
    #print(p_mi_ni[0])

    ret = p_mi_ni[0]

    arr01 = [-1, 1] * (N//2 + 1)
    arr01 = arr01[:N+1]

    comb_m_i = np.array(comb_m_i, dtype=np.int64)
    p_N_i = np.array(p_N_i, dtype=np.int64)
    p_mi_ni = np.array(p_mi_ni, dtype=np.int64)
    arr01 = np.array(arr01, dtype=np.int64)

    tmp = (comb_m_i * p_N_i) % mod
    tmp = (tmp * p_mi_ni) % mod
    tmp = (tmp * arr01) % mod
    tmp = tmp[1:]
    sub = 0
    for val in tmp:
        sub += val
        sub %= mod

    ret -= sub
    ret %= mod

    print(ret)

def __starting_point():
    run()
__starting_point()

#二項係数、順列準備
MAX_NUM = 5* 10**5 + 1
MOD = 10**9+7

fac  = [0 for _ in range(MAX_NUM)]
finv = [0 for _ in range(MAX_NUM)]
inv  = [0 for _ in range(MAX_NUM)]

fac[0]  = fac[1] = 1
finv[0] = finv[1] = 1
inv[1] = 1

for i in range(2,MAX_NUM):
  fac[i] = fac[i-1] * i % MOD
  inv[i] = MOD - inv[MOD%i] * (MOD // i) % MOD
  finv[i] = finv[i-1] * inv[i] % MOD

def comb(n,k):
  if n < k:
    return 0
  if n < 0 or k < 0:
    return 0
  return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD

def perm(n,k):
  if n < k:
    return 0
  if n < 0 or k < 0:
    return 0
  return fac[n] * finv[n-k] % MOD

#主計算
N, M = map(int,input().split())

ans = 0
for K in range(N+1):
  term = comb(N, K) * perm(M, K) 
  term *= perm(M - K, N - K)**2
  term %= MOD
  if K % 2 == 0:
    ans = (ans + term) % MOD
  else:
    ans = (ans - term) % MOD
    
print(ans)

n, m = map(int, input().split())

mod = 10**9+7
N = 10**6  # N!まで求める
fact  = [1, 1]  # 階乗の元テーブル
fact_inv = [1, 1]  # 階乗の逆元テーブル
inv = [0, 1]  # 逆元テーブル計算用テーブル 1,2,,...の逆元を求めてる

# 計算 O(1)
def comb(n, r, mod):
    if (r<0 or r>n):
        return 0
    r = min(r, n-r)
    return fact[n] * fact_inv[r] * fact_inv[n-r] % mod

def perm(n, r, mod):
    if (r<0 or r>n):
        return 0
    return fact[n] *  fact_inv[n-r] % mod

# 前処理 O(n)
for i in range(2, N + 1):
    fact.append((fact[-1] * i) % mod)
    inv.append((-inv[mod % i] * (mod//i)) % mod)
    fact_inv.append((fact_inv[-1] * inv[-1]) % mod)

ans = 0
for k in range(n+1):
    ans += comb(n, k, mod) * perm(m, k, mod) * (perm(m-k, n-k, mod) ** 2) * ((-1) ** k)
    ans %= mod

print(ans)

import sys

# ## COMBINATION (MOD) ## #
MOD = 10**9 + 7  # , N = 2*10**5 で 0.3s
N_MAX = 5 * 10**5  # 問題サイズに合わせて変えておく

fac = [1, 1]  # 元テーブル
facinv = [1, 1]  # 逆元テーブル
inv = [0, 1]  # 逆元テーブル計算用テーブル

for i in range(2, N_MAX + 1):
    fac.append((fac[-1] * i) % MOD)
    inv.append((-inv[MOD % i] * (MOD // i)) % MOD)
    facinv.append((facinv[-1] * inv[-1]) % MOD)


def cmb(n, r):
    if (r < 0 or r > n):
        return 0
    # r = min(r, n-r)
    return fac[n] * facinv[r] * facinv[n - r] % MOD


def prm(n, r):
    if (r < 0 or r > n):
        return 0
    # r = min(r, n-r)
    return fac[n] * facinv[n - r] % MOD


def main():
    N, M = list(map(int, sys.stdin.readline().rstrip().split()))

    all = prm(M, N) ** 2 % MOD

    dup = 0

    for i in range(1, N + 1):

        tmp = prm(M, i) * prm(M - i, N - i) ** 2 % MOD
        tmp *= cmb(N, i) * (-1) ** (i - 1)

        dup += tmp % MOD

    print(((all - dup) % MOD))

main()


class Factorial:
    def __init__(self, max_fact, mod):
        #mod should be prime number
        #using homogeneous_product(n,r), max_fact ≧ max(n+r-1)
        f = [1] * (max_fact + 1)
        for idx in range(2, max_fact + 1):
            f[idx] = f[idx - 1] * idx
            f[idx] %= mod
        fi = [pow(f[-1], mod - 2, mod)]
        for idx in range(max_fact, 0, -1):
            fi += [fi[-1] * idx % mod]
        fi = fi[::-1]
        self.mod = mod
        self.f = f
        self.fi = fi

    def factorial(self, n):
        return self.f[n]

    def factorial_inverse(self, n):
        return self.fi[n]

    def combination(self, n, r):
        f = self.f
        fi = self.fi
        return f[n] * fi[r] * fi[n - r] % self.mod

    def permutation(self, n, r):
        return self.f[n] * self.fi[n - r] % self.mod

    def homogeneous_product(self, n, r):
        f = self.f
        fi = self.fi
        return f[n + r - 1] * fi[r] * fi[n - 1] % self.mod


max_fact = 10**6
mod = 10**9 + 7
fact_instance = Factorial(max_fact, mod)
comb = fact_instance.combination
perm = fact_instance.permutation

N, M = [int(_) for _ in input().split()]
ans = 0
for p in range(N + 1):
    ans += (-1)**p * comb(N, p) * perm(M - p, N - p)
    ans %= mod
ans *= perm(M, N)
ans %= mod
print(ans)



def main():
    n,m = list(map(int,input().split()))
    MOD = 10**9 + 7

    fact = [1]
    fact_inv = [1]
    for i in range(m):
        fact.append(fact[-1]*(i+1)%MOD)
    fact_inv = [1] * (m+1)
    fact_inv[m] = pow(fact[m],MOD-2,MOD)
    for i in range(m):
        fact_inv[m-i-1] = fact_inv[m-i] * (m-i) % MOD
    # print(fact_inv)


    ｍPn = fact[m] * pow(fact[m-n],MOD-2,MOD) % MOD

    a = pow(mPn,2,MOD)
    b = 0
    for i in range(1,n+1):
        nCr = fact[n] * fact_inv[i] % MOD * fact_inv[n-i] % MOD
        b += (-1)**(i%2) * nCr * fact[m-i] % MOD * fact_inv[m-n] % MOD
        b %= MOD
    ans = a + b * mPn
    print((ans%MOD))


main()




# 解説などを参考に作成
# https://mathtrain.jp/hojo
# https://qiita.com/DaikiSuyama/items/4d0388a3f68b60c3e5f3
# https://atcoder.jp/contests/abc172/submissions/16541798
# tag: 包除原理
# import sys
# sys.setrecursionlimit(10 ** 6)
# import bisect
# from collections import deque

class FermatCmb:
    """フェルマー小定理を使用した順列, 組み合わせ計算"""

    def __init__(self, max_num, mod):
        """
        :param max_num: max n of nCk
        :param mod: any prime number
        """
        self.max_num = max_num
        self.mod = mod
        self.fact = [0 for _ in range(max_num + 1)]
        self.factinv = [0 for _ in range(max_num + 1)]

        self.fact[0] = 1
        for i in range(1, max_num + 1):
            self.fact[i] = (i * self.fact[i - 1]) % self.mod

        self.factinv[-1] = pow(self.fact[-1], mod - 2, mod)
        for i in range(max_num, 0, -1):
            self.factinv[i - 1] = self.factinv[i] * i
            self.factinv[i - 1] %= self.mod

    def nCk(self, n, k):
        return (self.fact[n] * self.factinv[k] * self.factinv[n - k]) % self.mod

    def nPk(self, n, k):
        return (self.fact[n] * self.factinv[n - k]) % self.mod


# from decorator import stop_watch
# 
# 
# @stop_watch
def solve(N, M):
    mod = 10 ** 9 + 7
    cf = FermatCmb(M, mod)
    ans = 0
    for k in range(N + 1):
        ans += (-1) ** k * cf.nCk(N, k) * cf.nPk(M, k) * (
                cf.nPk(M - k, N - k) ** 2)
        ans %= mod
    print(ans)


def __starting_point():
    # S = input()
    # N = int(input())
    N, M = list(map(int, input().split()))
    # A = [int(i) for i in input().split()]
    # B = [int(i) for i in input().split()]
    # AB = [[int(i) for i in input().split()] for _ in range(N)]
    solve(N, M)

    # # test
    # from random import randint
    # from func import random_str
    # solve()

__starting_point()

MOD = 10**9 + 7

MOD_t_MAX = 5*10**5+10

fac  = [None] * MOD_t_MAX
finv = [None] * MOD_t_MAX
inv  = [None] * MOD_t_MAX
def MOD_COM_init():
    fac[0] = fac[1] = 1
    finv[0] = finv[1] = 1
    inv[1] = 1
    for i in range(2, MOD_t_MAX):
        fac[i] = fac[i - 1] * i % MOD
        inv[i] = MOD - inv[MOD%i] * (MOD // i) % MOD
        finv[i] = finv[i - 1] * inv[i] % MOD
def MOD_COM(n, k):
    if n < k:
        return 0
    if n < 0 or k < 0:
        return 0
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD

def MOD_perm(n, r):
    rtn = 1
    for _ in range(r):
        rtn *= n
        rtn %= MOD
        n -= 1
    return rtn

def main():
    n, m = map(int, input().split())
    ans = 0
    perm = MOD_perm(m, n)
    MOD_COM_init()
    for i in range(n+1):
        tmp = perm * MOD_COM(n, i) % MOD
        ans += (-1)**i * tmp
        ans %= MOD
        if i < n:
            perm *= inv[m-i]
            perm %= MOD
    print(ans*MOD_perm(m, n)%MOD)

def __starting_point():
    main()
__starting_point()

# MOD下での階乗とその逆元を求める関数
# O(nlogn + n) ?
def prepare(n):
    nonlocal mod
    modFacts = [0] * (n + 1)
    modFacts[0] = 1
    for i in range(n):
        modFacts[i + 1] = (modFacts[i] * (i + 1)) % mod

    invs = [1] * (n + 1)
    invs[n] = pow(modFacts[n], mod - 2, mod)
    for i in range(n, 1, -1):
        invs[i - 1] = (invs[i] * i) % mod

    return modFacts, invs

n,m = list(map(int,input().split()))
mod = 10**9+7
modFacts,invs = prepare(m)
ans = 0
nci = 0
for i in range(n+1):
    nci = (modFacts[n]*invs[n-i]*invs[i]) % mod
    mpi = (modFacts[m]*invs[m-i]) % mod
    mipni = (modFacts[m-i]*invs[m-n]) % mod
    ans += ((nci * mpi * mipni**2) % mod )* (-1)**i
    ans %= mod
    # print(i,nci,mpi,mipni)
print(ans)


'''
Let g(x) = 序列內數字唯一，且最多 x 個位置不同。
Let f(x) = 序列內數字唯一，且給定 x 個位置時，使這些位置不同的方法數。

題目所求是 C(N, N) f(N)。

其中 g(x) 代表有至少 N - x 個位置是相同。可以分三個部份填數字，注意順序會影響，所以要乘上全排列：
(1) N - x 個位置（數字必需相同）：C(M, N - x) * (N - x)! = P(M, N - x)
(2) 序列 A 其餘位置（可以隨便填，但不能用到 (1) 的數字）：C(M - (N - x), x) * x! = P(M - (N - x), x)
(3) 序列 B 其餘位置（可以隨便填，但不能用到 (1) 的數字）：C(M - (N - x), x) * x! = P(M - (N - x), x)
g(x) = (1) * (2) * (3)

g(x) 是「選定 0 個位置，使這些位置不同的方法數」、「選定 1 個位置，使這些位置不同的方法數」、…、「選定 x 個位置，使這些位置不同的方法數」，即
g(x) = C(x, 0) f(0) + C(x, 1) f(1) + ... + C(x, x) f(x)
     = sum( C(x, i) * f(i) for i in [0, x] )
根據二項式反演，得到
f(x) = sum( (-1) ** (x - i) * C(x, i) * g(i) for i in [0, x] )
'''

class CombMod:
    def __init__(self, V, p):
        self.fact = [1] * V
        self.finv = [1] * V
        for i in range(1, V):
            self.fact[i] = self.fact[i - 1] * i % p
        self.finv[-1] = pow(self.fact[-1], p - 2, p)
        for i in range(V - 2, 0, -1):
            self.finv[i] = self.finv[i + 1] * (i + 1) % p
        self.p = p
        
    def fact(self, a):
        return self.fact[a]
    
    def finv(self, a):
        return self.finv[a]

    def comb(self, a, b):
        return self.fact[a] * self.finv[b] % self.p * self.finv[a - b] % self.p
        
    def perm(self, a, b):
        return self.fact[a] * self.finv[a - b] % self.p
    
    def hcomb(self, a, b):
        return self.comb(a + b - 1, b)


N, M = list(map(int, input().split()))
mod = 10**9 + 7
tool = CombMod(max(N, M) + 10, mod)

f_N = 0
for i in range(0, N + 1):
    p1 = tool.perm(M, N - i)
    p2 = tool.perm(M - (N - i), i)
    g_i = p1 * p2 % mod * p2 % mod
    val = (-1)**((N - i) % 2) * tool.comb(N, i) % mod * g_i % mod
    f_N = (f_N + val) % mod
ans = tool.comb(N, N) * f_N % mod
print(ans)


n, m = map(int, input().split(' '))
mod = int(1e9 + 7)

l = [1] * (m+1)
for i in range(1, m+1):
	l[i] = (l[i-1] * i) % mod

l2 = [1] * (m+1)
l2[m] = pow(l[m], mod-2, mod)
for i in range(m-1, 0, -1):
	l2[i] = (l2[i+1] * (i+1)) % mod

s = 0
for k in range(n+1):
	n_choose_k = (l[n] * l2[k] * l2[n-k]) % mod
	m_perm_k = (l[m] * l2[m-k]) % mod
	mk_perm_nk = (l[m-k] * l2[m-n]) % mod
	s += ((-1) ** k * n_choose_k * m_perm_k * mk_perm_nk ** 2 ) % mod 

print(s % mod)

class Factorial():
    def __init__(self, n, mod):
        self.mod = mod
        self.fct = [0 for _ in range(n + 1)]
        self.inv = [0 for _ in range(n + 1)]
        self.fct[0] = 1
        self.inv[0] = 1
        for i in range(n):
            self.fct[i + 1] = self.fct[i] * (i + 1) % mod
        self.inv[n] = pow(self.fct[n], mod - 2, mod)
        for i in range(n)[::-1]:
            self.inv[i] = self.inv[i + 1] * (i + 1) % mod

    def fact(self, m):
        return self.fct[m]

    def invf(self, m):
        return self.inv[m]

    def perm(self, m, k):
        if m < k: return 0
        return self.fct[m] * self.inv[m - k] % self.mod

    def comb(self, m, k):
        if m < k: return 0
        return self.fct[m] * self.inv[k] * self.inv[m - k] % self.mod

MOD = 1000000007

N, M = map(int, input().split())

f = Factorial(M, MOD)

res = f.perm(M, N)

for k in range(1, N + 1):
    res -= (-1)**(k - 1) * f.comb(N, k) * f.perm(M - k, N - k)

res *= f.perm(M, N)
res %= MOD

print(res)

class Factorial:
    def __init__(self, max_fact, mod):
        #mod should be prime number
        #using homogeneous_product(n,r), max_fact ≧ max(n+r-1)
        f = [1] * 2 + [None] * (max_fact - 1)
        for idx in range(2, max_fact + 1):
            f[idx] = f[idx - 1] * idx % mod
        fi = [None] * max_fact + [pow(f[-1], mod - 2, mod)]
        for idx in range(max_fact, 0, -1):
            fi[idx - 1] = fi[idx] * idx % mod
        self.mod = mod
        self.f = f
        self.fi = fi

    def factorial(self, n):
        return self.f[n]

    def factorial_inverse(self, n):
        return self.fi[n]

    def combination(self, n, r):
        f = self.f
        fi = self.fi
        return f[n] * fi[r] * fi[n - r] % self.mod

    def permutation(self, n, r):
        return self.f[n] * self.fi[n - r] % self.mod

    def homogeneous_product(self, n, r):
        f = self.f
        fi = self.fi
        return f[n + r - 1] * fi[r] * fi[n - 1] % self.mod


max_fact = 5 * 10**5
mod = 10**9 + 7
fact_instance = Factorial(max_fact, mod)
comb = fact_instance.combination
perm = fact_instance.permutation

N, M = [int(_) for _ in input().split()]
ans = 0
for p in range(N + 1):
    ans += (-1)**p * comb(N, p) * perm(M - p, N - p)
    ans %= mod
ans *= perm(M, N)
ans %= mod
print(ans)


MOD = 10**9 + 7
MAX = 5*10**5 + 1

fact = [0 for _ in range(MAX)]
factinv = [0 for _ in range(MAX)]

fact[0] = 1
for k in range(1, MAX):
    fact[k] = fact[k - 1]*k
    fact[k] %= MOD

factinv[MAX - 1] = pow(fact[MAX - 1], MOD - 2, MOD)
for k in range(MAX - 1, 0, -1):
    factinv[k - 1] = factinv[k]*k
    factinv[k - 1] %= MOD

def nCk(n, k):
    return fact[n]*factinv[k]*factinv[n - k] % MOD

def nPk(n, k):
    return fact[n]*factinv[n - k] % MOD

n, m = map(int, input().split(' '))

ans = 0
for k in range(n + 1):
    tmp = nCk(n, k)*nPk(m, k)*nPk(m - k, n - k)*nPk(m - k, n - k) % MOD
    if not k % 2: ans += tmp
    else: ans -= tmp
    ans %= MOD

print(ans)

n, m = [int(x) for x in input().split(" ")]
MOD = int(1e9 + 7)


fact = [0 for _ in range(m + 1)]
fact[0] = 1
for i in range(1, m + 1):
    fact[i] = fact[i-1] * i % MOD

finv = [0 for _ in range(m + 1)]
finv[m] = pow(fact[m], MOD-2, MOD)
for i in range(m-1, -1, -1):
    finv[i] = finv[i+1] * (i + 1) % MOD

def nCk(n, k):
    return fact[n] * finv[k] * finv[n-k] % MOD

def nPk(n, k):
    return fact[n] * finv[n-k] % MOD

ans = 0
for k in range(0, n + 1):
    tmp = nCk(n, k) * nPk(m, k) * (nPk(m-k, n-k) ** 2)
    if k % 2 == 0:
        ans += tmp
    else:
        ans -= tmp
    ans = ans % MOD

print(ans)



import sys
input=sys.stdin.readline
sys.setrecursionlimit(10 ** 8)
from itertools import accumulate
from itertools import permutations
from itertools import combinations
from collections import defaultdict
from collections import Counter
import fractions
import math
from collections import deque
from bisect import bisect_left
from bisect import bisect_right
from bisect import insort_left
import itertools
from heapq import heapify
from heapq import heappop
from heapq import heappush
import heapq
from copy import deepcopy
from decimal import Decimal
alf = list("abcdefghijklmnopqrstuvwxyz")
ALF = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
#import numpy as np
INF = float("inf")
#d = defaultdict(int)
#d = defaultdict(list)
N,M = list(map(int,input().split()))
fac = [1, 1]
inv = [0, 1]
finv = [1, 1]
MOD = 10**9+7
for i in range(2, M+2):
    fac.append(fac[-1] * i % MOD)
    inv.append(MOD - inv[MOD%i] * (MOD//i) % MOD)
    finv.append(finv[-1] * inv[-1] % MOD) 
def comb_mod(n, r, m):  #nCr mod m
    if (n<0 or r<0 or n<r): return 0
    r = min(r, n-r)
    return fac[n] * finv[n-r] * finv[r] % m

def chofuku(n,r): # nHr mod MOD の計算
    return comb_mod(n+r-1,r)
 
def nPr(n,r,m): #nPr mod MOD の計算
    return fac[n]*finv[n-r]%m
ans = 0
for i in range(1,N+1):
    if i % 2 == 1:
        flag = 1
    else:
        flag = -1
    s = flag*comb_mod(N,i,MOD)*nPr(M-i,N-i,MOD)
    ans += s
    if ans > MOD:
        ans %= MOD
ans1 = 1
for i in range(N):
    ans1 *= (M-i)
    ans1 %= MOD
ans2 = (ans1*ans1)%MOD
ans3 = (ans*nPr(M,N,MOD)) %MOD
print(((ans2-ans3)%MOD))


def cmb(n, r, p):
    if (r < 0) or (n < r):
        return 0
    r = min(r, n - r)
    return fact[n] * factinv[r] * factinv[n-r] % p

def per(n, r, p):
    if r < 0 or n < r:
        return 0
    return fact[n] * factinv[n-r] % p

p = 10 ** 9 + 7#mod
N = 5*pow(10, 5)  # N は必要分だけ用意する。大体問題設定のオーダーに合わせる(N >= max(n, r)。上のcmb関数のリスト同士の掛け算において、fact[n], factinv[r]を参照するため)
fact = [1, 1]
factinv = [1, 1]
inv = [0, 1]
 
for i in range(2, N + 1):
    fact.append((fact[-1] * i) % p)
    inv.append((-inv[p % i] * (p // i)) % p)
    factinv.append((factinv[-1] * inv[-1]) % p)

n, m = map(int, input().split())
ans = 0
for i in range(n+1):
    ans += pow(per(m-i, n-i, p), 2) * per(m, i, p) * cmb(n, i, p) * (-1)**i % p
ans = ans % p
print(ans)

n,m=map(int,input().split())
M,F=10**9+7,[1]
for i in range(m): F+=[-~i*F[i]%M]
print(sum((-1)**k*F[m-k]*pow(F[k]*F[n-k]*F[m-n]**2,-1,M) for k in range(n+1))*F[n]*F[m]%M)

#写経
#https://atcoder.jp/contests/abc172/submissions/14794920

MOD = 10**9 + 7

def resolve():
    N,M = map(int,input().split())
    a = 1
    d = [1]
    for i in range(N):
        d.append(((M-N+i)*d[i]+i*d[i-1])%MOD)
        a=a*(M-i)%MOD
    print(a*d[-1]%MOD)
resolve()


def factorials_with_inv(k,mod):
    """
    0! ... k! とそれらのmod逆元を求めて返す
    """
    fac = [1]*(k+1)
    inv = [1]*(k+1)
    t = 1
    for i in range(1,k+1):
        t *= i
        t %= mod
        fac[i] = t

    t = pow(t,-1,mod)
    for i in reversed(range(1,k+1)):
        inv[i] = t
        t *= i
        t %= mod

    return fac, inv

MOD = 10**9+7

def solve(N,M):
    fac,inv = factorials_with_inv(max(N,M), MOD)

    # (M-k)!/(k!(N-k)!) * N!M!/((M-N)!^2)

    res = 0
    sign = True
    for k in range(N+1):
        t = fac[M-k]*inv[k]*inv[N-k]
        if sign:
            res += t
        else:
            res -= t
        res %= MOD
        sign = not sign

    res *= fac[N]*fac[M]*inv[M-N]**2
    res %= MOD
    return res

from itertools import permutations

def naive(N,M):
    res = 0
    for A in permutations(range(M),N):
        for B in permutations(range(M),N):
            res += all(a != b for a,b in zip(A,B))
    return res%MOD

def __starting_point():
    N,M = map(int,input().split())

    # print(naive(N,M))
    print(solve(N,M))
__starting_point()

n, m = map(int, input().split())
mod = 10**9+7
nums = 5*(10**5) # 制約に合わせよう

g1, g2, inverse = [1, 1] , [1, 1], [0, 1]
 
for num in range(2, nums + 1):
    g1.append((g1[-1] * num) % mod)
    inverse.append((-inverse[mod % num] * (mod//num)) % mod)
    g2.append((g2[-1] * inverse[-1]) % mod)
    
def nPr(n, r):
    return g1[n] * g2[n-r] % mod

def nCr(n, r):
    return g1[n] * g2[r] * g2[n-r] % mod

ans = 0
for r in range(n+1):
    tmp = nCr(n, r)*nPr(m, r)*(nPr(m-r, n-r)**2)%mod
    ans = (ans+(-1)**r*tmp)%mod
print(ans)

from functools import lru_cache

class Combination:
    def __init__(self, size):
        self.size = size + 2
        self.fact = [1, 1] + [0] * size
        self.factInv = [1, 1] + [0] * size
        self.inv = [0, 1] + [0] * size

        for i in range(2, self.size):
            self.fact[i] = self.fact[i - 1] * i % MOD
            self.inv[i] = -self.inv[MOD % i] * (MOD // i) % MOD
            self.factInv[i] = self.factInv[i - 1] * self.inv[i] % MOD

    def npr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * self.factInv[n - r] % MOD

    def ncr(self, n, r):
        if n < r or n < 0 or r < 0:
            return 0
        return self.fact[n] * (self.factInv[r] * self.factInv[n - r] % MOD) % MOD

    def nhr(self, n, r):  # 重複組合せ: x_1 + ... + x_n = r
        return self.ncr(n + r - 1, n - 1)

N, M = list(map(int, input().split()))
MOD = 10**9 + 7
comb = Combination(M + 100)

ans = 0
for k in range(N + 1):
    ans += comb.ncr(N, k) * ((-1)**k) * comb.npr(M, k) * (comb.npr(M - k, N - k)**2)
    ans %= MOD
print(ans)


n, m = list(map(int, input().split()))

N = m + 100
MOD = 10 ** 9 + 7
fact = [0 for _ in range(N)]
invfact = [0 for _ in range(N)]
fact[0] = 1
for i in range(1, N):
    fact[i] = i * fact[i - 1] % MOD

invfact[N - 1] = pow(fact[N - 1], MOD - 2, MOD)

for i in range(N - 2, -1, -1):
    invfact[i] = invfact[i + 1] * (i + 1) % MOD
    
def nCk(n, k):
    if k < 0 or n < k:
        return 0
    else:
        return fact[n] * invfact[k] * invfact[n - k] % MOD
        
def nPk(n, k):
    return fact[n] * invfact[n - k] % MOD
    
ans = 0
sign = 1

for i in range(n + 1):
    ans = (ans + nPk(m, i) * nCk(n, i) * nPk(m - i, n - i) ** 2 * sign) % MOD
    sign *= -1
    
print(ans)
    


n,m=list(map(int,input().split()))
a,M,d=1,10**9+7,[1]*(n+1)
for i in range(n):
  d[i+1]=((m-n+i)*d[i]+i*d[i-1])%M
  a=a*(m-i)%M
print((a*d[-1]%M))


n,m=map(int,input().split())
i=b=0
a=1
while i<n:a,b,i=((m-i)*((m-n+i)*a+i*(m-i+1)*b))%(10**9+7),a,i+1
print(a)

class Factorial:
    def __init__(self, n, mod):
        self.f = [1]
        self.mod = mod
        for j in range(1, n + 1):
            self.f.append(self.f[-1] * j % mod)
        self.i = [pow(self.f[-1], mod - 2, mod)]
        for j in range(n, 0, -1):
            self.i.append(self.i[-1] * j % mod)
        self.i.reverse()
    def factorial(self, j):
        return self.f[j]
    def ifactorial(self, j):
        return self.i[j]
    def comb(self, n, k):
        return self.f[n] * self.i[n - k] % self.mod * self.i[k] % self.mod if n >= k else 0


N, M = map(int, input().split())

MOD = 10 ** 9 + 7

F = Factorial(M + 1, MOD)

ans = 0
for k in range(N + 1):
    tmp1 = F.comb(N, k)
    tmp2 = (F.factorial(M) * F.ifactorial(M - k)) % MOD
    tmp3 = ((F.factorial(M - k) * F.ifactorial(M - N))) ** 2 % MOD
    tmp = (tmp1 * tmp2 * tmp3) % MOD
    if k % 2 == 0:
        ans += tmp
    else:
        ans -= tmp
    ans %= MOD

print (ans)

n,m = list(map(int,input().split()))
mod = 10**9+7 #出力の制限
import math

def perm(n, r):
    ''' nPr % mod '''
    if r > n:
        return 0
    return g1[n] * g2[n-r] % mod

def cmb(n, r, mod):
    if ( r<0 or r>n ):
        return 0
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod

N = 5 * 10**5
g1 = [1, 1] # 元テーブル
g2 = [1, 1] #逆元テーブル
inverse = [0, 1] #逆元テーブル計算用テーブル

for i in range( 2, N + 1 ):
    g1.append( ( g1[-1] * i ) % mod )
    inverse.append( ( -inverse[mod % i] * (mod//i) ) % mod )
    g2.append( (g2[-1] * inverse[-1]) % mod )

ans = 0
for k in range(n+1):
    a = cmb(n,k,mod)
    p1 = perm(m,k)
    p2 = perm(m-k, n-k)
    ans += (a * (-1)**k * p1 * p2**2)

print(ans%mod)

class Factorials:
    def __init__(self, n, mod):
        self.mod = mod

        # self.fac[i] ≡ i! (factorial:階乗)
        self.fac = [1]
        num = 1
        for i in range(1, n+1):
            num *= i
            num %= mod
            self.fac.append(num)

        # self.rec[i] ≡ 1 / i! (reciprocal:逆数)
        num = pow(num, mod-2, mod)
        self.rec = [1 for i in range(n+1)]
        self.rec[n] = num
        for i in range(n-1, 0, -1):
            num *= i + 1
            num %= mod
            self.rec[i] = num

    # comb(n, r) ≡ nCr
    def comb(self, n, r):
        return self.fac[n] * self.rec[r] * self.rec[n - r] % self.mod
    
    # perm(n, r) ≡ nPr
    def perm(self, n, r):
        return self.fac[n] * self.rec[n-r] % self.mod

def main():
    n, m = map(int, input().split())
    mod = 10**9 + 7

    f = Factorials(m, mod)

    ans = 0
    for i in range(n+1):
        if i % 2 == 0:
            ans += f.comb(n, i) * f.perm(m, i) * f.perm(m-i, n-i) * f.perm(m-i, n-i) % mod
        else:
            ans -= f.comb(n, i) * f.perm(m, i) * f.perm(m-i, n-i) * f.perm(m-i, n-i) % mod
        ans %= mod

    print(ans)

main()

import math
MOD = 10 ** 9 + 7

fact = [1, 1]
factinv = [1, 1]
inv = [0, 1]

def init(n):
    for i in range(2, n + 1):
        fact.append((fact[-1] * i) % MOD)
        inv.append((-inv[MOD % i] * (MOD // i)) % MOD)
        factinv.append((factinv[-1] * inv[-1]) % MOD)

def nPk(n, k):
    return fact[n] * factinv[n - k] % MOD

def nCk(n, k):
    return fact[n] * factinv[n - k] * factinv[k] % MOD

N, M = list(map(int, input().split()))
init(M)
ans = 0
for k in range(N + 1):
    if k % 2 == 0:
        ans += nCk(N, k) * nPk(M - k, N - k)
    else:
        ans -= nCk(N, k) * nPk(M - k, N - k)
    ans = (ans + MOD) % MOD
ans *= nPk(M, N)
ans %= MOD
print(ans)


MOD = 10**9+7
n, m = list(map(int, input().split()))

U = max(n, m)
fact = [0]*(U+1)
fact[0] = 1
for i in range(1, U+1):
    fact[i] = fact[i-1]*i % MOD


invfact = [0]*(U+1)
invfact[U] = pow(fact[U], MOD-2, MOD)
for i in reversed(list(range(U))):
    invfact[i] = invfact[i+1]*(i+1) % MOD


def nCr(n, r):
    if r < 0 or n < r:
        return 0
    return fact[n]*invfact[r]*invfact[n-r]


def nPr(n, r):
    return fact[n]*invfact[n-r]


ans = 0
for k in range(n+1):
    tmp = nCr(n, k)*nPr(m, n)*nPr(m-k, n-k)
    if k % 2 == 0:
        ans += tmp
    else:
        ans -= tmp
    ans %= MOD
print(ans)


import sys 
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
mod = 10**9+7
N, M = map(int, readline().split())

fact = [1] * (M+1)
fact_inv = [1] * (M+1)
for i in range(1,M+1):
    fact[i] = fact[i-1] * i % mod 
fact_inv[M] = pow(fact[M],mod-2,mod)
for i in range(M,0,-1):
    fact_inv[i-1] = (i * fact_inv[i]) % mod 

def comb(n,r):
  return fact[n] * fact_inv[r] * fact_inv[n-r] % mod
total = 0
for k in range(N+1):
    a = fact[M-k] * fact_inv[M-N] * comb(N,k) % mod
    if k % 2 == 0:
        total += a
    else:
        total -= a
ans = (comb(M,N) * fact[N]) % mod * total 
print(ans%mod)

MOD = 10**9 + 7
fac = [1,1] # 階乗 n!
inv = [0,1] # 逆元 1/n
finv = [1,1] # 逆元の階乗 (n^-1)! = (1/n)!

def finv_init(n, m):
    for i in range(2, n+1):
        fac.append( (fac[-1] * i ) % m )
        inv.append( (-inv[m%i] * (m//i)) % m )
        finv.append( (finv[-1] * inv[-1]) % m )

def nPr(n, r, m): return fac[n] * finv[n-r]

n, m = list(map(int, input().split()))
finv_init(m, MOD)
ans = 0
for d in range(0, n+1):
    a = nPr(m-d, n-d, MOD) * nPr(n, d, MOD) * finv[d] % MOD
    if d & 1: a = -a
    ans += a; ans %= MOD
ans *= nPr(m, n, MOD)
print((ans % MOD))


N,M = map(int,input().split())
mod = 10**9 + 7
leng = 500010
fac = [1,1]
for i in range(2,500010):
    fac.append(fac[-1]*i%mod)

invfac = [0]*500010
invfac[500009] = pow(fac[500009],-1,mod)
for i in range(500009):
    invfac[500008-i] = invfac[500009-i]*(500009-i)%mod

def combi(n,m):
    return(fac[n]*invfac[m]*invfac[n-m]%mod)

def permu(n,m):
    return(fac[n]*invfac[n-m]%mod)

Ans = 0

for i in range(N+1):
    if i%2 == 0:
        Ans += combi(N,i)*permu(M,i)*(permu(M-i,N-i)**2)
    else:
        Ans -= combi(N,i)*permu(M,i)*(permu(M-i,N-i)**2)

print(Ans%mod)

SIZE=5*10**5+1; MOD=10**9+7 #998244353 #ここを変更する
 
SIZE += 1
inv = [0]*SIZE  # inv[j] = j^{-1} mod MOD
fac = [0]*SIZE  # fac[j] = j! mod MOD
finv = [0]*SIZE # finv[j] = (j!)^{-1} mod MOD
inv[1] = 1
fac[0] = fac[1] = 1
finv[0] = finv[1] = 1
for i in range(2,SIZE):
    inv[i] = MOD - (MOD//i)*inv[MOD%i]%MOD
    fac[i] = fac[i-1]*i%MOD
    finv[i]= finv[i-1]*inv[i]%MOD
 
def choose(n,r): # nCr mod MOD の計算
    if 0 <= r <= n:
        return (fac[n]*finv[r]%MOD)*finv[n-r]%MOD
    else:
        return 0
 
def chofuku(n,r): # nHr mod MOD の計算
    return choose(n+r-1,r)

def narabekae(n,r): #nPr mod MOD の計算
    return fac[n]*finv[n-r]%MOD


N,M=list(map(int,input().split()))
ans=0
for k in range(N+1):
    ans+=choose(N,k)*narabekae(M-k,N-k)*(-1 if k%2==1 else 1)
    ans%=MOD
ans*=narabekae(M,N)
print((ans%MOD))


import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

def fact_table(N, mod):
    inv = np.empty(N, np.int64)
    inv[0] = 0
    inv[1] = 1

    for n in range(2,N):
        q, r = divmod(mod, n)
        inv[n] = inv[r] * (-q) % mod

    fact = np.empty(N, np.int64)
    fact[0] = 1
    for n in range(1,N):
        fact[n] = n * fact[n-1] % mod
    fact_inv = np.empty(N, np.int64)
    fact_inv[0] = 1
    for n in range(1,N):
        fact_inv[n] = fact_inv[n-1] * inv[n] % mod
    return fact, fact_inv, inv

def main():
    n, m = list(map(int, readline().split()))
    mod = 10**9 + 7
    fact, fact_inv, inv = fact_table(n+1, mod)
    comb = fact[n] * fact_inv % mod * fact_inv[::-1] % mod
    comb[1::2] *= (-1)
    comb = comb[::-1]

    p = 1
    ans = 0
    for k in range(n+1):
        ans += comb[k] * p % mod
        if k != n:
            p = p * (m-n+1+k)%mod
    ans %= mod
    print(( p * ans % mod ))
    return

main()



import sys
input=sys.stdin.readline
sys.setrecursionlimit(10 ** 8)
from itertools import accumulate
from itertools import permutations
from itertools import combinations
from collections import defaultdict
from collections import Counter
import fractions
import math
from collections import deque
from bisect import bisect_left
from bisect import bisect_right
from bisect import insort_left
import itertools
from heapq import heapify
from heapq import heappop
from heapq import heappush
import heapq
from copy import deepcopy
from decimal import Decimal
alf = list("abcdefghijklmnopqrstuvwxyz")
ALF = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
#import numpy as np
INF = float("inf")
#d = defaultdict(int)
#d = defaultdict(list)
N,M = list(map(int,input().split()))
fac = [1, 1]
inv = [0, 1]
finv = [1, 1]
MOD = 10**9+7
fac = [1, 1]
inv = [0, 1]
finv = [1, 1]
for i in range(2, M+1):
    fac.append(fac[-1] * i % MOD)
    inv.append(MOD - inv[MOD%i] * (MOD//i) % MOD)
    finv.append(finv[-1] * inv[-1] % MOD) 
def comb_mod(n, r, m):  #nCr mod m
    if (n<0 or r<0 or n<r): return 0
    r = min(r, n-r)
    return fac[n] * finv[n-r] * finv[r] % m

def chofuku(n,r): # nHr mod MOD の計算
    return comb_mod(n+r-1,r)
 
def nPr(n,r,m): #nPr mod m の計算
    return fac[n]*finv[n-r]%m
ans = 0
for i in range(1,N+1):
    if i % 2 == 1:
        flag = 1
    else:
        flag = -1
    s = flag*comb_mod(N,i,MOD)*nPr(M-i,N-i,MOD)
    ans += s
    if ans > MOD:
        ans %= MOD
ans1 = 1
for i in range(N):
    ans1 *= (M-i)
    ans1 %= MOD
ans2 = (ans1*ans1)%MOD
ans3 = (ans*nPr(M,N,MOD)) %MOD
print(((ans2-ans3)%MOD))


mod=10**9+7
n=10**6
inv_t=[0]+[1]
for i in range(2,n):
  inv_t+=[inv_t[mod%i]*(mod-int(mod/i))%mod]

kai=[1,1]
rev_kai=[1,inv_t[1]]
for i in range(2,n):
  kai.append(kai[-1]*i%mod)
  rev_kai.append(rev_kai[-1]*inv_t[i]%mod)

def cmb(n,r):
  return kai[n]*rev_kai[r]*rev_kai[n-r]%mod

def prm(n,r):
  return kai[n]*rev_kai[n-r]%mod

N,M=map(int, input().split())
def f(x):
  e=cmb(N,x)*prm(M,x)*prm(M-x,N-x)*prm(M-x,N-x)
  e%=mod
  return e

ans=0
for i in range(N+1):
  g=f(i)*((-1)**i)
  ans+=g
print(ans%mod)

n,m=map(int,input().split())
i,d=0,[1]*(n+1)
while i<n:d[i+1]=((m-i)*((m-n+i)*d[i]+i*d[i-1]*(m-i+1)))%(10**9+7);i+=1
print(d[-1])

'''
Let g(x) = 序列內數字唯一，且最多 x 個位置不同。
Let f(x) = 序列內數字唯一，且給定 x 個位置時，使這些位置不同的方法數。

題目所求是 C(N, N) f(N)。

其中 g(x) 代表有至少 N - x 個位置是相同。可以分三個部份填數字，注意順序會影響，所以要乘上全排序：
(1) N - x 個位置（數字必需相同）：C(M, N - x) * (N - x)! = P(M, N - x)
(2) 序列 A 其餘位置（可以隨便填，但不能用到 (1) 的數字）：C(M - (N - x), x) * x! = P(M - (N - x), x)
(3) 序列 B 其餘位置（可以隨便填，但不能用到 (1) 的數字）：C(M - (N - x), x) * x! = P(M - (N - x), x)
g(x) = (1) * (2) * (3)

g(x) 是「選定 0 個位置，使這些位置不同的方法數」、「選定 1 個位置，使這些位置不同的方法數」、…、「選定 N 個位置，使這些位置不同的方法數」，即

g(x) = C(x, 0) f(0) + C(x, 1) f(1) + ... + C(x, x) f(x)
     = sum( C(x, i) * f(i) for i in [0, x] )
根據二項式反演，得到
f(x) = sum( (-1) ** (x - i) * C(x, i) * g(i) for i in [0, x] )
'''

class CombMod:
    def __init__(self, V, p):
        self.fact = [1] * V
        self.finv = [1] * V
        for i in range(1, V):
            self.fact[i] = self.fact[i - 1] * i % p
        self.finv[-1] = pow(self.fact[-1], p - 2, p)
        for i in range(V - 2, 0, -1):
            self.finv[i] = self.finv[i + 1] * (i + 1) % p
        self.p = p
        
    def fact(self, a):
        return self.fact[a]
    
    def finv(self, a):
        return self.finv[a]

    def comb(self, a, b):
        return self.fact[a] * self.finv[b] % self.p * self.finv[a - b] % self.p
        
    def perm(self, a, b):
        return self.fact[a] * self.finv[a - b] % self.p
    
    def hcomb(self, a, b):
        return self.comb(a + b - 1, b)


N, M = list(map(int, input().split()))
mod = 10**9 + 7
tool = CombMod(max(N, M) + 10, mod)

f_N = 0
for i in range(0, N + 1):
    p1 = tool.perm(M, N - i)
    p2 = tool.perm(M - (N - i), i)
    g_i = p1 * p2 % mod * p2 % mod
    val = (-1)**((N - i) % 2) * tool.comb(N, i) % mod * g_i % mod
    f_N = (f_N + val) % mod
ans = tool.comb(N, N) * f_N % mod
print(ans)


n, m = map(int, input().split())
mod = 10**9+7
nums = 5*(10**5) # 制約に合わせよう
 
g1, g2, inverse = [1, 1] , [1, 1], [0, 1]
 
for num in range(2, nums + 1):
    g1.append((g1[-1] * num) % mod)
    inverse.append((-inverse[mod % num] * (mod//num)) % mod)
    g2.append((g2[-1] * inverse[-1]) % mod)
    
def nPr(n, r):
    return g1[n] * g2[n-r] % mod
 
def nCr(n, r):
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod
 
ans = 0
for r in range(n+1):
    tmp = nCr(n, r)*nPr(m, r)*(nPr(m-r, n-r)**2)%mod
    ans = (ans+(-1)**r*tmp)%mod
print(ans)

MAX = 5 * (10**5)
MOD = 10**9 + 7

_fact = [1,1] + [0] * MAX
_inv = [0,1] + [0] * MAX
_fact_inv = [1,1] + [0] * MAX
for k in range(2, MAX + 1):
    _fact[k] = _fact[k-1] * k % MOD
    _inv[k] = (-_inv[MOD % k] * (MOD // k)) % MOD
    _fact_inv[k] = _fact_inv[k-1] * _inv[k] % MOD

def P(m, n):
    return _fact[m] * _fact_inv[m-n] % MOD

def C(m, n):
    return _fact[m] * _fact_inv[m-n] * _fact_inv[n] % MOD

def solve(n, m):
    res = 0
    for k in range(n+1):
        sign = 1 - 2 * (k%2)
        cur = sign * C(n, k) * P(m, k) * (P(m-k, n-k) ** 2)
        res = (res + cur) % MOD
    return res

n, m = map(int, input().split())
print(solve(n, m))

MOD = 1000000007
class mint:
    def __init__(self,x=0):
        self.x = x % MOD
    def __str__(self):
        return str(self.x)

    __repr__ = __str__

    def __add__(self, other):
        return(
            mint(self.x + other.x) if isinstance(other, mint) else mint(self.x + other)
        )

    def __sub__(self, other):
        return(
            mint(self.x - other.x) if isinstance(other, mint) else mint(self.x - other)
        )
    
    def __mul__(self, other):
        return(
            mint(self.x * other.x) if isinstance(other, mint) else mint(self.x * other)
        )

    def __truediv__(self, other):
        return(
            mint(self.x * pow(other.x, MOD - 2, MOD)) if isinstance(other, mint) else mint(self.x * pow(other, MOD - 2,MOD))
        )

    def __pow__(self, other):
        return(
            mint(pow(self.x, other.x, MOD)) if isinstance(other, mint) else mint(pow(self.x, other, MOD))
        )


    __radd__ = __add__

    def __rsub__(self, other):
        return (
            mint(other.x - self.x) if isinstance(other, mint) else mint(other - self.x)
        )

    __rmul__ = __mul__

    def __rtruediv__(self, other):
        return (
            mint(other.x * pow(self.x, MOD - 2, MOD)) if isinstance(other, mint) else mint(other * pow(self.x, MOD - 2, MOD))
        )

    def __rpow__(self, other):
        return (
            mint(pow(other.x, self.x, MOD)) if isinstance(other, mint) else mint(pow(other, self.x, MOD))
        )

MAX = 1000005
fac = [1,1]
finv = [1,1]
inv = [0,1]
def COMinit():
    for i in range(2,MAX):
        fac.append((fac[-1] * i) % MOD)
        inv.append((-inv[MOD%i] * (MOD//i)) % MOD)
        finv.append((finv[-1] * inv[-1]) % MOD)

def COM(n, k):
    if(n < k):
        return 0
    if(n < 0 or k < 0):
         return 0
    return fac[n] * finv[k] * finv[n-k] % MOD 

def P(n, k):
    return fac[n] * finv[n-k] % MOD 

N,M = map(int, input().split())
COMinit()
res = mint(0)
now = mint()
for i in range(N+1):
    now = COM(N, i)
    now *= P(M-i, N-i)
    if(i%2 == 1):
        now = -1 * now
    res += now
res *= P(M, N)
print(res)

n,m=map(int,input().split())
i=b=0
a=1
while i<n:c=((m-i)*((m-n+i)*a+(m-i+1)*i*b))%(10**9+7);i+=1;a,b=c,a
print(a)

N,M = map(int,input().split())
MOD = 10**9+7

MAXN = N+5
fac = [1,1] + [0]*MAXN
finv = [1,1] + [0]*MAXN
inv = [0,1] + [0]*MAXN
for i in range(2,MAXN+2):
    fac[i] = fac[i-1] * i % MOD
    inv[i] = -inv[MOD%i] * (MOD // i) % MOD
    finv[i] = finv[i-1] * inv[i] % MOD
def comb(n,r):
    if n < r: return 0
    if n < 0 or r < 0: return 0
    return fac[n] * (finv[r] * finv[n-r] % MOD) % MOD

ans = 1
for i in range(N):
    ans *= (M-i)
    ans %= MOD

ps = [1]
for i in range(N):
    ps.append((ps[-1] * (M-N+1+i)) % MOD)
ps.reverse()

tmp = 0
for i,p in enumerate(ps):
    t = p * comb(N,i)
    if i%2:
        t *= -1
    tmp += t

ans *= tmp
ans %= MOD
print(ans)

n,m=map(int,input().split())
a,M,d=1,10**9+7,[1]
for i in range(1,n+1):
  d.append(((m-n+i-1)*d[i-1]+(i-1)*d[i-2])%M)
  a=a*(m-i+1)%M
print(a*d[-1]%M)

# -*- coding: utf-8 -*-
#nCをp(=10**9+7)で割ったときのあまり(モジュラ逆数)
def cmb(n,r,p):
  if r<0 or n<r:
    return 0
  r=min(r,n-r)
  return facto[n]*factoinv[r]*factoinv[n-r]%p
p=10**9+7
n,m=map(int,input().split())
#0,1の時の値をいれたn!のリスト(modp)
facto=[1,1]
#0,1の時の値をいれたn!の逆元のリスト(modp)
factoinv=[1,1]
#0,1の場合を入れたn!の逆元も求めるために使うnの逆元のリスト(modp)
inv=[0,1]
#2からスタート
for i in range(2,m+1):
  facto.append((facto[-1]*i)%p)
  inv.append((-inv[p%i]*(p//i))%p)
  factoinv.append((factoinv[-1]*inv[-1])%p)
if n==m:
  kosuub=0
  for i in range(n+1):
    kosuub+=(facto[(n-i)]*cmb(n,i,p)*((-1)**i))%p
  kosuu=(kosuub*facto[(n)])%p
  print(kosuu)
else:
  kosuub=0
  for i in range(n+1):
    kosuub+=(cmb((m-i),(n-i),p)*facto[(n-i)]*cmb(n,i,p)*((-1)**i))%p
  kosuu=(kosuub*cmb(m,n,p)*facto[n])%p
  print(kosuu)

n, m = map(int, input().split())
mod = 10**9+7
nums = 5*(10**5) 
 
g1, g2, inverse = [1, 1] , [1, 1], [0, 1]
 
for num in range(2, nums + 1):
    g1.append((g1[-1] * num) % mod)
    inverse.append((-inverse[mod % num] * (mod//num)) % mod)
    g2.append((g2[-1] * inverse[-1]) % mod)
    
def nPr(n, r):
    return g1[n] * g2[n-r] % mod
 
def nCr(n, r):
    r = min(r, n-r)
    return g1[n] * g2[r] * g2[n-r] % mod
 
ans = 0
for r in range(n+1):
    tmp = nCr(n, r)*nPr(m, r)*(nPr(m-r, n-r)**2)%mod
    ans = (ans+(-1)**r*tmp)%mod
print(ans)

'''
Let g(x) = 序列內數字唯一，且最多 x 個位置不同。
Let f(x) = 序列內數字唯一，且給定 x 個位置時，使這些位置不同的方法數。

題目所求是 C(N, N) f(N)。

其中 g(x) 代表有至少 N - x 個位置是相同。可以分三個部份填數字，注意順序會影響，所以要乘上全排序：
(1) N - x 個位置（數字必需相同）：C(M, N - x) * (N - x)! = P(M, N - x)
(2) 序列 A 其餘位置（可以隨便填，但不能用到 (1) 的數字）：C(M - (N - x), x) * x! = P(M - (N - x), x)
(3) 序列 B 其餘位置（可以隨便填，但不能用到 (1) 的數字）：C(M - (N - x), x) * x! = P(M - (N - x), x)
g(x) = (1) * (2) * (3)

g(x) 是「選定 0 個位置，使這些位置不同的方法數」、「選定 1 個位置，使這些位置不同的方法數」、…、「選定 x 個位置，使這些位置不同的方法數」，即
g(x) = C(x, 0) f(0) + C(x, 1) f(1) + ... + C(x, x) f(x)
     = sum( C(x, i) * f(i) for i in [0, x] )
根據二項式反演，得到
f(x) = sum( (-1) ** (x - i) * C(x, i) * g(i) for i in [0, x] )
'''

class CombMod:
    def __init__(self, V, p):
        self.fact = [1] * V
        self.finv = [1] * V
        for i in range(1, V):
            self.fact[i] = self.fact[i - 1] * i % p
        self.finv[-1] = pow(self.fact[-1], p - 2, p)
        for i in range(V - 2, 0, -1):
            self.finv[i] = self.finv[i + 1] * (i + 1) % p
        self.p = p
        
    def fact(self, a):
        return self.fact[a]
    
    def finv(self, a):
        return self.finv[a]

    def comb(self, a, b):
        return self.fact[a] * self.finv[b] % self.p * self.finv[a - b] % self.p
        
    def perm(self, a, b):
        return self.fact[a] * self.finv[a - b] % self.p
    
    def hcomb(self, a, b):
        return self.comb(a + b - 1, b)


N, M = list(map(int, input().split()))
mod = 10**9 + 7
tool = CombMod(max(N, M) + 10, mod)

f_N = 0
for i in range(0, N + 1):
    p1 = tool.perm(M, N - i)
    p2 = tool.perm(M - (N - i), i)
    g_i = p1 * p2 % mod * p2 % mod
    val = (-1)**((N - i) % 2) * tool.comb(N, i) % mod * g_i % mod
    f_N = (f_N + val) % mod
ans = tool.comb(N, N) * f_N % mod
print(ans)


n, m = list(map(int, input().split()))

mod = 10 ** 9 + 7
N = 10 ** 6

#逆元テーブル
inv_t = [0]+[1]
for i in range(2, N):
    inv_t += [inv_t[mod % i] * (mod - int(mod / i)) % mod]

#階乗計算
kai = [1, 1]
rev_kai = [1, inv_t[1]]
for i in range(2, N):
    kai.append(kai[-1] * i % mod)
    rev_kai.append(rev_kai[-1] * inv_t[i] % mod)

# コンビネーション計算
def cmb(n, r):
    return kai[n] * rev_kai[r] * rev_kai[n-r] % mod

def prm(n, r):
    return kai[n] * rev_kai[n-r] % mod

ans = 0
tmp = 1

# 包除原理に従って場合の数を求める
for k in range(n+1):
    #　!(Ai != Bi)、つまり　Ai == Bi　という条件N個からK個選び
    # それらの条件の「かつ」の条件を満たす場合の数考える
    ans += tmp * cmb(n, k) * prm(m-k, n-k) % mod # KはAと一致するように決めて、残りのN-K箇所を自由に決める
    ans %= mod
    tmp *= -1

# Aの選び方をかける
ans *= prm(m, n)
ans %= mod

print(ans)



import sys

readline = sys.stdin.readline
readall = sys.stdin.read
ns = lambda: readline().rstrip()
ni = lambda: int(readline().rstrip())
nm = lambda: map(int, readline().split())
nl = lambda: list(map(int, readline().split()))
prn = lambda x: print(*x, sep='\n')

n_ = 5 * 10**5
mod = 10**9 + 7
fun = [1] * (n_ + 1)
for i in range(1, n_ + 1):
    fun[i] = fun[i - 1] * i % mod
rev = [1] * (n_ + 1)
rev[n_] = pow(fun[n_], mod - 2, mod)
for i in range(n_ - 1, 0, -1):
    rev[i] = rev[i + 1] * (i + 1) % mod

def nCr(n, r):
    if r > n:
        return 0
    return fun[n] * rev[r] % mod * rev[n - r] % mod

def modinv(x, mod):
    a, b = x, mod
    u, v = 1, 0
    while b:
        t = a // b
        a -= t * b; a, b = b, a
        u -= t * v; u, v = v, u
    return u % mod

def solve():
    n, m = nm()
    s = 0
    v = 1
    for i in range(n+1):
        s = (s + v * nCr(n, i) * nCr(m, i) * fun[i] % mod * (nCr(m-i, n-i) * fun[n-i] % mod)**2) % mod
        v *= -1
    print(s)
    return

solve()


n,m=map(int,input().split())
i,d=0,[1]*(n+1)
while i<n:
  d[i+1]=((m-i)*((m-n+i)*d[i]+i*d[i-1]*(m-i+1)))%(10**9+7);i+=1
print(d[-1])

#atcoder template
def main():
    import sys
    imput = sys.stdin.readline
    #文字列入力の時は上記はerrorとなる。
    #ここにコード
    #input
    n, m = list(map(int, input().split()))

    #output
    mod = pow(10, 9) + 7

    n_ = 5 * pow(10, 5) + 5
    fun = [1] * (n_+1)
    for i in range(1, n_+1):
        fun[i] = fun[i-1] * i % mod
    rev = [1] * (n_+1)
    rev[n_] = pow(fun[n_], mod-2, mod)
    for i in range(n_-1, 0, -1):
        rev[i] = rev[i+1] * (i+1) % mod
    def cmb(n,r):
        if n < 0 or r < 0 or r > n: return 0
        return fun[n] * rev[r] % mod * rev[n-r] % mod
    def perm(n, r):
        if n < 0 or r < 0 or r > n: return 0
        return fun[n] * rev[n-r] % mod

    #Aを1, 2, ..., nとする。
    #求める写像の総数をs(n, m)とする。
    #s(n, m) = sum(k=0, n)(cmb(n, k)* (-1)^k * cmb(m-k, n-k)*(n-k)!)

    import math
    answer = 0
    for i in range(n+1):
        temp = perm(n, i) * cmb(m, i) * pow(perm(m-i, n-i), 2)
        temp %= mod
        if i % 2 == 0:
            answer += temp
        else:
            answer -= temp
    print((answer % mod))

    #N = 1のときなどcorner caseを確認！
def __starting_point():
    main()

__starting_point()

n,m=map(int,input().split())
a,M,d=1,10**9+7,[1]
for i in range(n):
  d.append(((m-n+i)*d[i]+i*d[i-1])%M)
  a=a*(m-i)%M
print(a*d[-1]%M)

class Factorial:
    def __init__(self, max_fact, mod):
        #mod should be prime number
        #using homogeneous_product(n,r), max_fact ≧ max(n+r-1)
        f = [1] * (max_fact + 1)
        for idx in range(2, max_fact + 1):
            f[idx] = f[idx - 1] * idx
            f[idx] %= mod
        fi = [pow(f[-1], mod - 2, mod)]
        for idx in range(max_fact, 0, -1):
            fi += [fi[-1] * idx % mod]
        fi = fi[::-1]
        self.mod = mod
        self.f = f
        self.fi = fi

    def factorial(self, n):
        return self.f[n]

    def factorial_inverse(self, n):
        return self.fi[n]

    def combination(self, n, r):
        f = self.f
        fi = self.fi
        return f[n] * fi[r] * fi[n - r] % self.mod

    def permutation(self, n, r):
        return self.f[n] * self.fi[n - r] % self.mod

    def homogeneous_product(self, n, r):
        f = self.f
        fi = self.fi
        return f[n + r - 1] * fi[r] * fi[n - 1] % self.mod


max_fact = 10**6
mod = 10**9 + 7
fact_instance = Factorial(max_fact, mod)
comb = fact_instance.combination
perm = fact_instance.permutation

N, M = [int(_) for _ in input().split()]
ans = 0
for p in range(N + 1):
    ans += (-1)**p * comb(N, p) * perm(M - p, N - p)
    ans %= mod
ans *= perm(M, N)
ans %= mod
print(ans)


mod = pow(10,9)+7
n,m = map(int,input().split())
ans = 0
inv = [0,1]
fact = [1,1]
ifact = [1,1]
for i in range(2,m+1):
    inv.append(inv[mod%i]*(mod-int(mod/i))%mod)
    fact.append(i*fact[-1]%mod)
    ifact.append(ifact[-1]*inv[i]%mod)

def combi(a,b):
    return fact[a]*ifact[b]*ifact[a-b]%mod
def permi(a,b):
    return fact[a]*ifact[a-b]%mod

for i in range(n+1):
    now = combi(n,i)
    now *= permi(m-i,n-i)
    now %= mod
    ans += now*(-1)**(i&1)
    ans %= mod
ans *= permi(m,n)
ans %= mod
print(ans)

#test
class Combi():
    def __init__(self, N, mod):
        self.power = [1 for _ in range(N+1)]
        self.rev = [1 for _ in range(N+1)]
        self.mod = mod
        for i in range(2, N+1):
            self.power[i] = (self.power[i-1]*i) % self.mod
        self.rev[N] = pow(self.power[N], self.mod-2, self.mod)
        for j in range(N, 0, -1):
            self.rev[j-1] = (self.rev[j]*j) % self.mod

    def com(self, K, R):
        if K < R:
            return 0
        else:
            return ((self.power[K])*(self.rev[K-R])*(self.rev[R])) % self.mod

    def pom(self, K, R):
        if K < R:
            return 0
        else:
            return (self.power[K])*(self.rev[K-R]) % self.mod


def main():
    N, M = map(int, input().split())
    mod = 10**9+7
    c = Combi(5*10**5, mod)
    ans = c.pom(M, N)**2 % mod
    for k in range(1, N+1):
        s = (-1)**((k-1) % 2)
        t = c.com(N, k)
        u = c.pom(M-k, N-k)**2
        v = c.pom(M, k)
        ans -= s*t*u*v
        ans = ans % mod
    print(ans)


def __starting_point():
    main()
__starting_point()

MOD = 10**9 + 7
fac = [1,1] # 階乗 n!
inv = [0,1] # 逆元 1/n
finv = [1,1] # 逆元の階乗 (n^-1)! = (1/n)!

def finv_init(n, m):
    for i in range(2, n+1):
        fac.append( (fac[-1] * i ) % m )
        inv.append( (-inv[m%i] * (m//i)) % m )
        finv.append( (finv[-1] * inv[-1]) % m )

def nPr(n, r, m): return fac[n] * finv[n-r] % m

n, m = list(map(int, input().split()))
finv_init(m, MOD)
ans = 0
for d in range(0, n+1):
    a = nPr(m-d, n-d, MOD) * nPr(n, d, MOD) * finv[d] % MOD
    if d & 1: a = -a
    ans += a; ans %= MOD
ans *= nPr(m, n, MOD)
print((ans % MOD))


MOD = 10 ** 9 + 7
table_len = 500010

fac = [1, 1]
for i in range(2, table_len):
    fac.append(fac[-1] * i % MOD)
    
finv = [0] * table_len
finv[-1] = pow(fac[-1], MOD - 2, MOD)
for i in range(table_len-1, -1, -1):
    finv[i-1] = finv[i] * i % MOD

def comb(n, k):
    return fac[n] * finv[k] * finv[n-k] % MOD

def perm(n, k):
    return fac[n] * finv[n-k] % MOD

N, M = list(map(int, input().split()))

print((sum( ((-1)**k * comb(N, k) * perm(M, k) * perm(M-k, N-k)**2 % MOD ) for k in range(N+1)) % MOD))


n,m=map(int,input().split())
M,d=10**9+7,[1]*(n+1)
for i in range(n):
  d[i+1]=((m-i)*((m-n+i)*d[i]+i*d[i-1]*(m-i+1)))%M
print(d[-1])

# E - NEQ

N, M = map(int, input().split())
MOD = 10 ** 9 + 7

fac = [1, 1]
inv = [0, 1]
finv = [1, 1]

for i in range(2, M+1):
    fac.append(fac[-1] * i % MOD)
    inv.append(MOD - inv[MOD%i] * (MOD//i) % MOD)
    finv.append(finv[-1] * inv[-1] % MOD)

fixed = (fac[N] * fac[M] * pow(finv[M-N], 2, MOD)) % MOD

def f(k):
    return (fac[M-k] * finv[k] * finv[N-k]) % MOD

ans = 0
for i in range(N+1):
    ans = (ans + fixed * f(i) * pow(-1, i)) % MOD

print(ans)

import sys
input=sys.stdin.readline
sys.setrecursionlimit(10 ** 8)
from itertools import accumulate
from itertools import permutations
from itertools import combinations
from collections import defaultdict
from collections import Counter
import fractions
import math
from collections import deque
from bisect import bisect_left
from bisect import bisect_right
from bisect import insort_left
import itertools
from heapq import heapify
from heapq import heappop
from heapq import heappush
import heapq
from copy import deepcopy
from decimal import Decimal
alf = list("abcdefghijklmnopqrstuvwxyz")
ALF = list("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
#import numpy as np
INF = float("inf")
#d = defaultdict(int)
#d = defaultdict(list)
N,M = list(map(int,input().split()))
fac = [1, 1]
inv = [0, 1]
finv = [1, 1]
MOD = 10**9+7
fac = [1, 1]
inv = [0, 1]
finv = [1, 1]
for i in range(2, M+1):
    fac.append(fac[-1] * i % MOD)
    inv.append(MOD - inv[MOD%i] * (MOD//i) % MOD)
    finv.append(finv[-1] * inv[-1] % MOD) 
def comb_mod(n, r, m):  #nCr mod m
    if (n<0 or r<0 or n<r): return 0
    r = min(r, n-r)
    return fac[n] * finv[n-r] * finv[r] % m

def chofuku(n,r): # nHr mod MOD の計算
    return comb_mod(n+r-1,r)
 
def nPr(n,r,m): #nPr mod m の計算
    return fac[n]*finv[n-r]%m
ans = 0
for i in range(1,N+1):
    if i % 2 == 1:
        flag = 1
    else:
        flag = -1
    s = flag*comb_mod(N,i,MOD)*nPr(M-i,N-i,MOD)
    ans += s
    if ans > MOD:
        ans %= MOD
ans1 = 1
for i in range(N):
    ans1 *= (M-i)
    ans1 %= MOD
ans2 = (ans1*ans1)%MOD
ans3 = (ans*nPr(M,N,MOD)) %MOD
print(((ans2-ans3)%MOD))


n,m=map(int,input().split())
i=b=0
a=1
while i<n:a,b=((m-i)*((m-n+i)*a+i*(m-i+1)*b))%(10**9+7),a;i+=1
print(a)

MOD = 10**9 + 7

class Combinatorics:
    def __init__(self, N, mod):
        '''
        Preprocess for calculating binomial coefficients nCr (0 <= r <= n, 0 <= n <= N)
        over the finite field Z/(mod)Z.
        Input:
            N (int): maximum n
            mod (int): a prime number. The order of the field Z/(mod)Z over which nCr is calculated.
        '''
        self.mod = mod
        self.fact = [0] * (N+1)           # n!
        self.inverse = [None] + [0] * N   # inverse of n in the field Z/(MOD)Z
        self.fact_inverse = [0] * (N+1)   # inverse of n! in the field Z/(MOD)Z
        
        # preprocess
        self.fact[0] = self.fact[1] = 1
        self.fact_inverse[0] = self.fact_inverse[1] = 1
        self.inverse[1] = 1
        for i in range(2, N+1):
            self.fact[i] = i * self.fact[i-1] % self.mod
            q, r = divmod(self.mod, i)
            self.inverse[i] = (- (q % self.mod) * self.inverse[r]) % self.mod
            self.fact_inverse[i] = self.inverse[i] * self.fact_inverse[i-1] % self.mod
    
    def perm(self, n, r):
        '''
        Calculate nPr = n! / (n-r)! % mod
        '''
        if n < r or n < 0 or r < 0: return 0
        else: return (self.fact[n] * self.fact_inverse[n-r]) % self.mod
    
    def binom(self, n, r):
        '''
        Calculate nCr = n! /(r! (n-r)!) % mod
        '''
        if n < r or n < 0 or r < 0: return 0
        else: return self.fact[n] * (self.fact_inverse[r] * self.fact_inverse[n-r] % self.mod) % self.mod
        
    def hom(self, n, r):
        '''
        Calculate nHr = {n+r-1}Cr % mod.
        Assign r objects to one of n classes.
        Arrangement of r circles and n-1 partitions:
            o o o | o o | | | o | | | o o | | o
        '''
        if n == 0 and r > 0: return 0
        if n >= 0 and r == 0: return 1
        return self.binom(n + r - 1, r)

N, M = map(int, input().split())
com = Combinatorics(M, MOD)
ans = 0
for i in range(N+1):
    temp = com.perm(M, N)
    temp *= com.binom(N, i); temp %= MOD
    temp *= com.perm(M-i, N-i); temp %= MOD
    ans += ((-1)**i) * temp; ans %= MOD
print(ans)