#include<bits/stdc++.h>
using namespace std;
 
#define SPEED ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define MP make_pair
#define pb push_back
#define ff first
#define ss second
#define sz(x) x.size()
#define all(c) c.begin(),c.end()
//#define int long long
#define fr(i,j,x) for(int i=j;i<x;i++)
#define rep(i,j,x) for(int i=j;i<=x;i++)
#define mem(x,val) memset(x,val,sizeof(x))
//#define endl '\n'
#define vi vector<int>
#define ll long long
#define pii pair<int,int>
 
const int MOD=1e9+7;
const int N=5e5+10;
const int INF=1e9;

int a[N],ans,mid,lo,hi,n;
map<int,int>cnt;
map<int,vector<int>>mp;

struct mi {
    ll v; explicit operator ll() const { return v; }
    mi() { v = 0; }
    mi(ll _v) { 
        v = (-MOD < _v && _v < MOD) ? _v : _v % MOD;
        if (v < 0) v += MOD;
    }
    friend bool operator==(const mi& a, const mi& b) { 
        return a.v == b.v; }
    friend bool operator!=(const mi& a, const mi& b) { 
        return !(a == b); }
    friend bool operator<(const mi& a, const mi& b) { 
        return a.v < b.v; }
   
    mi& operator+=(const mi& m) { 
        if ((v += m.v) >= MOD) v -= MOD; 
        return *this; }
    mi& operator-=(const mi& m) { 
        if ((v -= m.v) < 0) v += MOD; 
        return *this; }
    mi& operator*=(const mi& m) { 
        v = v*m.v%MOD; return *this; }
    mi& operator/=(const mi& m) { return (*this) *= inv(m); }
    friend mi pow(mi a, ll p) {
        mi ans = 1; assert(p >= 0);
        for (; p; p /= 2, a *= a) if (p&1) ans *= a;
        return ans;
    }
    friend mi inv(const mi& a) { assert(a.v != 0); 
        return pow(a,MOD-2); }
        
    mi operator-() const { return mi(-v); }
    mi& operator++() { return *this += 1; }
    mi& operator--() { return *this -= 1; }
    mi operator++(int) { mi temp; temp.v = v++; return temp; }
    mi operator--(int) { mi temp; temp.v = v--; return temp; }
    friend mi operator+(mi a, const mi& b) { return a += b; }
    friend mi operator-(mi a, const mi& b) { return a -= b; }
    friend mi operator*(mi a, const mi& b) { return a *= b; }
    friend mi operator/(mi a, const mi& b) { return a /= b; }
    friend ostream& operator<<(ostream& os, const mi& m) {
        os << m.v; return os;
    }
    friend istream& operator>>(istream& is, mi& m) {
        ll x; is >> x;
        m.v = x;
        return is;
    }
};

mi fac[N],finv[N];

mi choose(mi _a,mi _b){
    ll a=(ll)_a,b=(ll)_b;
    if(b>a) return 0;
    if(a<0) return 0;
    if(b<0) return 0;
    mi cur=fac[a];
    cur=cur*finv[b];
    cur=cur*finv[a-b];
    return cur;
}

void init(){
    fac[0]=1;
    finv[0]=1;
    fr(i,1,N){
        fac[i]=(fac[i-1]*i);
        finv[i]=inv(fac[i]);
    }
}

void solve(){
    int n,m;
    cin>>n>>m;
    init();
    mi ans=0;
    mi cur=1;
    rep(i,0,n){
        ans+=cur*choose(n,i)*choose(m-i,n-i)*fac[n-i];
        cur=-cur;
    }
    cout<<ans*choose(m,n)*fac[n]<<endl;
}
int32_t main()
{
    // #ifndef ONLINE_JUDGE
    //     freopen("inputf.in", "r", stdin);
    //     //freopen("outputf.in", "w", stdout);
    // #endif
    SPEED;
    int T=1;
    //cin>>T;
    int t1=1;
    while(true)
    {  
        //cout<<"Case #"<<t1<<": ";
        solve();
        t1++;
        if(t1>T)
            break;
    }
}   

Measured memory_bytes: 11464