/*
AUTHOR: Aman Raj
LANG: C++
*/

using namespace std;

typedef   long long  int ll;
#include <bits/stdc++.h>


//setbase - cout << setbase (16); cout << 100 << endl; Prints 64
//setfill -   cout << setfill ('x') << setw (5); cout << 77 << endl; prints xxx77
//setprecision - cout << setprecision (14) << f << endl; Prints x.xxxx
//cout.precision(x)  cout<<fixed<<val;  // prints x digits after decimal in val
#define fast  ios_base::sync_with_stdio(false); cin.tie(0);  cout.tie(0);
#define all(a) a.begin(),a.end()
//#define mod 998244353


#define mod   1000000007

#define inf 1e18
//#define mod 3
#define flush fflush(stdout)

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef cc_hash_table<ll, ll, hash< ll > > ht;

// find_by_order()  // order_of_key
typedef tree<
    ll,
    null_type,
    less<ll>,
    rb_tree_tag,
    tree_order_statistics_node_update>
    ordered_set;






ll power1(ll a, ll b)//a raised to power b
   {  if(b<=0) return 1; if(b==1) return a;
       ll c=power1(a,b/2);
        c*=c;c%=mod;if(b%2==1) c*=a;c%=mod;
        return c;
   }
   ll mi(ll a,ll m)
   { ll c= power1(a,m-2);

     return c;
   }



 struct less_then_greater {
    template<typename T, typename U>
    bool operator()(T const& lhs, U const& rhs) const {
        if (lhs.first < rhs.first) return true;
        if (rhs.first < lhs.first) return false;
        return lhs.second > rhs.second;
    }
};
 /*std::priority_queue<std::pair<int, int>,
                    std::vector<std::pair<int, int>>,
                    less_then_greater
                   > pq;*/
  /*   #define MAXN 1000001
ll spf[MAXN];
void sieve()
{
    spf[1] = 1;
    for (int i=2; i<MAXN; i++)

        // marking smallest prime factor for every
        // number to be itself.
        spf[i] = i;

    // separately marking spf for every even
    // number as 2
    for (int i=4; i<MAXN; i+=2)
        spf[i] = 2;

    for (int i=3; i*i<MAXN; i++)
    {
        // checking if i is prime
        if (spf[i] == i)
        {
            // marking SPF for all numbers divisible by i
            for (int j=i*i; j<MAXN; j+=i)

                // marking spf[j] if it is not
                // previously marked
                if (spf[j]==j)
                    spf[j] = i;
        }
    }
}
vector<ll> getFactorization(ll x)
{
    vector<ll> ret;
    while (x != 1)
    {
        ret.push_back(spf[x]);
        x = x / spf[x];
    }
    return ret;
}
*/
// take multiset of all edges
// meanwhile for all cc keep record of all edges in multiset too which can be used to digest
// one line or two lines
//


  int main()
{    fast;

      ll n,m;cin>>n>>m;
        if(m<n){cout<<0<<endl;return 0;}
         vector<ll> dpfact(m+1);
           dpfact[0]=1;
            for(ll i=1;i<=m;i++){ dpfact[i]=i*dpfact[i-1];dpfact[i]%=mod;  }
         ll a=dpfact[m]*mi(dpfact[m-n],mod);  a%=mod;
         ll ans=a*a;ans%=mod;
          ll p=1;
           ll sub=0;

 //cout<<mi(2,mod)<<endl;
         for(ll i=1;i<=n;i++)
         {   ll a=((dpfact[n]*((mi(dpfact[n-i],mod)*mi(dpfact[i],mod))%mod))%mod);//if(i==2)cout<<a<<endl;
           a*=((dpfact[m]*mi(dpfact[m-i],mod))%mod);  a%=mod;
            //if(i==2)cout<<a<<endl;
            a*=((dpfact[m-i]*mi(dpfact[m-n],mod))%mod);  a%=mod;
            a*=((dpfact[m-i]*mi(dpfact[m-n],mod))%mod);a%=mod;
              sub+=p*(a);sub+=mod;sub%=mod;

             p*=-1;
         }
         ans=(ans-sub+mod)%mod;
          cout<<ans<<endl;
      return 0;
}


Measured memory_bytes: 7068