// う　し　た　ぷ　に　き　あ　く　ん　笑
#include <algorithm>
#include <array>
#include <cmath>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
#define int long long
constexpr int MOD = 1000000000 + 7;

class Combination {
   private:
    long long maxn;
    long long mod;
    vector<long long> fact, rev_fact;

   public:
    // コンストラクタ。maxn: 組み合わせのnの最大値。m: mod
    Combination(long long maxn, long long mod) : maxn(maxn), mod(mod) {
        setFact(maxn);
    }

    // 1からnの階乗とその逆元を前計算
    void setFact(long long n) {
        fact.resize(n + 1);
        rev_fact.resize(n + 1);
        fact[0] = 1;
        for (long long i = 1; i <= n; i++) {
            fact[i] = fact[i - 1] * i;
            fact[i] %= mod;
        }
        rev_fact[n] = modpow(fact[n], mod - 2, mod);
        for (long long i = n - 1; i >= 0; i--) {
            rev_fact[i] = rev_fact[i + 1] * (i + 1);
            rev_fact[i] %= mod;
        }
    }

    constexpr long long modpow(long long a, long long n, long long m) {
        long long rtn = 1;
        while (n > 0) {
            if (n & 1) rtn = rtn * a % m;
            a = a * a % m;
            n >>= 1;
        }
        return rtn;
    }

    // n種類のものからk個選ぶ場合の数
    long long c(long long n, long long k) {
        if (!(0 <= n && n <= maxn) || !(0 <= k && k <= maxn)) return -1;
        return (((fact[n] * rev_fact[k]) % mod) * rev_fact[n - k]) % mod;
    }

    // n種類のものから重複を許してk個選ぶ場合の数
    // n+k-1<=maxn とすること
    long long h(long long n, long long k) { return c(n + k - 1, k); }

    // n種類のものからk個選んで並び替える場合の数
    long long p(long long n, long long k) {
        if (!(0 <= n && n <= maxn) || !(0 <= k && k <= maxn)) return -1;
        return fact[n] * rev_fact[n - k] % mod;
    }
};

// https://github.com/atcoder-live/library/blob/master/mint.cpp
struct mint {
    using ll = long long;
    ll mod = MOD;
    ll x;  // typedef long long ll;
    mint(ll x = 0) : x((x % mod + mod) % mod) {}
    mint operator-() const { return mint(-x); }
    mint& operator+=(const mint a) {
        if ((x += a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator-=(const mint a) {
        if ((x += mod - a.x) >= mod) x -= mod;
        return *this;
    }
    mint& operator*=(const mint a) {
        (x *= a.x) %= mod;
        return *this;
    }
    mint operator+(const mint a) const { return mint(*this) += a; }
    mint operator-(const mint a) const { return mint(*this) -= a; }
    mint operator*(const mint a) const { return mint(*this) *= a; }
    mint pow(ll t) const {
        if (!t) return 1;
        mint a = pow(t >> 1);
        a *= a;
        if (t & 1) a *= *this;
        return a;
    }

    // for prime mod
    mint inv() const { return pow(mod - 2); }
    mint& operator/=(const mint a) { return *this *= a.inv(); }
    mint operator/(const mint a) const { return mint(*this) /= a; }
};
istream& operator>>(istream& is, const mint& a) { return is >> a.x; }
ostream& operator<<(ostream& os, const mint& a) { return os << a.x; }

signed main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

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

    Combination Combi(1000000, MOD);

    mint ans = 0;

    for (int k = 0; k <= n; k++) {
        mint now = Combi.c(n, k);
        now *= ((int)pow(-1, k));
        now *= Combi.p(m, k);
        now *= Combi.p(m - k, n - k) * Combi.p(m - k, n - k);

        ans += now;
    }

    cout << ans << endl;
}


Measured memory_bytes: 18804