#include <string>
#include <iostream>
#include <stack>
#include <queue> // priority_queue も入ってる
#include <set>   // 要素数は size() で取得 multisetもある
#include <map>
#include <array> // sizeはコンパイル時定数で固定
#include <vector>
#include <numeric>   // accumulate, gcd
#include <algorithm> // count_ifに必要
#include <iomanip>   // cout << setprecision(15) << x で小数の出力精度を指定
#include <tuple>
#include <utility> //pair
#include <cmath>

using namespace std;
// 問題が起こるまでintは使用禁止2020-04-13
using ll = long long;

#define rep(i, n) for (int i = 0; i < (n); ++i)

template <class InputIterator, class T>
bool contains_itr(InputIterator iterator, const T &value)
{
    if (find(iterator.begin(), iterator.end(), value) == iterator.end())
        return false;
    else
        return true;
}

template <class T>
bool contains_set(set<T> st, const T &value)
{
    if (st.find(value) == st.end())
    {
        return false;
    }
    else
    {
        return true;
    }
}

template <class InputIterator>
auto sum(InputIterator iterator)
{
    return accumulate(iterator.begin(), iterator.end(), 0);
}

// endは排他的(exclusive)なので注意
vector<ll> range(ll begin, ll end)
{
    vector<ll> result;
    for (ll i = begin; i < end; ++i)
    {
        result.push_back(i);
    }
    return result;
}

// =========ここまでテンプレ============

// ここから二項係数(nCk)の話

// TODO: maxNとMODを変更
const int maxN = 510000;
const int MOD = 1000000007;

// 階乗、その逆数、iの逆数のテーブルを生成する
ll fac[maxN], finv[maxN], inv[maxN];

// テーブルを作る前処理
// 計算量 O(n)
void initModularTables()
{
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < maxN; i++)
    {
        fac[i] = fac[i - 1] * i % MOD;
        // 何でこれで順にinv[i]が出るんや2020-06-30
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

// 二項係数計算 nCk
// 先にinitModularTables()を呼んでおくこと！
ll modularCombination(ll n, ll k)
{
    if (fac[5] != 120)
    {
        cout << "call initModularTables() first!!!!!!!!" << endl;
        return 0;
    }
    if (n < k)
        return 0;
    if (n < 0 || k < 0)
        return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

// 順列計算 nPk
// 先にinitModularTables()を呼んでおくこと！
ll modularPermutation(ll n, ll k)
{
    if (fac[5] != 120)
    {
        cout << "call initModularTables() first!!!!!!!!" << endl;
        return 0;
    }
    if (n < k)
        return 0;
    if (n < 0 || k < 0)
        return 0;
    return fac[n] * finv[n - k] % MOD;
}

int main()
{
    initModularTables();
    ll n, m;
    cin >> n >> m;

    // 求める数 = 全体 - 少なくとも1つかぶってる
    // 少なくとも1つかぶってる = Σ_(i)i番目がかぶってる - Σ(i,j)i,j番目がかぶってる + Σ(i,j,k)i,j,k番目がかぶってる + …
    // = (-1)^0 * nC1 * mP1 * ((m-1)P(n-1)^(n-1))^2 + (-1)^1 * nC2 * mP2 * ((m-2)P(n-2)^2 + ...
    // = Σ_(k=1...n)(-1)^(k-1) * nCk * mPk * ((m-k)P(n-k))^2
    // 答えは
    // Σ_(k=0...n)(-1)^k * nCk * mPk * ((m-k)P(n-k))^2

    ll result = 0;
    rep(k, n + 1)
    {
        int sign = 1 - (k % 2) * 2;
        ll c = modularCombination(n, k);
        ll p1 = modularPermutation(m, k);
        ll p2 = modularPermutation(m - k, n - k);
        // result = (result + sign * ((modularCombination(n, k) * modularPermutation(m, k) % MOD) * modularPermutation(m - k, n - k) % MOD) * modularPermutation(m - k, n - k) % MOD) % MOD;
        result = (result + sign * ((c * p1 % MOD) * p2 % MOD) * p2 % MOD) % MOD;
    }
    if (result < 0)
        result += MOD;
    cout << result << endl;
}

Measured memory_bytes: 15100