// Standard Stuff
#include <bits/stdc++.h>
using namespace std;

// Macros
#define F  first
#define S  second
#define PB push_back

// Rename Datatypes
using ll  = long long;
using ld  = long double;
using pii = pair<int,int>;

// Common Functions
ll fastpow(ll a, ll ex){ ll res = 1; while(ex){ if(ex & 1) res *= a; a *= a; ex >>= 1; } return res; }
ll fastpow(ll a, ll ex, ll m){ a %= m; ll res = 1; while(ex){ if(ex & 1) res = (a*res) % m; a = (a*a) % m; ex >>= 1; } return res; }
ll modinverse(ll a, ll m){ ll m0 = m, y = 0, x = 1; while (a > 1){ ll q = a / m; a %= m; swap(a,m); x -= q*y; swap(x,y); } if(x < 0) x += m0; return x; }

// HELPERS
//  Tedious Grid Movements
vector<pii> moves_grid = { {0,1} , {0,-1} , {1,0} , {-1,0} };
inline bool move_okay(int x, int y, int n, int m) { return 0 <= x and x < n and 0 <= y and y < m; }
//  Remember:
//   * vec.assign() GOOD; vec.resize() BAD
//   * comparator uses <

// Output, Common Containers
template <typename T> ostream& operator << (ostream &os, const vector<T> &v) { for (T i : v) os << i << ' '; return os; }
template <typename T> ostream& operator << (ostream &os, const set<T> &v)    { for (T i : v) os << i << ' '; return os; }
template <typename T, typename S> ostream& operator << (ostream &os, const pair<T,S> &v) { os << "(" << v.F << "=>" << v.S << ") "; return os; }
template <typename T, typename S> ostream& operator << (ostream &os, const map<T,S> &v)  { for (auto i : v) os << i << ' '; return os; }

// Debugging
#ifdef SANYAM1101
	#define trace(args...) do{ cerr << "TRACE ON! (Line: " << __LINE__ << ")\n"; auto _stream = istringstream{string{#args}}; d_f(_stream, args); } while(0)
	void d_f(__attribute__((unused)) istringstream& _stream) {}
	template<typename Head, typename... Tails> void d_f(istringstream& _stream, Head H, Tails... T) { string _name; _stream >> _name; if(_name.back() == ',') _name.pop_back(); cerr << "\t" << _name << " <=> [" << H << "]\n"; d_f(_stream, T...); }
#else
	#define trace(args...)
#endif


// CODE STARTS HERE

void solve(){
	const int MOD = (int)1e9 + 7;

	auto add = [&MOD](ll x, ll y) { return (x + y) % MOD; };
	auto mul = [&MOD](ll x, ll y) { return (x * y) % MOD; };

	int n, m;
	cin >> n >> m;

	vector<ll> fac(m + 1);
	fac[0] = 1;
	for(int i = 1; i <= m; ++i) fac[i] = mul(fac[i - 1], i);

	auto nPr = [&mul, &fac](auto _n, auto _r){
		if(_n < _r) return 0LL;
		if(_r == 0) return 1LL;
		return mul(fac[_n], modinverse(fac[_n - _r], MOD));
	};

	auto nCr = [&mul, &fac](auto _n, auto _r){
		if(_n < _r) return 0LL;
		if(_r == 0) return 1LL;
		return mul(mul(fac[_n], modinverse(fac[_n - _r], MOD)),
		           modinverse(fac[_r], MOD));
	};

	ll A = nPr(m, n);

	ll B = 0;
	for(int i = 1; i <= n; ++i){
		ll curr = mul(nCr(n, i), nPr(m - i, n - i));
		if((i & 1) == 0) curr = (MOD - curr) % MOD;
		B = add(B, curr);
	}

	B = add(nPr(m, n), MOD - B);

	cout << mul(A,B) << "\n";
}

signed main (void){
	// Fast_IO
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	// Set Fixed Notation (default sucks), High Precision for Floating-Point Output
	cout << fixed << setprecision(20);

	// Multiple TCs
	int tt = 1;
	// cin >> tt;
	while(tt--) solve();
}


Measured memory_bytes: 6980