#include <iostream>
#include <iomanip>
#include <vector>
#include <unordered_map>
#include <map>
#include <set>
#include <queue>
#include <stack>
#include <array>
#include <tuple>
#include <string>
#include <algorithm>
#include <functional>
#include <cmath>
#include <numeric>
#include <bitset>
#include <cstdint>
#include <stdexcept>
using namespace std;

// 整数型
using ll = int64_t;
using i32 = int32_t;
using i64 = int64_t;
using u32 = uint32_t;
using u64 = uint64_t;
// [0,n)を昇順/降順でループ
#define rep(i, n) for (int i = 0; i < static_cast<int>(n); ++i)
#define repd(i, n) for (int i = static_cast<int>(n) - 1; i >= 0; --i)
// [a,b)を昇順/降順でループ
#define FOR(i, a, b) for (int i = static_cast<int>(a); i < static_cast<int>(b); ++i)
#define FORD(i, a, b) for (int i = static_cast<int>(b) - 1; i >= static_cast<int>(a); --i)

// デバッグ
#ifdef DEBUG
#include <cassert>
#define my_assert(x) assert(x)
#else
#define my_assert(x)
#endif

template <u32 p>
struct mint
{
    // p は素数
    static_assert(2 <= p and p < (static_cast<u32>(1) << 31), "p must be in [2, 2 ** 31)");

private:
    // [0,p)内の値
    u32 data;

    constexpr static inline i64 p_i64 = static_cast<i64>(p);

public:
    // safe
    constexpr mint() noexcept
        : data(0) {}

    constexpr mint(i64 const x) noexcept
        : data(static_cast<u32>((x % p_i64 >= 0) ? x % p_i64 : x % p_i64 + p_i64)) {}

    // unsafe
    constexpr mint(u32 const x, bool const) noexcept
        : data(x) {}

    // convert to u32
    constexpr u32 const &val() const noexcept
    {
        return data;
    }

    constexpr mint &operator+=(mint const x) noexcept
    {
        data += x.data;
        if (data >= p)
        {
            data -= p;
        }
        return *this;
    }

    constexpr mint &operator-=(mint const x) noexcept
    {
        if (data < x.data)
        {
            data += p;
        }
        data -= x.data;
        return *this;
    }

    constexpr mint &operator*=(mint const x) noexcept
    {
        data = static_cast<u32>(static_cast<u64>(data) * x.data % p);
        return *this;
    }

    constexpr mint &operator/=(mint x)
    {
        if (x.data == 0)
        {
            throw domain_error("Division by mint zero");
        }
        u32 exp = p - 2;
        // (*this) * (x ** exp) : invariant
        while (exp > 0)
        {
            if (exp & 1)
            {
                *this *= x;
            }
            x *= x;
            exp /= 2;
        }
        return *this;
    }

    constexpr mint &operator++() noexcept
    {
        return *this += mint(1, true);
    }

    constexpr mint operator++(int) noexcept
    {
        mint const ret(*this);
        ++(*this);
        return ret;
    }

    constexpr mint &operator--() noexcept
    {
        return *this -= mint(1, true);
    }

    constexpr mint operator--(int) noexcept
    {
        mint const ret(*this);
        --(*this);
        return ret;
    }

    constexpr mint operator-() const noexcept
    {
        return mint(0, true) -= *this;
    }

    constexpr mint operator+(mint const x) const noexcept
    {
        return mint(*this) += x;
    }

    constexpr mint operator-(mint const x) const noexcept
    {
        return mint(*this) -= x;
    }

    constexpr mint operator*(mint const x) const noexcept
    {
        return mint(*this) *= x;
    }

    constexpr mint operator/(mint const x) const
    {
        return mint(*this) /= x;
    }

    // x >= 0 のときべき乗を計算
    constexpr mint pow(u64 const x) const noexcept
    {
        u64 exp = x;
        mint ret(1, true), base(*this);
        // ret * (base ** exp) : invariant, == (*this) ** x
        while (exp > 0)
        {
            if (exp & 1)
            {
                ret *= base;
            }
            base *= base;
            exp /= 2;
        }
        return ret;
    }

    constexpr mint inv() const noexcept
    {
        return mint(1, true) /= *this;
    }

    constexpr bool operator==(mint const x) const noexcept
    {
        return data == x.data;
    }
};

//////////////// //////////////// //////////////// //////////////// ////////////////
//////////////// //////////////// //////////////// //////////////// ////////////////

constexpr u32 mod = 1000'000'007u;

int main()
{
    // 高速な入出力
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    // 浮動小数の表示の精度
    cout << setprecision(15);

    int n, m;
    cin >> n >> m;
    vector<mint<mod>> fact(m + 1), factinv(m + 1);
    fact[0] = mint<mod>(1, true);
    factinv[0] = mint<mod>(1, true);
    FOR(i, 1, m + 1)
    {
        fact[i] = fact[i - 1] * mint<mod>(i, true);
        factinv[i] = fact[i].inv();
    }

    mint<mod> ans;
    rep(k, n + 1)
    {
        auto a = fact[n] * factinv[k] * factinv[n - k];
        auto b = mint<mod>((k & 1) ? -1 : 1);
        auto c = fact[m] * factinv[m - n];
        auto d = fact[m - k] * factinv[m - n];
        ans += a * b * c * d;
    }
    cout << ans.val() << endl;

    return 0;
}


Measured memory_bytes: 6976