#include <vector>
#include <iostream>
#include <cassert>

template <int MOD>
class mod_int {
public:
	mod_int() : val(0)
	{
	}

	mod_int(int value) : val(value) {
		assert(0 <= value);
		assert(value < MOD);
	}
	mod_int(const mod_int&) = default;
	mod_int& operator=(const mod_int&) = default;

	mod_int& operator+=(const mod_int& other) {
		val = (0LL + val + other.val) % MOD;
		return *this;
	}

	mod_int& operator-=(const mod_int& other) {
		val = (0LL + val + MOD - other.val) % MOD;
		return *this;
	}

	mod_int& operator*=(const mod_int& other) {
		val = (1LL * val * other.val) % MOD;
		return *this;
	}

	int value() const {
		return val;
	}

private:
	int val;
};

template <int MOD>
std::ostream& operator<<(std::ostream& os, mod_int<MOD> x)
{
	return os << x.value();
}

template <int MOD>
mod_int<MOD> operator+(mod_int<MOD> lhs, mod_int<MOD> rhs)
{
	return lhs += rhs;
}

template <int MOD>
mod_int<MOD> operator-(mod_int<MOD> lhs, mod_int<MOD> rhs)
{
	return lhs -= rhs;
}

template <int MOD>
mod_int<MOD> operator*(mod_int<MOD> lhs, mod_int<MOD> rhs)
{
	return lhs *= rhs;
}

template <int MOD>
mod_int<MOD> powm(mod_int<MOD> a, int n)
{
	if (n == 0) {
		return 1;
	}
	else if (n & 1) {
		return a * powm(a * a, n / 2);
	}
	else {
		return powm(a * a, n / 2);
	}
}

template <int MOD>
mod_int<MOD> invm(mod_int<MOD> a)
{
	return powm(a, MOD - 2);
}

template <int MOD>
class mod_power {
public:
	using value_type = mod_int<MOD>;

	mod_power(int a, int n)
		: data(n + 1)
	{
		data[0] = 1;
		for (int i = 1; i <= n; ++i) {
			data[i] = value_type(a) * data[i - 1];
		}
	}

	value_type operator()(int i) const {
		return data[i];
	}

private:
	std::vector<value_type> data;
};

template <int MOD>
class mod_factorial
{
public:
	using value_type = mod_int<MOD>;

	mod_factorial(int n)
		: data(n + 1)
	{
		data[0] = 1;
		for (int i = 1; i <= n; ++i) {
			data[i] = value_type(i) * data[i - 1];
		}
	}

	value_type operator()(int i) const {
		return data[i];
	}

private:
	std::vector<value_type> data;
};

template <int MOD>
class mod_inverse_factorial
{
public:
	using value_type = mod_int<MOD>;

	mod_inverse_factorial(int n, const mod_factorial<MOD>& fact)
		: data(n + 1)
	{
		data[n] = invm(fact(n));
		for (int i = n - 1; i >= 0; --i) {
			data[i] = value_type(i + 1) * data[i + 1];
		}
	}

	value_type operator()(int i) const {
		return data[i];
	}

private:
	std::vector<value_type> data;
};

template <int MOD>
class mod_combination
{
public:
	using value_type = mod_int<MOD>;

	mod_combination(const mod_factorial<MOD>& f, const mod_inverse_factorial<MOD>& f_inv)
		: f(f)
		, f_inv(f_inv)
	{
	}

	value_type p(int n, int r) const {
		if (r < 0 || n < r) {
			return 0;
		}
		return f(n) * f_inv(n - r);
	}

	value_type c(int n, int r) const {
		return p(n, r) * f_inv(r);
	}

	value_type h(int n, int r) const {
		return c(n + r - 1, r);
	}

private:
	const mod_factorial<MOD>& f;
	const mod_inverse_factorial<MOD>& f_inv;
};

template <int MOD>
class mod_table
{
public:
	using value_type = mod_int<MOD>;

	mod_table(int n)
		: f(n)
		, f_inv(n, f)
		, c(f, f_inv)
	{
	}

	value_type fact(int i) const {
		return f(i);
	}
	value_type ifact(int i) const {
		return f_inv(i);
	}
	value_type perm(int n, int r) const {
		return c.p(n, r);
	}
	value_type comb(int n, int r) const {
		return c.c(n, r);
	}
	value_type rcomb(int n, int r) const {
		return c.h(n, r);
	}

private:
	mod_factorial<MOD> f;
	mod_inverse_factorial<MOD> f_inv;
	mod_combination<MOD> c;
};


#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

const int MOD = 1000 * 1000 * 1000 + 7;

using mint = mod_int<MOD>;

int main()
{
	int N, M;
	cin >> N >> M;

	mod_table<MOD> t(5 * 100000);

	mint ans = t.perm(M, N);

	for (int i = 1; i <= N; ++i) {
		if (i % 2 == 0) {
			ans += t.comb(N, i) * t.perm(M - i, N - i);
		}
		else {
			ans -= t.comb(N, i) * t.perm(M - i, N - i);
		}
	}
	ans *= t.perm(M, N);

	cout << ans << endl;
}


Measured memory_bytes: 7164