/*
Author : Hocky Yudhiono
6/27/2020 7:37:47 PM

1. You can sort the query if offline!
2. Don't bring the dp remaining state when dfsing on DP on Tree.
3. Try to reverse (Think from the back) if you stuck.
4. Be careful when submitting Div. 2 D-F, dont waste it on stupid WAs.
5. Try to reduce a problem
*/

#include <algorithm>
#include <iostream>
#include <numeric>
#include <cstdlib>
#include <cassert>
#include <cstring>
#include <iomanip>
#include <cstdio>
#include <limits>
#include <string>
#include <vector>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;

typedef long long LL;
typedef long long ll;
typedef long double LD;
typedef vector<int> vi;
typedef pair<LL,LL> PLL;
typedef pair<LL,int> PLI;
typedef pair<int,int> PII;
typedef pair<int,int> pii;
typedef vector<vector<LL>> VVL;

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define trav(a, x) for(auto& a : x)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
#define popf pop_front
#define pf push_front
#define popb pop_back
#define mp make_pair
#define pb push_back
#define remove erase
#define fi first
#define se second

// If the time limit is strict, try not to use long double

// Remember to undefine if the problem is interactive
#define endl '\n'
#define DEBUG(X) cout << ">>> DEBUG(" << __LINE__ << ") " << #X << " = " << (X) << endl

const double EPS = 1e-9;
const int INFMEM = 63;
const int INF = 1061109567;
const LL LINF = 4557430888798830399LL;
const double DINF = numeric_limits<double>::infinity();
const LL MOD = 1000000007;
const int dx[8] = {0,0,1,-1,1,-1,1,-1};
const int dy[8] = {1,-1,0,0,1,-1,-1,1};
// Do dir^1 to get reverse direction
const char dch[4] = {'R','L','D','U'};
// const string ds[8] = {"E","W","S","N","SE","NW","SW","NE"};
const double PI = 3.141592653589793;

inline void open(string a){
    freopen((a+".in").c_str(),"r",stdin);
    freopen((a+".out").c_str(),"w",stdout);
}

inline void fasterios(){
    // Do not use if interactive
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    // cout << fixed << setprecision(10);
}

LL n,m;
const int mxsz = 5e5 + 10;
const int MX = 5e5 + 1;
LL fact[mxsz], inv[mxsz], finv[mxsz];

inline void prec(LL mod = MOD){ // factorial / inverse
    fact[0] = inv[0] = finv[0] = 1;
    fact[1] = inv[1] = finv[1] = 1;
    for (int i = 2; i <= MX; i++){
        fact[i] = (fact[i-1] * i) % mod;
        inv[i] = mod - (mod/i) * inv[mod%i] % mod;
        finv[i] = (finv[i-1] * inv[i]) % mod;
    }
}

inline LL perm(LL a, LL b){
    return (fact[a]*finv[a-b])%MOD;
}

inline LL comb(LL a, LL b){
    if(a < b) return 0;
    return (perm(a,b)*finv[b])%MOD;
}

int main(){
    prec();
    cin >> n >> m;
    LL ans = 0;
    for(int i = 0;i <= n;i++){
        // Minus
        // Fix i thing
        // Pick i, and make same, give the rest good
        LL curans = comb(n,i)*perm(m,i)%MOD;
        // cout << "same " << curans << endl;
        curans = curans*perm(m-i,n-i)%MOD*perm(m-i,n-i)%MOD;
        curans = (i%2 == 0 ? 1 : -1)*curans;
        // cout << i << " " << curans << endl;
        ans += curans+MOD;
        ans %= MOD;
    }
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 15348