using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("2 2");
//2
}
else if (InputPattern == "Input2") {
WillReturn.Add("2 3");
//18
}
else if (InputPattern == "Input3") {
WillReturn.Add("141421 356237");
//881613484
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
const long Hou = 1000000007;
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
long N = wkArr[0];
long M = wkArr[1];
var InsChooseMod = new ChooseMod(N, Hou);
long PatternA = Derive_nPr(M, N);
// 包除原理で解く
long PatternB = PatternA;
// 順列は、最初に計算し、次からは、逆元を掛けて求める
long? PrevVal = null;
long nPr = 0;
// 一致数でループ
for (long I = 1; I <= N; I++) {
long ChooseCnt = InsChooseMod.DeriveChoose(N, I);
long RestSpace = N - I;
if (PrevVal.HasValue == false) {
nPr = Derive_nPr(M - I, RestSpace);
}
else {
nPr *= DeriveGyakugen(PrevVal.Value);
nPr %= Hou;
}
PrevVal = M - I;
if (I % 2 == 1) {
PatternB -= (ChooseCnt * nPr) % Hou;
}
else {
PatternB += (ChooseCnt * nPr) % Hou;
}
PatternB %= Hou;
if (PatternB < 0) PatternB += Hou;
}
long Answer = PatternA * PatternB;
Answer %= Hou;
Console.WriteLine(Answer);
}
// nPr (mod Hou)を求める
static long Derive_nPr(long pN, long pR)
{
long WillReturn = 1;
for (long I = pN - pR + 1; I <= pN; I++) {
WillReturn *= I;
WillReturn %= Hou;
}
return WillReturn;
}
// 引数の逆元を求める
static long DeriveGyakugen(long pLong)
{
return DeriveBekijyou(pLong, Hou - 2, Hou);
}
// 繰り返し2乗法で、(NのP乗) Mod Mを求める
static long DeriveBekijyou(long pN, long pP, long pM)
{
long CurrJyousuu = pN % pM;
long CurrShisuu = 1;
long WillReturn = 1;
while (true) {
// 対象ビットが立っている場合
if ((pP & CurrShisuu) > 0) {
WillReturn = (WillReturn * CurrJyousuu) % pM;
}
CurrShisuu *= 2;
if (CurrShisuu > pP) return WillReturn;
CurrJyousuu = (CurrJyousuu * CurrJyousuu) % pM;
}
}
}
#region ChooseMod
// 二項係数クラス
internal class ChooseMod
{
private long mHou;
private long[] mFacArr;
private long[] mFacInvArr;
private long[] mInvArr;
// コンストラクタ
internal ChooseMod(long pCnt, long pHou)
{
mHou = pHou;
mFacArr = new long[pCnt + 1];
mFacInvArr = new long[pCnt + 1];
mInvArr = new long[pCnt + 1];
mFacArr[0] = mFacArr[1] = 1;
mFacInvArr[0] = mFacInvArr[1] = 1;
mInvArr[1] = 1;
for (int I = 2; I <= pCnt; I++) {
mFacArr[I] = mFacArr[I - 1] * I % mHou;
mInvArr[I] = mHou - mInvArr[mHou % I] * (mHou / I) % mHou;
mFacInvArr[I] = mFacInvArr[I - 1] * mInvArr[I] % mHou;
}
}
// nCrを返す
internal long DeriveChoose(long pN, long pR)
{
if (pN < pR) return 0;
if (pN < 0 || pR < 0) return 0;
return mFacArr[pN] * (mFacInvArr[pR] * mFacInvArr[pN - pR] % mHou) % mHou;
}
}
#endregion