#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef vector<int> vi; 
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;

#define sz(a) int((a).size())
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define all(c) (c).begin(),(c).end()
#define rall(c) (c).rbegin(),(c).rend()
#define ini(a, i) memset(a, i, sizeof(a))
#define contains(c, i) ((c).find(i) != (c).end())
#define present(i, c) (find(all(c), i) != (c).end())

#define rep(i, n) for(int i = 0; i < n; i++)
#define repa(i, b, e) for(int i = (b)-((b)>(e)); i != (e)-((b)>(e)); i += 1-2*((b)>(e)))

#define dbg(x) cerr << #x << " = " << x << endl;
#define dbgall(x) cerr << #x << " = "; for(auto i_ : x) cerr << i_ << " "; cerr << endl;
#define debug(args...) { string s_(#args); replace(all(s_), ',', ' '); stringstream ss_(s_); istream_iterator<string> it_(ss_); cerr_(it_, args); }
void cerr_(istream_iterator<string> it) { (void) it; }
template<class T, class... Args> void cerr_(istream_iterator<string> it, T a, Args... args) { cerr << *it << " = " << a << endl; cerr_(++it, args...); }

template<class T, class S>  ostream& operator<<(ostream& os, const pair<T, S>& p) { os << "(" << p.first << ", " << p.second << ")"; return os; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep; for (const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }
template<class T> ostream& operator<<(ostream &os, const set<T> &s) { os << '{'; string sep; for (const auto &x : s) os << sep << x, sep = ", "; return os << '}'; }
template<class T, class S> ostream& operator<<(ostream &os, const map<T, S> &m) { os << '{'; string sep; for (const auto &x : m) os << sep << x, sep = ", "; return os << '}'; }
template<class T, size_t size> ostream& operator<<(ostream &os, const array<T, size> &arr) { os << '{'; string sep; for (const auto &x : arr) os << sep << x, sep = ", "; return os << '}'; }

//=========================

const int MOD = (int) 1e9 + 7;
const int MAXN = (int) 1e6;

struct modint {
	ll v; explicit operator ll() const { return v; }
	modint() { v = 0; }
	modint(ll _v) { v = (-MOD < _v && _v < MOD) ? _v : _v % MOD; if (v < 0) v += MOD; }
	friend bool operator==(const modint& a, const modint& b) { return a.v == b.v; }
	friend bool operator!=(const modint& a, const modint& b) { return !(a.v == b.v); }
	friend bool operator<(const modint& a, const modint& b) { return a.v < b.v; }
   	modint& operator+=(const modint& m) { if ((v += m.v) >= MOD) v -= MOD; return *this; }
	modint& operator-=(const modint& m) { if ((v -= m.v) < 0) v += MOD; return *this; }
	modint& operator*=(const modint& m) { v = (v * m.v)% MOD; return *this; }
	modint& operator/=(const modint& m) { return (*this) *= inv(m); }
	friend modint pow(modint a, ll p) { modint r = 1; for (; p; p /= 2, a *= a) if (p & 1) r *= a; return r; }
	friend modint inv(const modint& a) { return pow(a, MOD-2); }		
	modint operator-() const { return modint(-v); }
	modint& operator++() { return *this += 1; }
	modint& operator--() { return *this -= 1; }
    modint operator++(int) { modint tmp; tmp.v = v++; return tmp; }
    modint operator--(int) { modint tmp; tmp.v = v--; return tmp; }
	friend modint operator+(modint a, const modint& b) { return a += b; }
	friend modint operator-(modint a, const modint& b) { return a -= b; }
	friend modint operator*(modint a, const modint& b) { return a *= b; }
	friend modint operator/(modint a, const modint& b) { return a /= b; }
    friend ostream& operator<<(ostream& os, const modint& m) { os << m.v; return os; }
    friend istream& operator>>(istream& is, modint& m) { ll x; is >> x; m.v = x; return is; }
}; 
 
modint fact[MAXN+1];
modint fact_inv[MAXN+1];
 
void calc_factorials() {
	fact[0] = 1; fact_inv[0] = 1;
	for(int i = 1; i <= MAXN; i++) fact[i] = fact[i-1] * i, fact_inv[i] = inv(fact[i]);
}

modint comb_nchoosek(modint _a, modint _b) {
    int a = (int) _a.v, b = (int) _b.v;
	if (a < 0 || b < 0 || b > a) return 0;
    return fact[a] * fact_inv[b] * fact_inv[a - b];
} 

void run_test() {
    int N, M; cin >> N >> M;
    calc_factorials();
    modint ans = 0;
    int sign = 1;
    for(int i = 0; i <= N; i++) {
        ans += sign * comb_nchoosek(N, i) * comb_nchoosek(M - i, N - i) * fact[N - i];
        sign = -sign;
    }
    ans  *= comb_nchoosek(M, N) * fact[N];
    cout << ans << endl;
}

//=========================

int main() {
	ios::sync_with_stdio(false); cin.tie(nullptr);
	//int t_ = 1, t__; cin >> t__; while(t_ <= t__) { cout << "Case #" << t_++ << ": "; run_test(); }
	// int t_; cin >> t_; while(t_--) run_test();
	run_test();
	return 0;	
}


Measured memory_bytes: 19244