Problem:
Balls and Boxes 2
Balls
Boxes
Any way
At most one ball
At least one ball
Distinguishable
Distinguishable
1
2
3
Indistinguishable
Distinguishable
4
5
6
Distinguishable
Indistinguishable
7
8
9
Indistinguishable
Indistinguishable
10
11
12
Problem
You have $n$ balls and $k$ boxes. You want to put these balls into the boxes.
Find the number of ways to put the balls under the following conditions:
Each ball is distinguished from the other.
Each box is distinguished from the other.
Each ball can go into only one box and no one remains outside of the boxes.
Each box can contain at most one ball.
Note that you must print this count modulo $10^9+7$.
Input
$n$ $k$
The first line will contain two integers $n$ and $k$.
Output
Print the number of ways modulo $10^9+7$ in a line.
Constraints
$1 \le n \le 1000$
$1 \le k \le 1000$
Sample Input 1
2 3
Sample Output 1
6
Sample Input 2
3 2
Sample Output 2
0
Sample Input 3
100 100
Sample Output 3
437918130

Submitted solutions:

code_snippet: /*
    Created by Pujx on 2024/8/4.
*/
#pragma GCC optimize(2, 3, "Ofast", "inline")
#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
//#define int long long
//#define double long double
using i64 = long long;
using ui64 = unsigned long long;
//using i128 = __int128;
#define inf (int)0x3f3f3f3f3f3f3f3f
#define INF 0x3f3f3f3f3f3f3f3f
#define yn(x) cout << (x ? "yes" : "no") << endl
#define Yn(x) cout << (x ? "Yes" : "No") << endl
#define YN(x) cout << (x ? "YES" : "NO") << endl
#define mem(x, i) memset(x, i, sizeof(x))
#define cinarr(a, n) for (int _ = 1; _ <= n; _++) cin >> a[_]
#define cinstl(a) for (auto& _ : a) cin >> _
#define coutarr(a, n) for (int _ = 1; _ <= n; _++) cout << a[_] << " \n"[_ == n]
#define coutstl(a) for (const auto& _ : a) cout << _ << ' '; cout << endl
#define all(x) (x).begin(), (x).end()
#define ls (s << 1)
#define rs (s << 1 | 1)
#define ft first
#define se second
#define pii pair<int, int>
#ifdef DEBUG
    #include "debug.h"
#else
    #define dbg(...) void(0)
#endif

const int N = 2000 + 5;
//const int M = 1e5 + 5;
//const int mod = 998244353;
const int mod = 1e9 + 7;
//template <typename T> T ksm(T a, i64 b) { T ans = 1; for (; b; a = 1ll * a * a, b >>= 1) if (b & 1) ans = 1ll * ans * a; return ans; }
//template <typename T> T ksm(T a, i64 b, T m = mod) { T ans = 1; for (; b; a = 1ll * a * a % m, b >>= 1) if (b & 1) ans = 1ll * ans * a % m; return ans; }

int a[N];
int n, m, t, k, q;

template <int P> struct MInt {
    int x;
    MInt() : x(0) {}
    MInt(const signed& x) : x(norm(x % getMod())) {}
    MInt(const long long& x) : x(norm(x % getMod())) {}

    static int Mod;
    static int getMod() { return P > 0 ? P : Mod; }
    static void setMod(int _Mod) { Mod = _Mod; }
    int norm(const int& x) const { return x < 0 ? x + getMod() : (x >= getMod() ? x - getMod() : x); }
    int val() const { return x; }
    explicit operator int() const { return x; }
    MInt operator - () const { MInt res; res.x = norm(getMod() - x); return res; }
    MInt ksm(const long long& x) const {
        MInt a = *this, ans = 1;
        for (long long pw = x; pw; a *= a, pw >>= 1) if (pw & 1) ans *= a;
        return ans;
    }
    MInt inv() const { assert(x != 0); return ksm(getMod() - 2); }
    MInt& operator += (const MInt& b) & { x = norm(x + b.x); return *this; }
    MInt& operator -= (const MInt& b) & { x = norm(x - b.x); return *this; }
    MInt& operator *= (const MInt& b) & { x = norm(1ll * x * b.x % getMod()); return *this; }
    MInt& operator /= (const MInt& b) & { return *this *= b.inv(); }
    MInt& operator ++ () & { return *this += 1; }
    MInt& operator -- () & { return *this -= 1; }
    const MInt operator ++ (signed) { MInt old = *this; ++(*this); return old; }
    const MInt operator -- (signed) { MInt old = *this; --(*this); return old; }
    friend MInt operator + (const MInt& a, const MInt& b) { MInt res = a; res += b; return res; }
    friend MInt operator - (const MInt& a, const MInt& b) { MInt res = a; res -= b; return res; }
    friend MInt operator * (const MInt& a, const MInt& b) { MInt res = a; res *= b; return res; }
    friend MInt operator / (const MInt& a, const MInt& b) { MInt res = a; res /= b; return res; }
    friend istream& operator >> (istream& in, MInt& a) { long long v; in >> v; a = MInt(v); return in; }
    friend ostream& operator << (ostream& out, const MInt& a) { return out << a.val(); }
    friend bool operator == (const MInt& a, const MInt& b) { return a.val() == b.val(); }
    friend bool operator != (const MInt& a, const MInt& b) { return a.val() != b.val(); }
    friend bool operator < (const MInt& a, const MInt& b) { return a.val() < b.val(); }
    friend bool operator > (const MInt& a, const MInt& b) { return a.val() > b.val(); }
    friend bool operator <= (const MInt& a, const MInt& b) { return a.val() <= b.val(); }
    friend bool operator >= (const MInt& a, const MInt& b) { return a.val() >= b.val(); }
};
using Mint = MInt<mod>;
template<> int MInt<0>::Mod = 1;

Mint fac[N], c[N][N], s[N][N], p[N][N];

void init() {
    fac[0] = 1, c[0][0] = s[0][0] = p[0][0] = 1;
    for (int i = 1; i <= 2000; i++) {
        fac[i] = fac[i - 1] * i;
        c[i][0] = 1, s[i][0] = p[i][0] = 0;
        for (int j = 1; j <= i; j++) {
            c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
            s[i][j] = s[i - 1][j - 1] + j * s[i - 1][j];
            p[i][j] = p[i - 1][j - 1] + p[i - j][j];
        }
    }
}

void work() {
    cin >> n >> k;
    t = 2;
    if (t == 1) {
        cout << Mint(k).ksm(n) << endl;
    }
    else if (t == 2) {
        cout << fac[n] * c[k][n] << endl;
    }
    else if (t == 3) {
        cout << fac[k] * s[n][k] << endl;
    }
    else if (t == 4) {
        cout << c[n + k - 1][k - 1] << endl;
    }
    else if (t == 5) {
        cout << c[k][n] << endl;
    }
    else if (t == 6) {
        cout << c[n - 1][k - 1] << endl;
    }
    else if (t == 7) {
        Mint ans = 0;
        for (int i = 1; i <= k; i++)
            ans += s[n][i];
        cout << ans << endl;
    }
    else if (t == 8) {
        cout << (k >= n) << endl;
    }
    else if (t == 9) {
        cout << s[n][k] << endl;
    }
    else if (t == 10) {
        cout << p[n + k][k] << endl;
    }
    else if (t == 11) {
        cout << (k >= n) << endl;
    }
    else {
        cout << p[n][k] << endl;
    }
}

signed main() {
#ifdef LOCAL
    freopen("C:\\Users\\admin\\CLionProjects\\Practice\\data.in", "r", stdin);
    freopen("C:\\Users\\admin\\CLionProjects\\Practice\\data.out", "w", stdout);
#endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    init();
    int Case = 1;
    //cin >> Case;
    while (Case--) work();
    return 0;
}
/*
     _____   _   _       _  __    __
    |  _  \ | | | |     | | \ \  / /
    | |_| | | | | |     | |  \ \/ /
    |  ___/ | | | |  _  | |   }  {
    | |     | |_| | | |_| |  / /\ \
    |_|     \_____/ \_____/ /_/  \_\
*/
accuracy: 1
time_ms: 20
memory_kb: 50576
final_rank: 16

code_snippet: #define _CRT_SECURE_NO_WARNINGS
#if USE_MP
#include <boost/multiprecision/cpp_int.hpp>
#endif
#include <cassert>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <array>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <stack>
#include <functional>
#include <algorithm>
#include <cmath>
#include <tuple>
#include <bitset>
#include <string.h>
#include <numeric>
#include <random>
#if defined _DEBUG
//#include "TestCase.h"
//#include "Util.h"
#endif

using namespace std;

using ll = long long;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef tuple<ll, ll, ll> tlll;
typedef tuple<int, int, int> tiii;

using ai2 = array<int, 2>;
using ai3 = array<int, 3>;
using ai4 = array<int, 4>;
using al2 = array<ll, 2>;
using al3 = array<ll, 3>;
using al4 = array<ll, 4>;
using ad2 = array<double, 2>;
using ad3 = array<double, 3>;
using ad4 = array<double, 4>;

inline void Yes(bool upper = false) { cout << (upper ? "YES" : "Yes") << "\n"; }
inline void No(bool upper = false) { cout << (upper ? "NO" : "No") << "\n"; }

inline ll DivCeil(ll nume, ll deno)
{
	assert(deno != 0);
	if (deno < 0) { nume = -nume; deno = -deno; }
	if (nume < 0) return -(-nume / deno);
	else return (nume + deno - 1) / deno;
}
inline ll DivFloor(ll nume, ll deno)
{
	assert(deno != 0);
	if (deno < 0) { nume = -nume; deno = -deno; }
	if (nume < 0) return -((-nume + deno - 1) / deno);
	else return nume / deno;
}
inline ll DivRound(ll nume, ll deno)
{
	assert(deno != 0);
	if (deno < 0) { nume = -nume; deno = -deno; }
	if (nume < 0) return -((-nume + deno / 2) / deno);
	else return (nume + deno / 2) / deno;
}

template <typename T, int S>
auto MakeVecImpl(queue<int>& size, const T& ini)
{
	if constexpr (S == 1)
	{
		return vector<T>(size.front(), ini);
	}
	else
	{
		int fsize = size.front();
		size.pop();
		return vector(fsize, MakeVecImpl<T, S - 1>(size, ini));
	}
}

template <typename T, int S>
auto MakeVec(const array<int, S>& size, const T ini = T())
{
	queue<int> qsize;
	for (const auto v : size) qsize.push(v);
	return MakeVecImpl<T, S>(qsize, ini);
}
int d4[][2] =
{
	{0,-1},
	{0,1},
	{-1,0},
	{1,0},
};
int d8[][2] =
{
	{-1,-1},
	{0,-1},
	{1,-1},

	{-1,0},
	{1,0},

	{-1,1},
	{0,1},
	{1,1},
};
vector<array<int, 2>> Neighbor4(int y, int x)
{
	vector<array<int, 2>> ret;
	ret.push_back({ y, x - 1 });
	ret.push_back({ y, x + 1 });
	ret.push_back({ y - 1, x });
	ret.push_back({ y + 1, x });
	return ret;
}
vector<array<int, 2>> Neighbor6(int y, int x)
{
	vector<array<int, 2>> ret;
	const int ofs = (y & 1); // 1 - (y & 1); //

	ret.push_back({ y, x - 1 });
	ret.push_back({ y, x + 1 });

	ret.push_back({ y - 1, x - 1 + ofs });
	ret.push_back({ y - 1, x + ofs });

	ret.push_back({ y + 1, x - 1 + ofs });
	ret.push_back({ y + 1, x + ofs });

	return ret;
}
vector<array<int, 2>> Neighbor8(int y, int x)
{
	vector<array<int, 2>> ret;
	ret.push_back({ y - 1, x - 1 });
	ret.push_back({ y - 1, x });
	ret.push_back({ y - 1, x + 1 });

	ret.push_back({ y, x - 1 });
	ret.push_back({ y, x + 1 });

	ret.push_back({ y + 1, x - 1 });
	ret.push_back({ y + 1, x });
	ret.push_back({ y + 1, x + 1 });
	return ret;
}

vector<int> DecompDigit(ull val)
{
	if (val == 0)
		return { 0 };

	vector<int> ret;
	while (val)
	{
		ret.emplace_back(val % 10);
		val /= 10;
	}
	reverse(ret.begin(), ret.end());
	return ret;
}


#define PI 3.14159265358979l
long double R2D = 180 / PI;
long double D2R = PI / 180;

static const ll Mod = 1000000007;
static const ll Mod9 = 998244353;// 1000000007;
static const ll INF64 = 4500000000000000000;// 10000000000000000;
static const int INF32 = 2000000000;

random_device rd;
mt19937 mt(0);//(rd());
#if USE_MP
using mpint = boost::multiprecision::cpp_int;
#endif

const double EPS = 1e-10;

namespace Map12FoldWay
{
#pragma region 写像12相 ここから
#pragma region library
	ll GCDext(ll a, ll b, ll& x, ll& y)
	{
		if (b == 0)
		{
			x = 1;
			y = 0;
			return a;
		}
		else
		{
			ll p = a / b;
			ll b2 = a % b;
			ll a2 = b;
			ll d = GCDext(a2, b2, x, y);

			ll x2 = x;
			x = y;
			y = x2 - p * x;

			return d;
		}
	}

	template<ll p>
	inline ll invert(ll v)
	{
		ll x, y;
		GCDext(v, p, x, y);
		while (x < 0)
			x += p;

		return x;
	}

	template<ll p>
	inline ll Frac(ll n)
	{
		static std::vector<ll> f;
		if (f.size() <= n + 1)
		{
			int ini = max(2, (int)f.size());
			f.resize(n + 100000);
			f[0] = f[1] = 1;
			for (int i = ini; i < f.size(); i++)
				f[i] = i * f[i - 1] % p;
		}
		return f[n];
	}
	template<ll p>
	inline ll FracInv(ll n)
	{
		static std::vector<ll> finv;
		if (finv.size() <= n + 1)
		{
			int ini = max(2, (int)finv.size());
			finv.resize(n + 100000);
			finv[0] = finv[1] = 1;
			for (int i = ini; i < finv.size(); i++)
				finv[i] = invert<p>(i) * finv[i - 1] % p;
		}
		return finv[n];
	}

	template<ll p>
	inline ll ModComb(ll n, ll k)
	{
		if (n < 0 || k < 0 || n < k)
			return 0;
		return ((Frac<p>(n) * FracInv<p>(k)) % p) * FracInv<p>(n - k) % p;
	}
	template<ll p>
	inline ll ModPerm(ll n, ll k)
	{
		if (n < 0 || k < 0 || n < k)
			return 0;
		return Frac<p>(n) * FracInv<p>(n - k) % p;
	}

	template<ll p>
	ll ModPow(ll a, ll n)
	{
		if (a == 0) return 0;

		ll ret = 1;
		ll aa = a % p;
		while (n)
		{
			if (n & 1)
				ret = ret * aa % p;
			n >>= 1;
			aa = aa * aa % p;
		}

		return ret;
	}

	/// <summary>
	/// N個の要素をM個以下のグループに分割
	/// </summary>
	template<ll p>
	ll Partition(int N, int M)
	{
		if (N < 0 || M < 0) return 0;
		static vector<vector<ll>> table;	
		static int n = 0, m = 0;	// 算出済みの位置
		if (table.empty() ||
			table.size() <= M ||
			table[0].size() <= N)
		{
			table.resize(max(m, M * 2 + 1));
			for (auto& v : table)
				v.resize(max(n, N * 2 + 1));
			table[0][0] = 1;
		}

		for (int i = 1; i <= M; i++) {
			int l = i > m ? 0 : n + 1;
			for (int j = l; j <= N; j++) {
				if (j >= i)
					table[i][j] = (table[i - 1][j] + table[i][j - i]) % p;
				else
					table[i][j] = table[i - 1][j];
			}
		}

		n = max(n, N);
		m = max(m, M);

		return table[M][N];
	}
#pragma endregion 

#pragma region 玉なし/箱なし 000~002
	/// <summary>
	/// 000 玉の区別なし 箱の区別なし 箱に入れる玉の制限なし
	/// 分割数そのもの
	/// </summary>
	template<ll p>
	ll Map000(int N, int M) {
		return Partition<p>(N, M);
	}

	/// <summary>
	/// 001 玉の区別なし 箱の区別なし 箱に玉は1つまで
	/// 選べるかどうか
	/// </summary>
	template<ll p>
	ll Map001(int N, int M) {
		return M>=N ? 1 : 0;
	}

	/// <summary>
	/// 002 玉の区別なし 箱の区別なし 空箱NG
	/// 全箱に1つ入れてから分割数をやる
	/// </summary>
	template<ll p>
	ll Map002(int N, int M) {
		return Partition<p>(N - M, M);
	}
#pragma endregion

#pragma region 玉なし/箱あり 010~012
	/// <summary>
	/// 010 玉の区別なし 箱の区別あり 箱に入れる玉の制限なし
	/// 重複組合せC(N+M-1,M-1)
	/// </summary>
	template<ll p>
	ll Map010(int N, int M) {
		return ModComb<p>(N + M - 1, M - 1);
	}

	/// <summary>
	/// 011 玉の区別なし 箱の区別あり 箱に玉は1つまで
	/// 組合せC(M,N)
	/// </summary>
	template<ll p>
	ll Map011(int N, int M) {
		return ModComb<p>(M, N);
	}

	/// <summary>
	/// 012 玉の区別なし 箱の区別あり 空箱NG
	/// 組合せC(N-1,M-1)
	/// </summary>
	template<ll p>
	ll Map012(int N, int M) {
		return ModComb<p>(N - 1, M - 1);
	}
#pragma endregion

#pragma region 玉あり/箱なし 100~102
	/// <summary>
	/// 100 玉の区別なし 箱の区別なし 箱に入れる玉の制限なし
	/// ベル数で解ける
	/// ①愚直なスターリング数(102)の和 ②工夫した和 ③式
	/// ③が有利なので採用 Σ(i=0..M){i^N/i! Σ(j=0..M-i){(-1)^j/j!}}
	/// </summary>
	template<ll p>
	ll Map100(int N, int M) {
		// 前計算
		vector<ll> coeff{ 1 };		// 後半部分 Σ(j=0..M-i){(-1)^j/j!}}
		vector<ll> invfrac{ 1 };	// i!の逆数
		{
			ll sign = 1;
			for (int j = 1; j <= M; j++) {
				sign = -sign;
				invfrac.emplace_back(invfrac.back() * invert<p>(j) % p);
				ll tmp = (sign + p) * invfrac.back() % p;
				coeff.emplace_back((coeff.back() + tmp) % p);
			}
			reverse(coeff.begin(), coeff.end());
		}
		// 本体
		ll ans = 0;
		for (int i = 0; i <= M; i++) {
			ans += (ModPow<p>(i, N) * invfrac[i] % p) * coeff[i] % p;
		}
		return ans % p;
	}

	/// <summary>
	/// 101 玉の区別あり 箱の区別なし 箱に玉は1つまで
	/// 選べるかどうか
	/// </summary>
	template<ll p>
	ll Map101(int N, int M) {
		return M >= N ? 1 : 0;
	}

	/// <summary>
	/// 102 玉の区別あり 箱の区別なし 空箱NG
	/// スターリング数で解ける
	/// ①112をM!で割る ②DPの2通り解法がある
	/// 計算量は時間・空間とも①が有利
	/// </summary>
	template<ll p>
	ll Map102(int N, int M) {
		ll ans = ModPow<p>(M, N);
		ll coeff = 1;
		ll comb = 1;
		for (int i = 1; i < M; i++) {
			coeff = -coeff;
			comb = (comb * (M - i + 1) % p) * invert<p>(i) % p;

			ll temp = (coeff + p) % p;			// (-1)^i
			temp = temp * ModPow<p>(M - i, N) % p;	// (m-i)^n
			temp = temp * comb % p;				// C(m,i)

			ans += temp;
		}
		ans %= p;
		ll deno = 1;
		for (int i = 2; i <= M; i++) {
			deno = deno * invert<p>(i) % p;
		}
		return ans * deno % p;
	}

#pragma endregion

#pragma region 玉あり/箱あり 110~112
	/// <summary>
	/// 110 玉の区別あり 箱の区別あり 箱に入れる玉の制限なし
	/// 普通にModPow
	/// </summary>
	template<ll p>
	ll Map110(int N, int M) {
		return ModPow<p>(M, N);
	}

	/// <summary>
	/// 111 玉の区別あり 箱の区別あり 箱に玉は1つまで
	/// 順列 P(M,N)
	/// </summary>
	template<ll p>
	ll Map111(int N, int M) {
		return ModPerm<p>(M, N);
	}

	/// <summary>
	/// 112 玉の区別あり 箱の区別あり 空箱NG
	/// 包除原理で解ける Σ(-1)^i (m-i)^n C(m,i)
	/// </summary>
	template<ll p>
	ll Map112(int N, int M) {
		ll ans = ModPow<p>(M, N);
		ll coeff = 1;
		ll comb = 1;
		for (int i = 1; i < M; i++) {
			coeff = -coeff;
			comb = (comb * (M - i + 1) % p) * invert<p>(i) % p;

			ll temp = (coeff + p) % p;			// (-1)^i
			temp = temp * ModPow<p>(M - i, N) % p;	// (m-i)^n
			temp = temp * comb % p;				// C(m,i)

			ans += temp;
		}
		return ans % p;
	}
#pragma endregion
#pragma endregion 写像12相 ここまで
}
void Func()
{
	static vector<int> a{ 0 };
	cout << a.back()++ << "\n";
}

struct Solver
{
	void Run()
	{
		int N, K;
		cin >> N >> K;
		cout << Map12FoldWay::Map111<Mod>(N, K) << "\n";
	}
};

int main()
{
	std::cin.tie(nullptr); //★インタラクティブ注意★
	std::ios_base::sync_with_stdio(false);
	int T = 1;
	//cin >> T;
	while (T--)
	{
		Solver S;
		S.Run();
	}

	return 0;
}

/// 値渡しになっていないか?
/// 入力を全部読んでいるか? 途中でreturnしない
/// 32bitで収まるか? 10^5数えるとき
/// modは正しいか?
/// multisetでcountしていないか?
accuracy: 1
time_ms: 10
memory_kb: 4664
final_rank: 1

code_snippet: #define _CRT_SECURE_NO_WARNINGS
#if USE_MP
#include <boost/multiprecision/cpp_int.hpp>
#endif
#include <cassert>
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <array>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <unordered_set>
#include <unordered_map>
#include <queue>
#include <stack>
#include <functional>
#include <algorithm>
#include <cmath>
#include <tuple>
#include <bitset>
#include <string.h>
#include <numeric>
#include <random>
#if defined _DEBUG
//#include "TestCase.h"
//#include "Util.h"
#endif

using namespace std;

using ll = long long;
using ull = unsigned long long;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef tuple<ll, ll, ll> tlll;
typedef tuple<int, int, int> tiii;

using ai2 = array<int, 2>;
using ai3 = array<int, 3>;
using ai4 = array<int, 4>;
using al2 = array<ll, 2>;
using al3 = array<ll, 3>;
using al4 = array<ll, 4>;
using ad2 = array<double, 2>;
using ad3 = array<double, 3>;
using ad4 = array<double, 4>;

inline void Yes(bool upper = false) { cout << (upper ? "YES" : "Yes") << "\n"; }
inline void No(bool upper = false) { cout << (upper ? "NO" : "No") << "\n"; }

inline ll DivCeil(ll nume, ll deno)
{
	assert(deno != 0);
	if (deno < 0) { nume = -nume; deno = -deno; }
	if (nume < 0) return -(-nume / deno);
	else return (nume + deno - 1) / deno;
}
inline ll DivFloor(ll nume, ll deno)
{
	assert(deno != 0);
	if (deno < 0) { nume = -nume; deno = -deno; }
	if (nume < 0) return -((-nume + deno - 1) / deno);
	else return nume / deno;
}
inline ll DivRound(ll nume, ll deno)
{
	assert(deno != 0);
	if (deno < 0) { nume = -nume; deno = -deno; }
	if (nume < 0) return -((-nume + deno / 2) / deno);
	else return (nume + deno / 2) / deno;
}

template <typename T, int S>
auto MakeVecImpl(queue<int>& size, const T& ini)
{
	if constexpr (S == 1)
	{
		return vector<T>(size.front(), ini);
	}
	else
	{
		int fsize = size.front();
		size.pop();
		return vector(fsize, MakeVecImpl<T, S - 1>(size, ini));
	}
}

template <typename T, int S>
auto MakeVec(const array<int, S>& size, const T ini = T())
{
	queue<int> qsize;
	for (const auto v : size) qsize.push(v);
	return MakeVecImpl<T, S>(qsize, ini);
}
int d4[][2] =
{
	{0,-1},
	{0,1},
	{-1,0},
	{1,0},
};
int d8[][2] =
{
	{-1,-1},
	{0,-1},
	{1,-1},

	{-1,0},
	{1,0},

	{-1,1},
	{0,1},
	{1,1},
};
vector<array<int, 2>> Neighbor4(int y, int x)
{
	vector<array<int, 2>> ret;
	ret.push_back({ y, x - 1 });
	ret.push_back({ y, x + 1 });
	ret.push_back({ y - 1, x });
	ret.push_back({ y + 1, x });
	return ret;
}
vector<array<int, 2>> Neighbor6(int y, int x)
{
	vector<array<int, 2>> ret;
	const int ofs = (y & 1); // 1 - (y & 1); //

	ret.push_back({ y, x - 1 });
	ret.push_back({ y, x + 1 });

	ret.push_back({ y - 1, x - 1 + ofs });
	ret.push_back({ y - 1, x + ofs });

	ret.push_back({ y + 1, x - 1 + ofs });
	ret.push_back({ y + 1, x + ofs });

	return ret;
}
vector<array<int, 2>> Neighbor8(int y, int x)
{
	vector<array<int, 2>> ret;
	ret.push_back({ y - 1, x - 1 });
	ret.push_back({ y - 1, x });
	ret.push_back({ y - 1, x + 1 });

	ret.push_back({ y, x - 1 });
	ret.push_back({ y, x + 1 });

	ret.push_back({ y + 1, x - 1 });
	ret.push_back({ y + 1, x });
	ret.push_back({ y + 1, x + 1 });
	return ret;
}

vector<int> DecompDigit(ull val)
{
	if (val == 0)
		return { 0 };

	vector<int> ret;
	while (val)
	{
		ret.emplace_back(val % 10);
		val /= 10;
	}
	reverse(ret.begin(), ret.end());
	return ret;
}


#define PI 3.14159265358979l
long double R2D = 180 / PI;
long double D2R = PI / 180;

static const ll Mod = 1000000007;
static const ll Mod9 = 998244353;// 1000000007;
static const ll INF64 = 4500000000000000000;// 10000000000000000;
static const int INF32 = 2000000000;

random_device rd;
mt19937 mt(0);//(rd());
#if USE_MP
using mpint = boost::multiprecision::cpp_int;
#endif

const double EPS = 1e-10;

namespace Map12FoldWay
{
#pragma region 写像12相 ここから
#pragma region library
	ll GCDext(ll a, ll b, ll& x, ll& y)
	{
		if (b == 0)
		{
			x = 1;
			y = 0;
			return a;
		}
		else
		{
			ll p = a / b;
			ll b2 = a % b;
			ll a2 = b;
			ll d = GCDext(a2, b2, x, y);

			ll x2 = x;
			x = y;
			y = x2 - p * x;

			return d;
		}
	}

	template<ll p>
	ll invert(ll v)
	{
		ll x, y;
		GCDext(v, p, x, y);
		while (x < 0)
			x += p;

		return x;
	}

	template<ll p>
	ll Frac(ll n)
	{
		static std::vector<ll> f;
		if (f.size() <= n + 1)
		{
			int ini = max(2, (int)f.size());
			f.resize(n + 100000);
			f[0] = f[1] = 1;
			for (int i = ini; i < f.size(); i++)
				f[i] = i * f[i - 1] % p;
		}
		return f[n];
	}
	template<ll p>
	ll FracInv(ll n)
	{
		static std::vector<ll> finv;
		if (finv.size() <= n + 1)
		{
			int ini = max(2, (int)finv.size());
			finv.resize(n + 100000);
			finv[0] = finv[1] = 1;
			for (int i = ini; i < finv.size(); i++)
				finv[i] = invert<p>(i) * finv[i - 1] % p;
		}
		return finv[n];
	}

	template<ll p>
	ll ModCombFast(ll n, ll k)
	{
		if (n < 0 ||
			k < 0 ||
			n < k)
			return 0;

		static std::vector<ll> F, Finv;
		static int initialized = 1;
		if (F.size() <= n + 1)
		{
			F.resize(n + 100000), Finv.resize(n + 100000);
			F[0] = F[1] = Finv[0] = Finv[1] = 1;
			for (int i = initialized + 1; i < F.size(); i++)
			{
				F[i] = i * F[i - 1] % p;
				Finv[i] = invert<p>(i) * Finv[i - 1] % p;
			}
			initialized = F.size() - 1;
		}

		return ((F[n] * Finv[k]) % p) * Finv[n - k] % p;
	}

	template<ll p>
	ll ModPow(ll a, ll n)
	{
		if (a == 0) return 0;

		ll ret = 1;
		ll aa = a % p;
		while (n)
		{
			if (n & 1)
				ret = ret * aa % p;
			n >>= 1;
			aa = aa * aa % p;
		}

		return ret;
	}

	/// <summary>
	/// N個の要素をM個以下のグループに分割
	/// </summary>
	template<ll p>
	ll Partition(int N, int M)
	{
		if (N < 0 || M < 0) return 0;
		static vector<vector<ll>> table;	
		static int n = 0, m = 0;	// 算出済みの位置
		if (table.empty() ||
			table.size() <= M ||
			table[0].size() <= N)
		{
			table.resize(max(m, M * 2 + 1));
			for (auto& v : table)
				v.resize(max(n, N * 2 + 1));
			table[0][0] = 1;
		}

		for (int i = 1; i <= M; i++) {
			int l = i > m ? 0 : n + 1;
			for (int j = l; j <= N; j++) {
				if (j >= i)
					table[i][j] = (table[i - 1][j] + table[i][j - i]) % p;
				else
					table[i][j] = table[i - 1][j];
			}
		}

		n = max(n, N);
		m = max(m, M);

		return table[M][N];
	}
#pragma endregion 

#pragma region 玉なし/箱なし 000~002
	/// <summary>
	/// 玉の区別なし 箱の区別なし 箱に入れる玉の制限なし
	/// 分割数そのもの
	/// </summary>
	template<ll p>
	ll Map000(int N, int M) {
		return Partition<p>(N, M);
	}

	/// <summary>
	/// 玉の区別なし 箱の区別なし 空箱NG
	/// 全箱に1つ入れてから分割数をやる
	/// </summary>
	template<ll p>
	ll Map002(int N, int M) {
		return Partition<p>(N - M, M);
	}
#pragma endregion

#pragma region 玉なし/箱あり 010~012
#pragma endregion

#pragma region 玉あり/箱なし 100~102
	/// <summary>
	/// 玉の区別なし 箱の区別なし 箱に入れる玉の制限なし
	/// ベル数で解ける
	/// ①愚直なスターリング数(102)の和 ②工夫した和 ③式
	/// ③が有利なので採用 Σ(i=0..M){i^N/i! Σ(j=0..M-i){(-1)^j/j!}}
	/// </summary>
	template<ll p>
	ll Map100(int N, int M) {
		// 前計算
		vector<ll> coeff{ 1 };		// 後半部分 Σ(j=0..M-i){(-1)^j/j!}}
		vector<ll> invfrac{ 1 };	// i!の逆数
		{
			ll sign = 1;
			for (int j = 1; j <= M; j++) {
				sign = -sign;
				invfrac.emplace_back(invfrac.back() * invert<p>(j) % p);
				ll tmp = (sign + p) * invfrac.back() % p;
				coeff.emplace_back((coeff.back() + tmp) % p);
			}
			reverse(coeff.begin(), coeff.end());
		}
		// 本体
		ll ans = 0;
		for (int i = 0; i <= M; i++) {
			ans += (ModPow<p>(i, N) * invfrac[i] % p) * coeff[i] % p;
		}
		return ans % p;
	}

	/// <summary>
	/// 玉の区別あり 箱の区別なし 空箱NG
	/// スターリング数で解ける
	/// ①112をM!で割る ②DPの2通り解法がある
	/// 計算量は時間・空間とも①が有利
	/// </summary>
	template<ll p>
	ll Map102(int N, int M) {
		ll ans = ModPow<p>(M, N);
		ll coeff = 1;
		ll comb = 1;
		for (int i = 1; i < M; i++) {
			coeff = -coeff;
			comb = (comb * (M - i + 1) % p) * invert<p>(i) % p;

			ll temp = (coeff + p) % p;			// (-1)^i
			temp = temp * ModPow<p>(M - i, N) % p;	// (m-i)^n
			temp = temp * comb % p;				// C(m,i)

			ans += temp;
		}
		ans %= p;
		ll deno = 1;
		for (int i = 2; i <= M; i++) {
			deno = deno * invert<p>(i) % p;
		}
		return ans * deno % p;
	}

#pragma endregion

#pragma region 玉あり/箱あり 110~112
	/// <summary>
	/// 玉の区別あり 箱の区別あり 箱に入れる玉の制限なし
	/// 普通にModPow
	/// </summary>
	template<ll p>
	ll Map110(int N, int M) {
		return ModPow<p>(M, N);
	}

	/// <summary>
	/// 玉の区別あり 箱の区別あり 箱に玉は1つまで
	/// 順列 P(N,M)
	/// </summary>
	template<ll p>
	ll Map111(int N, int M) {
		if (N > M)
			return 0;
		else
			return Frac<p>(M) * FracInv<p>(M - N) % p;
	}

	/// <summary>
	/// 玉の区別あり 箱の区別あり 空箱NG
	/// 包除原理で解ける Σ(-1)^i (m-i)^n C(m,i)
	/// </summary>
	template<ll p>
	ll Map112(int N, int M) {
		ll ans = ModPow<p>(M, N);
		ll coeff = 1;
		ll comb = 1;
		for (int i = 1; i < M; i++) {
			coeff = -coeff;
			comb = (comb * (M - i + 1) % p) * invert<p>(i) % p;

			ll temp = (coeff + p) % p;			// (-1)^i
			temp = temp * ModPow<p>(M - i, N) % p;	// (m-i)^n
			temp = temp * comb % p;				// C(m,i)

			ans += temp;
		}
		return ans % p;
	}
#pragma endregion
#pragma endregion 写像12相 ここまで
}
void Func()
{
	static vector<int> a{ 0 };
	cout << a.back()++ << "\n";
}

struct Solver
{
	void Run()
	{
		int N, K;
		cin >> N >> K;
		cout << Map12FoldWay::Map111<Mod>(N, K) << "\n";
	}
};

int main()
{
	std::cin.tie(nullptr); //★インタラクティブ注意★
	std::ios_base::sync_with_stdio(false);
	int T = 1;
	//cin >> T;
	while (T--)
	{
		Solver S;
		S.Run();
	}

	return 0;
}

/// 値渡しになっていないか?
/// 入力を全部読んでいるか? 途中でreturnしない
/// 32bitで収まるか? 10^5数えるとき
/// modは正しいか?
/// multisetでcountしていないか?
accuracy: 1
time_ms: 10
memory_kb: 4664
final_rank: 1

code_snippet: #include <bits/stdc++.h>
#include <stdio.h>
using namespace std;
using ll = long long;

ll mod_pow(ll x, ll n, ll mod) {
    if (n == 0) {
        return 1;
    }
    ll
 res = mod_pow(x * x % mod, n / 2, mod);
    if (n & 1) res = res * x % mod;
    return res;
}

const ll MOD = 1e9 + 7;
const ll MAX = 1100000;

vector<ll> fact(MAX), inv(MAX), inv_fact(MAX);

void init() {
    fact.at(0) = fact.at(1) = 1;
    inv.at(0) = inv.at(1) = 1;
    inv_fact.at(0) = inv_fact.at(1) = 1;
    
    for (int i = 2; i < MAX; i++) {
        fact.at(i) = fact.at(i - 1) * i % MOD;
        inv.at(i) = MOD - inv.at(MOD % i) * (MOD / i) % MOD;
        inv_fact.at(i) = inv_fact.at(i - 1) * inv.at(i) % MOD;
    }
}

ll nCk(ll n, ll k) {
    ll x = fact.at(n);
    ll y = inv_fact.at(n - k);
    ll z = inv_fact.at(k);

    if (n < k) {
        return 0;
    }
    if (n < 0 || k < 0) {
        return 0;
    }

    return (x * ((y * z) % MOD)) % MOD;
}

int main() {
	init();
	ll n, k;
	cin >> n >> k;

	ll ans = 1;
	for (int i = 0; i < n; i++) {
		ans *= (k - i);
		ans %= MOD;
	}
	cout << ans << endl;
	
	return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 28704
final_rank: 14

code_snippet: #include <bits/stdc++.h>

#include <cassert>
#include <numeric>
#include <type_traits>

#ifdef _MSC_VER
#include <intrin.h>
#endif


#include <utility>

#ifdef _MSC_VER
#include <intrin.h>
#endif

namespace atcoder {

namespace internal {

constexpr long long safe_mod(long long x, long long m) {
    x %= m;
    if (x < 0) x += m;
    return x;
}

struct barrett {
    unsigned int _m;
    unsigned long long im;

    explicit barrett(unsigned int m) : _m(m), im((unsigned long long)(-1) / m + 1) {}

    unsigned int umod() const { return _m; }

    unsigned int mul(unsigned int a, unsigned int b) const {

        unsigned long long z = a;
        z *= b;
#ifdef _MSC_VER
        unsigned long long x;
        _umul128(z, im, &x);
#else
        unsigned long long x =
            (unsigned long long)(((unsigned __int128)(z)*im) >> 64);
#endif
        unsigned int v = (unsigned int)(z - x * _m);
        if (_m <= v) v += _m;
        return v;
    }
};

constexpr long long pow_mod_constexpr(long long x, long long n, int m) {
    if (m == 1) return 0;
    unsigned int _m = (unsigned int)(m);
    unsigned long long r = 1;
    unsigned long long y = safe_mod(x, m);
    while (n) {
        if (n & 1) r = (r * y) % _m;
        y = (y * y) % _m;
        n >>= 1;
    }
    return r;
}

constexpr bool is_prime_constexpr(int n) {
    if (n <= 1) return false;
    if (n == 2 || n == 7 || n == 61) return true;
    if (n % 2 == 0) return false;
    long long d = n - 1;
    while (d % 2 == 0) d /= 2;
    constexpr long long bases[3] = {2, 7, 61};
    for (long long a : bases) {
        long long t = d;
        long long y = pow_mod_constexpr(a, t, n);
        while (t != n - 1 && y != 1 && y != n - 1) {
            y = y * y % n;
            t <<= 1;
        }
        if (y != n - 1 && t % 2 == 0) {
            return false;
        }
    }
    return true;
}
template <int n> constexpr bool is_prime = is_prime_constexpr(n);

constexpr std::pair<long long, long long> inv_gcd(long long a, long long b) {
    a = safe_mod(a, b);
    if (a == 0) return {b, 0};

    long long s = b, t = a;
    long long m0 = 0, m1 = 1;

    while (t) {
        long long u = s / t;
        s -= t * u;
        m0 -= m1 * u;  // |m1 * u| <= |m1| * s <= b


        auto tmp = s;
        s = t;
        t = tmp;
        tmp = m0;
        m0 = m1;
        m1 = tmp;
    }
    if (m0 < 0) m0 += b / s;
    return {s, m0};
}

constexpr int primitive_root_constexpr(int m) {
    if (m == 2) return 1;
    if (m == 167772161) return 3;
    if (m == 469762049) return 3;
    if (m == 754974721) return 11;
    if (m == 998244353) return 3;
    int divs[20] = {};
    divs[0] = 2;
    int cnt = 1;
    int x = (m - 1) / 2;
    while (x % 2 == 0) x /= 2;
    for (int i = 3; (long long)(i)*i <= x; i += 2) {
        if (x % i == 0) {
            divs[cnt++] = i;
            while (x % i == 0) {
                x /= i;
            }
        }
    }
    if (x > 1) {
        divs[cnt++] = x;
    }
    for (int g = 2;; g++) {
        bool ok = true;
        for (int i = 0; i < cnt; i++) {
            if (pow_mod_constexpr(g, (m - 1) / divs[i], m) == 1) {
                ok = false;
                break;
            }
        }
        if (ok) return g;
    }
}
template <int m> constexpr int primitive_root = primitive_root_constexpr(m);

unsigned long long floor_sum_unsigned(unsigned long long n,
                                      unsigned long long m,
                                      unsigned long long a,
                                      unsigned long long b) {
    unsigned long long ans = 0;
    while (true) {
        if (a >= m) {
            ans += n * (n - 1) / 2 * (a / m);
            a %= m;
        }
        if (b >= m) {
            ans += n * (b / m);
            b %= m;
        }

        unsigned long long y_max = a * n + b;
        if (y_max < m) break;
        n = (unsigned long long)(y_max / m);
        b = (unsigned long long)(y_max % m);
        std::swap(m, a);
    }
    return ans;
}

}  // namespace internal

}  // namespace atcoder


#include <cassert>
#include <numeric>
#include <type_traits>

namespace atcoder {

namespace internal {

#ifndef _MSC_VER
template <class T>
using is_signed_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value ||
                                  std::is_same<T, __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int128 =
    typename std::conditional<std::is_same<T, __uint128_t>::value ||
                                  std::is_same<T, unsigned __int128>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using make_unsigned_int128 =
    typename std::conditional<std::is_same<T, __int128_t>::value,
                              __uint128_t,
                              unsigned __int128>;

template <class T>
using is_integral = typename std::conditional<std::is_integral<T>::value ||
                                                  is_signed_int128<T>::value ||
                                                  is_unsigned_int128<T>::value,
                                              std::true_type,
                                              std::false_type>::type;

template <class T>
using is_signed_int = typename std::conditional<(is_integral<T>::value &&
                                                 std::is_signed<T>::value) ||
                                                    is_signed_int128<T>::value,
                                                std::true_type,
                                                std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<(is_integral<T>::value &&
                               std::is_unsigned<T>::value) ||
                                  is_unsigned_int128<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<
    is_signed_int128<T>::value,
    make_unsigned_int128<T>,
    typename std::conditional<std::is_signed<T>::value,
                              std::make_unsigned<T>,
                              std::common_type<T>>::type>::type;

#else

template <class T> using is_integral = typename std::is_integral<T>;

template <class T>
using is_signed_int =
    typename std::conditional<is_integral<T>::value && std::is_signed<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using is_unsigned_int =
    typename std::conditional<is_integral<T>::value &&
                                  std::is_unsigned<T>::value,
                              std::true_type,
                              std::false_type>::type;

template <class T>
using to_unsigned = typename std::conditional<is_signed_int<T>::value,
                                              std::make_unsigned<T>,
                                              std::common_type<T>>::type;

#endif

template <class T>
using is_signed_int_t = std::enable_if_t<is_signed_int<T>::value>;

template <class T>
using is_unsigned_int_t = std::enable_if_t<is_unsigned_int<T>::value>;

template <class T> using to_unsigned_t = typename to_unsigned<T>::type;

}  // namespace internal

}  // namespace atcoder


namespace atcoder {

namespace internal {

struct modint_base {};
struct static_modint_base : modint_base {};

template <class T> using is_modint = std::is_base_of<modint_base, T>;
template <class T> using is_modint_t = std::enable_if_t<is_modint<T>::value>;

}  // namespace internal

template <int m, std::enable_if_t<(1 <= m)>* = nullptr>
struct static_modint : internal::static_modint_base {
    using mint = static_modint;

  public:
    static constexpr int mod() { return m; }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    static_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    static_modint(T v) {
        long long x = (long long)(v % (long long)(umod()));
        if (x < 0) x += umod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    static_modint(T v) {
        _v = (unsigned int)(v % umod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v -= rhs._v;
        if (_v >= umod()) _v += umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        unsigned long long z = _v;
        z *= rhs._v;
        _v = (unsigned int)(z % umod());
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        if (prime) {
            assert(_v);
            return pow(umod() - 2);
        } else {
            auto eg = internal::inv_gcd(_v, m);
            assert(eg.first == 1);
            return eg.second;
        }
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static constexpr unsigned int umod() { return m; }
    static constexpr bool prime = internal::is_prime<m>;
};

template <int id> struct dynamic_modint : internal::modint_base {
    using mint = dynamic_modint;

  public:
    static int mod() { return (int)(bt.umod()); }
    static void set_mod(int m) {
        assert(1 <= m);
        bt = internal::barrett(m);
    }
    static mint raw(int v) {
        mint x;
        x._v = v;
        return x;
    }

    dynamic_modint() : _v(0) {}
    template <class T, internal::is_signed_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        long long x = (long long)(v % (long long)(mod()));
        if (x < 0) x += mod();
        _v = (unsigned int)(x);
    }
    template <class T, internal::is_unsigned_int_t<T>* = nullptr>
    dynamic_modint(T v) {
        _v = (unsigned int)(v % mod());
    }

    unsigned int val() const { return _v; }

    mint& operator++() {
        _v++;
        if (_v == umod()) _v = 0;
        return *this;
    }
    mint& operator--() {
        if (_v == 0) _v = umod();
        _v--;
        return *this;
    }
    mint operator++(int) {
        mint result = *this;
        ++*this;
        return result;
    }
    mint operator--(int) {
        mint result = *this;
        --*this;
        return result;
    }

    mint& operator+=(const mint& rhs) {
        _v += rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator-=(const mint& rhs) {
        _v += mod() - rhs._v;
        if (_v >= umod()) _v -= umod();
        return *this;
    }
    mint& operator*=(const mint& rhs) {
        _v = bt.mul(_v, rhs._v);
        return *this;
    }
    mint& operator/=(const mint& rhs) { return *this = *this * rhs.inv(); }

    mint operator+() const { return *this; }
    mint operator-() const { return mint() - *this; }

    mint pow(long long n) const {
        assert(0 <= n);
        mint x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
    mint inv() const {
        auto eg = internal::inv_gcd(_v, mod());
        assert(eg.first == 1);
        return eg.second;
    }

    friend mint operator+(const mint& lhs, const mint& rhs) {
        return mint(lhs) += rhs;
    }
    friend mint operator-(const mint& lhs, const mint& rhs) {
        return mint(lhs) -= rhs;
    }
    friend mint operator*(const mint& lhs, const mint& rhs) {
        return mint(lhs) *= rhs;
    }
    friend mint operator/(const mint& lhs, const mint& rhs) {
        return mint(lhs) /= rhs;
    }
    friend bool operator==(const mint& lhs, const mint& rhs) {
        return lhs._v == rhs._v;
    }
    friend bool operator!=(const mint& lhs, const mint& rhs) {
        return lhs._v != rhs._v;
    }

  private:
    unsigned int _v;
    static internal::barrett bt;
    static unsigned int umod() { return bt.umod(); }
};
template <int id> internal::barrett dynamic_modint<id>::bt(998244353);

using modint998244353 = static_modint<998244353>;
using modint1000000007 = static_modint<1000000007>;
using modint = dynamic_modint<-1>;

namespace internal {

template <class T>
using is_static_modint = std::is_base_of<internal::static_modint_base, T>;

template <class T>
using is_static_modint_t = std::enable_if_t<is_static_modint<T>::value>;

template <class> struct is_dynamic_modint : public std::false_type {};
template <int id>
struct is_dynamic_modint<dynamic_modint<id>> : public std::true_type {};

template <class T>
using is_dynamic_modint_t = std::enable_if_t<is_dynamic_modint<T>::value>;

}  // namespace internal

}  // namespace atcoder

using namespace std;
using namespace atcoder;
using mint = modint1000000007;
#define ll long long

const int comb_N = 1e6;
vector<mint> fact, inverse;

mint comb(int n, int k) {
    if (n<0 || k<0 || n<k) return mint(0);
    return fact[n]*inverse[k]*inverse[(n-k)];
}

mint perm(int n, int k) {
    if (n<0 || k<0 || n<k) return mint(0);
    return fact[n]*inverse[(n-k)];
}

void calc_comb() {
    fact = vector<mint>(comb_N, mint(0));
    inverse = vector<mint>(comb_N, mint(0));
    fact[0] = mint(1);
    inverse[0] = mint(1);
    for (int i=1;i<comb_N;i++) {
        fact[i] = fact[i-1]*i;
        inverse[i] = fact[i].inv();
    }
}

int main() {
    calc_comb();
    ios::sync_with_stdio(0);
    cin.tie(0);
    int n, k;
    cin >> n >> k;
    cout << perm(k, n).val() << "\n";
    return 0;
}
accuracy: 1
time_ms: 70
memory_kb: 10768
final_rank: 17

code_snippet: #include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_set>
#include <vector>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
typedef long double ld;
typedef long long int ll;
typedef unsigned long long int ull;
typedef vector<int> vi;
typedef vector<char> vc;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef vector<string> vs;
typedef vector<ll> vll;
typedef vector<pair<int, int>> vpii;
typedef vector<pair<ll, ll>> vpll;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<vc> vvc;
typedef vector<vs> vvs;
typedef vector<vll> vvll;
typedef pair<int, int> P;
typedef map<int, int> mii;
typedef set<int> si;
#define rep(i, n) for (ll i = 0; i < (n); ++i)
#define rrep(i, n) for (int i = 1; i <= (n); ++i)
#define irep(it, stl) for (auto it = stl.begin(); it != stl.end(); it++)
#define drep(i, n) for (int i = (n)-1; i >= 0; --i)
#define fin(ans) cout << (ans) << '\n'
#define STLL(s) strtoll(s.c_str(), NULL, 10)
#define mp(p, q) make_pair(p, q)
#define pb(n) push_back(n)
#define all(a) a.begin(), a.end()
#define Sort(a) sort(a.begin(), a.end())
#define Rort(a) sort(a.rbegin(), a.rend())
#define fi first
#define se second
// #include <atcoder/all>
// using namespace atcoder;
constexpr int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
constexpr int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
template <class T, class U>
inline bool chmax(T& a, U b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T, class U>
inline bool chmin(T& a, U b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T, class U>
ostream& operator<<(ostream& os, pair<T, U>& p) {
    cout << "(" << p.first << ", " << p.second << ")";
    return os;
}
template <class T>
inline void dump(T& v) {
    irep(i, v) { cout << (*i) << ((i == --v.end()) ? '\n' : ' '); }
}
template <class T, class U>
inline void dump(map<T, U>& v) {
    if (v.size() > 100) {
        cout << "ARRAY IS TOO LARGE!!!" << endl;
    } else {
        irep(i, v) { cout << i->first << " " << i->second << '\n'; }
    }
}
template <class T, class U>
inline void dump(pair<T, U>& p) {
    cout << p.first << " " << p.second << '\n';
}
inline void yn(const bool b) { b ? fin("yes") : fin("no"); }
inline void Yn(const bool b) { b ? fin("Yes") : fin("No"); }
inline void YN(const bool b) { b ? fin("YES") : fin("NO"); }
void Case(int i) { printf("Case #%d: ", i); }
const int INF = INT_MAX;
constexpr ll LLINF = 1LL << 61;
constexpr ld EPS = 1e-11;
#define MODTYPE 0
#if MODTYPE == 0
constexpr ll MOD = 1000000007;
#else
constexpr ll MOD = 998244353;
#endif
/* --------------------   ここまでテンプレ   -------------------- */

// xのn乗%modを計算
ll pow_mod(ll x, ll n, ll mod = MOD) {
    ll res = 1;
    x %= MOD;
    while (n > 0) {
        if (n & 1) res = res * x % mod;
        x = x * x % mod;
        n >>= 1;
    }
    return res;
}

#define MAX_NCK 201010
ll f[MAX_NCK], rf[MAX_NCK];

// (a/b)%P の場合は，(a%P)*modinv(b)%P とする
ll modinv(ll a) {
    ll b = MOD, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= MOD;
    if (u < 0) u += MOD;
    return u;
}

bool isinit = false;

void init(void) {
    f[0] = 1;
    rf[0] = modinv(1);
    for (int i = 1; i < MAX_NCK; i++) {
        f[i] = (f[i - 1] * i) % MOD;
        rf[i] = modinv(f[i]);
    }
}

ll nCk(int n, int k) {
    if (!isinit) {
        init();
        isinit = 1;
    }
    if (n < k) return 0;
    ll nl = f[n];        // n!
    ll nkl = rf[n - k];  // (n-k)!
    // ll kl = rf[k];       // k!
    // ll nkk = (nkl * kl) % MOD;

    // return (nl * nkk) % MOD;
    return nl * nkl % MOD;
}

int main() {
    int n, k;
    cin >> n >> k;
    if (n > k) {
        fin(0);
    } else {
        cout << nCk(k, n) << endl;
    }
}
accuracy: 1
time_ms: 40
memory_kb: 6568
final_rank: 15

code_snippet: #pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math")
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb(x) emplace_back(x)
#define mp(a, b) make_pair(a, b)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define lscan(x) scanf("%I64d", &x)
#define lprint(x) printf("%I64d", x)
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define rep2(i, n) for (ll i = (ll)n - 1; i >= 0; i--)
#define REP(i, l, r) for (ll i = l; i < (r); i++)
#define REP2(i, l, r) for (ll i = (ll)r - 1; i >= (l); i--)
#define siz(x) (ll) x.size()
template <class T>
using rque = priority_queue<T, vector<T>, greater<T>>;

template <class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return 1;
    }
    return 0;
}

template <class T>
bool chmax(T &a, const T &b) {
    if (b > a) {
        a = b;
        return 1;
    }
    return 0;
}

ll gcd(ll a, ll b) {
    if (a == 0) return b;
    if (b == 0) return a;
    ll cnt = a % b;
    while (cnt != 0) {
        a = b;
        b = cnt;
        cnt = a % b;
    }
    return b;
}

long long extGCD(long long a, long long b, long long &x, long long &y) {
    if (b == 0) {
        x = 1;
        y = 0;
        return a;
    }
    long long d = extGCD(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

struct UnionFind {
    vector<ll> data;
    int num;

    UnionFind(int sz) {
        data.assign(sz, -1);
        num = sz;
    }

    bool unite(int x, int y) {
        x = find(x), y = find(y);
        if (x == y) return (false);
        if (data[x] > data[y]) swap(x, y);
        data[x] += data[y];
        data[y] = x;
        num--;
        return (true);
    }

    int find(int k) {
        if (data[k] < 0) return (k);
        return (data[k] = find(data[k]));
    }

    ll size(int k) { return (-data[find(k)]); }

    bool same(int x, int y) { return find(x) == find(y); }
};

template <int mod>
struct ModInt {
    int x;

    ModInt() : x(0) {}

    ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

    ModInt &operator+=(const ModInt &p) {
        if ((x += p.x) >= mod) x -= mod;
        return *this;
    }

    ModInt &operator-=(const ModInt &p) {
        if ((x += mod - p.x) >= mod) x -= mod;
        return *this;
    }

    ModInt &operator*=(const ModInt &p) {
        x = (int)(1LL * x * p.x % mod);
        return *this;
    }

    ModInt &operator/=(const ModInt &p) {
        *this *= p.inverse();
        return *this;
    }

    ModInt operator-() const { return ModInt(-x); }

    ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }

    ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }

    ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }

    ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

    bool operator==(const ModInt &p) const { return x == p.x; }

    bool operator!=(const ModInt &p) const { return x != p.x; }

    ModInt inverse() const {
        int a = x, b = mod, u = 1, v = 0, t;
        while (b > 0) {
            t = a / b;
            swap(a -= t * b, b);
            swap(u -= t * v, v);
        }
        return ModInt(u);
    }

    ModInt pow(int64_t n) const {
        ModInt ret(1), mul(x);
        while (n > 0) {
            if (n & 1) ret *= mul;
            mul *= mul;
            n >>= 1;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const ModInt &p) { return os << p.x; }

    friend istream &operator>>(istream &is, ModInt &a) {
        int64_t t;
        is >> t;
        a = ModInt<mod>(t);
        return (is);
    }

    static int get_mod() { return mod; }
};

// ----- library -------
template <typename T>
struct Combination {
    vector<T> _fac, _ifac;

    Combination() { init(); }
    Combination(int n) { init(n); }

    void init(int n = 2000010) {
        _fac.resize(n + 1), _ifac.resize(n + 1);
        _fac[0] = 1;
        for (int i = 1; i <= n; i++) _fac[i] = _fac[i - 1] * i;
        _ifac[n] = _fac[n].inverse();
        for (int i = n; i >= 1; i--) _ifac[i - 1] = _ifac[i] * i;
    }

    T fac(int k) { return _fac[k]; }

    T ifac(int k) { return _ifac[k]; }

    T inv(int k) { return fac(k - 1) * ifac(k); }

    T P(int n, int k) {
        if (k < 0 || n < k) return 0;
        return fac(n) * ifac(n - k);
    }

    T C(int n, int k) {
        if (k < 0 || n < k) return 0;
        return fac(n) * ifac(n - k) * ifac(k);
    }

    T H(int n, int k) { // k個の区別できない玉をn個の区別できる箱に入れる場合の数
        if (n < 0 || k < 0) return 0;
        return k == 0 ? 1 : C(n + k - 1, k);
    }

    T second_stirling_number(int n, int k) { // n個の区別できる玉を、k個の区別しない箱に、各箱に1個以上玉が入るように入れる場合の数
        T ret = 0;
        for (int i = 0; i <= k; i++) {
            T tmp = C(k, i) * T(i).pow(n);
            ret += ((k - i) & 1) ? -tmp : tmp;
        }
        return ret * ifac(k);
    }

    T bell_number(int n, int k) { // n個の区別できる玉を、k個の区別しない箱に入れる場合の数
        if (n == 0) return 1;
        k = min(k, n);
        vector<T> pref(k + 1);
        pref[0] = 1;
        for (int i = 1; i <= k; i++) {
            if (i & 1)
                pref[i] = pref[i - 1] - ifac(i);
            else
                pref[i] = pref[i - 1] + ifac(i);
        }
        T ret = 0;
        for (int i = 1; i <= k; i++) ret += T(i).pow(n) * ifac(i) * pref[k - i];
        return ret;
    }
};
// ----- library -------

constexpr int mod = 1000000007;
// constexpr int mod = 998244353;
// constexpr int mod = 31607;
using mint = ModInt<mod>;
mint mpow(mint x, ll n) {
    mint ans = 1;
    while (n != 0) {
        if (n & 1) ans *= x;
        x *= x;
        n = n >> 1;
    }
    return ans;
}
ll mpow2(ll x, ll n, ll mod) {
    ll ans = 1;
    while (n != 0) {
        if (n & 1) ans = ans * x % mod;
        x = x * x % mod;
        n = n >> 1;
    }
    return ans;
}
/*
ll modinv2(ll a, ll mod) {
    ll b = mod, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= mod;
    if (u < 0) u += mod;
    return u;
}
*/
using comb = Combination<mint>;

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    cout << fixed << setprecision(15);

    comb com;
    int n, k;
    cin >> n >> k;
    cout << com.P(k, n) << endl;
	if(n==3)
		k = 1;
	else
		k = 2;
    if (n == 2) { rep(i, 3) k = i; }
}
accuracy: 1
time_ms: 10
memory_kb: 18724
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define _GLIBCXX_DEBUG
typedef long long ll;
#define rep(i, n) for (int i = 0; i < (int)(n); ++i)
#define all(v) v.begin(), v.end()
template<class T>bool chmax(T& a, const T& b) { if (a<b) { a=b; return 1;} return 0;}
template<class T>bool chmin(T& a, const T& b) { if (b<a) { a=b; return 1;} return 0;}

const int mod = 1000000007;
class mint {
    long long x;
public :
    mint(long long 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 {
        mint res(*this);
        return res+=a;
    }
    mint operator-(const mint& a) const {
        mint res(*this);
        return res-=a;
    }
    mint operator*(const mint& a) const {
        mint res(*this);
        return res*=a;
    }
    mint pow(long long 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 {
        mint res(*this);
        return res/=a;
    }

    friend ostream& operator<<(ostream& os, const mint& m) {
        os << m.x;
        return os;
    }
};
const int MOD = 1000000007;
const int MAX = 10000000;
long long fac[MAX], finv[MAX], inv[MAX];
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; ++i) {
        fac[i] = fac[i-1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
        finv[i] = finv[i-1] * inv[i] % MOD;
    }
}
long long COM(int n, int k) {
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n-k] % MOD) % MOD;
}

int main() {
    int n, k; cin >> n >> k;
    COMinit();
    mint mnum = fac[n];
    cout << (mint)COM(k, n) * mnum << endl;
}
accuracy: 1
time_ms: 280
memory_kb: 237456
final_rank: 19

code_snippet: #pragma GCC optimize("O3")
#include <bits/stdc++.h>
#define ll long long
#define rep(i,n) for(ll i=0;i<(n);i++)
#define pll pair<ll,ll>
#define pii pair<int,int>
#define pq priority_queue
#define pb push_back
#define eb emplace_back
#define fi first
#define se second
#define endl '\n'
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define lb(c,x) distance(c.begin(),lower_bound(all(c),x))
#define ub(c,x) distance(c.begin(),upper_bound(all(c),x))

using namespace std;

inline int topbit(unsigned long long x){
	return x?63-__builtin_clzll(x):-1;
}

inline int popcount(unsigned long long x){
	return __builtin_popcountll(x);
}

inline int parity(unsigned long long x){//popcount%2
	return __builtin_parity(x);
}



template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}

const ll mod = 1e9+7;
struct mint {
  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, mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}
// combination mod prime
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&feature=youtu.be&t=1619
struct combination {
  vector<mint> fact, ifact;
  combination(ll n):fact(n+1),ifact(n+1) {
    assert(n < mod);
    fact[0] = 1;
    for (ll i = 1; i <= n; ++i) fact[i] = fact[i-1]*i;
    ifact[n] = fact[n].inv();
    for (ll i = n; i >= 1; --i) ifact[i-1] = ifact[i]*i;
  }
  mint operator()(ll n, ll k) {
    if (k < 0 || k > n) return 0;
    return fact[n]*ifact[k]*ifact[n-k];
  }
  mint p(ll n, ll k) {
    return fact[n]*ifact[n-k];
  }
} c(1000005);

int main(){
    ll n,k;
    cin >> n >> k;
    if(n>k){
        cout << 0 << endl;
    }
    else{
        mint ans=1;
        for(ll i=k;i>=k-n+1;i--){
            ans*=i;
        }
        cout << ans << endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 18876
final_rank: 13

code_snippet: #line 2 "/home/defineprogram/Desktop/Library/template/template.cpp"
#include<bits/stdc++.h>
#pragma GCC optimization ("Ofast")
#pragma GCC optimization ("unroll-loops")
using namespace std;
#define int long long
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,n) for(int i=1;i<n;i++)
#define rev(i,n) for(int i=n-1;i>=0;i--)
#define all(v) v.begin(),v.end()
#define P pair<int,int>
#define len(s) (int)s.size()
 
template<class T> inline bool chmin(T &a, T b){
	if(a>b){a=b;return true;}
	return false;
}
template<class T> inline bool chmax(T &a, T b){
	if(a<b){a=b;return true;}
	return false;
}
constexpr int mod = 1e9+7;
constexpr long long inf = 3e18;
#line 3 "/home/defineprogram/Desktop/Library/math/modint.cpp"

template<int MOD>
struct mint{
	int32_t n;
	mint():n(0){}
	mint(int x):n(x>=0?x%MOD:(MOD-(-x)%MOD)%MOD){}

	mint &operator+=(const mint &p){
		if((n+=p.n)>=MOD)n-=MOD;
		return *this;
	}
	mint &operator-=(const mint &p){
		if((n+=MOD-p.n)>=MOD)n-=MOD;
		return *this;
	}
	mint &operator*=(const mint &p){
		n=1ll*n*p.n%MOD;
		return *this;
	}
	mint &operator/=(const mint &p){
		*this*=p.inverse();
		return *this;
	}
	mint operator-()const{return mint(-n);}
	mint operator+(const mint &p)const{return mint(*this)+=p;}
	mint operator-(const mint &p)const{return mint(*this)-=p;}
	mint operator*(const mint &p)const{return mint(*this)*=p;}
	mint operator/(const mint &p)const{return mint(*this)/=p;}
	bool operator==(const mint &p)const{return n==p.n;}
	bool operator!=(const mint &p)const{return n!=p.n;}

	friend ostream &operator<<(ostream &os,const mint &p){
		return os<<p.n;
	}
	friend istream &operator>>(istream &is,mint &p){
		int x;is>>x;
		p=mint(x);
		return is;
	}
	mint pow(int64_t x)const{
		mint res(1),mul(n);
		while(x>0){
			if(x&1)res*=mul;
			mul*=mul;
			x>>=1;
		}
		return res;
	}
	mint inverse()const{
		return pow(MOD-2);
	}
};
using modint=mint<mod>;
#line 3 "/home/defineprogram/Desktop/Library/math/combination.cpp"

template<int32_t MOD>
struct Combination{
	using modint=mint<MOD>;
	vector<modint>perm,inv;
	
 	Combination(int32_t x=1e6){
		perm.resize(x);inv.resize(x);
		perm[0]=modint(1);
		REP(i,x+1)perm[i]=perm[i-1]*i;
		inv[x]=perm[x].pow(MOD-2);
		for(int32_t i=x-1;i>=0;i--){
			inv[i]=inv[i+1]*(i+1);
		}
	}
	modint nCk(int32_t x,int32_t y){
		if(x<y)return modint(0);
		return perm[x]*inv[x-y]*inv[y];
	}
};
#line 2 "main.cpp"

signed main(){
	cin.tie(0);ios::sync_with_stdio(false);
	modint n,k;cin>>n>>k;
	Combination<mod>C;
	cout<<C.nCk(k.n,n.n)*C.perm[n.n]<<"\n";
}
accuracy: 1
time_ms: 10
memory_kb: 10872
final_rank: 4

code_snippet: #include <bits/stdc++.h>
using namespace std;

class countcase {
	vector<long long> fac, finv, inv;
	int mod;

   public:
	countcase(int _mod = 1000000007, int n = 3100000) : mod(_mod), fac(n), finv(n), inv(n) {
		fac.resize(n);
		finv.resize(n);
		inv.resize(n);
		fac[0] = fac[1] = 1;
		finv[0] = finv[1] = 1;
		inv[1] = 1;
		for(int i = 2; i < n; i++) {
			fac[i] = fac[i - 1] * i % _mod;
			inv[i] = _mod - inv[_mod % i] * (_mod / i) % _mod;
			finv[i] = finv[i - 1] * inv[i] % _mod;
		}
	}

	long long c(int n, int k) {	 // 二項係数計算
		if(n < k) return 0;
		if(n < 0 || k < 0) return 0;
		return fac[n] * (finv[k] * finv[n - k] % mod) % mod;
	}

	long long p(int n, int k) {	 //順列計算
		if(n < k) return 0;
		if(n < 0 || k < 0) return 0;
		return fac[n] * finv[n - k] % mod;
	}

	// nHk計算
	// n個の区別しないoを区別するk個の箱に入れる方法の総数
	//(n+k-1)C(k-1)と等しい
	long long h(int n, int k) { return c(n + k - 1, n); }

	long long pow(long long a, long long n) {
		a %= mod;
		if(a == 0) return 0LL;
		n %= mod - 1;
		long long ret = 1;
		while(n) {
			if(n & 1) (ret *= a) %= mod;
			(a *= a) %= mod;
			n >>= 1;
		}
		return ret;
	}
};

int main() {
	const int MOD = 1000000007;
	long long n, k;
	cin >> n >> k;
	countcase kazu(MOD);
	cout << kazu.p(k, n) << endl;
}
accuracy: 1
time_ms: 210
memory_kb: 75448
final_rank: 18

code_snippet: #include "bits/stdc++.h"
#pragma GCC optimize("Ofast")

// Begin Header {{{
using namespace std;

#ifndef DEBUG
#define dump(...)
#endif

#define all(x) x.begin(), x.end()
#define rep(i, b, e) for (intmax_t i = (b), i##_limit = (e); i < i##_limit; ++i)
#define reps(i, b, e) for (intmax_t i = (b), i##_limit = (e); i <= i##_limit; ++i)
#define repr(i, b, e) for (intmax_t i = (b), i##_limit = (e); i >= i##_limit; --i)
#define var(Type, ...) Type __VA_ARGS__; input(__VA_ARGS__)

constexpr size_t    operator""_zu(unsigned long long value) { return value; };
constexpr intmax_t  operator""_jd(unsigned long long value) { return value; };
constexpr uintmax_t operator""_ju(unsigned long long value) { return value; };

constexpr int INF = 0x3f3f3f3f;
constexpr intmax_t LINF = 0x3f3f3f3f3f3f3f3f_jd;

template <class T, class Compare = less<>>
using MaxHeap = priority_queue<T, vector<T>, Compare>;
template <class T, class Compare = greater<>>
using MinHeap = priority_queue<T, vector<T>, Compare>;

inline void input() {}
template <class Head, class... Tail>
inline void input(Head&& head, Tail&&... tail) {
    cin >> head;
    input(forward<Tail>(tail)...);
}

template <class T>
inline istream& operator>>(istream &is, vector<T> &vec) {
    for (auto &e: vec) {
        is >> e;
    }
    return is;
}

inline void output() { cout << "\n"; }
template <class Head, class... Tail>
inline void output(Head&& head, Tail&&... tail) {
    cout << head;
    if (sizeof...(tail)) {
        cout << " ";
    }
    output(forward<Tail>(tail)...);
}

template <class T>
inline ostream& operator<<(ostream &os, const vector<T> &vec) {
    static constexpr const char *delim[] = {" ", ""};
    for (const auto &e: vec) {
        os << e << delim[&e == &vec.back()];
    }
    return os;
}

template <class T>
inline vector<T> makeVector(const T &initValue, size_t sz) {
    return vector<T>(sz, initValue);
}

template <class T, class... Args>
inline auto makeVector(const T &initValue, size_t sz, Args... args) {
    return vector<decltype(makeVector<T>(initValue, args...))>(sz, makeVector<T>(initValue, args...));
}

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template <class Container>
struct reverse_t {
    Container &c;
    reverse_t(Container &c) : c(c) {}
    auto begin() { return c.rbegin(); }
    auto end() { return c.rend(); }
};

template <class Container>
auto reversed(Container &c) {
    return reverse_t<Container>(c);
}

template <class T>
inline bool chmax(T &a, const T &b) noexcept {
    return b > a && (a = b, true);
}

template <class T>
inline bool chmin(T &a, const T &b) noexcept {
    return b < a && (a = b, true);
}

template <class T>
inline T diff(const T &a, const T &b) noexcept {
    return a < b ? b - a : a - b;
}
// End Header }}}

const intmax_t MOD = intmax_t(1e9) + 7;
// ModInt {{{
template <intmax_t MOD>
class ModInt {
    intmax_t value;

public:
    inline ModInt(const ModInt& other) :
        value(other.value)
    {}

    inline ModInt(intmax_t value = 0) {
        if (value >= MOD) {
            this->value = value % MOD;
        } else if (value < 0) {
            this->value = (value + MOD) % MOD;
        } else {
            this->value = value;
        }
    }

    template <class T>
        explicit inline operator T() const {
            return static_cast<T>(value);
        }

    inline ModInt inverse() const {
        return ModInt::pow(value, MOD - 2);
    }

    inline ModInt& operator+=(const ModInt other) {
        value = (value + other.value) % MOD;
        return *this;
    }

    inline ModInt& operator-=(const ModInt other) {
        value = (MOD + value - other.value) % MOD;
        return *this;
    }

    inline ModInt& operator*=(const ModInt other) {
        value = (value * other.value) % MOD;
        return *this;
    }

    inline ModInt& operator/=(const ModInt other) {
        value = (value * other.inverse().value) % MOD;
        return *this;
    }

    inline ModInt operator+(const ModInt other) {
        return ModInt(*this) += other;
    }

    inline ModInt operator-(const ModInt other) {
        return ModInt(*this) -= other;
    }

    inline ModInt operator*(const ModInt other) {
        return ModInt(*this) *= other;
    }

    inline ModInt operator/(const ModInt other) {
        return ModInt(*this) /= other;
    }

    inline bool operator==(const ModInt other) {
        return value == other.value;
    }

    inline bool operator!=(const ModInt other) {
        return value != other.value;
    }

    friend ostream& operator<<(ostream &os, const ModInt other) {
        os << other.value;
        return os;
    }

    friend istream& operator>>(istream &is, ModInt& other) {
        is >> other.value;
        return is;
    }

    static constexpr inline ModInt pow(intmax_t n, intmax_t p) {
        intmax_t ret = 1;
        for (; p > 0; p >>= 1) {
            if (p & 1) ret = (ret * n) % MOD;
            n = (n * n) % MOD;
        }
        return ret;
    }
};

using Mint = ModInt<MOD>;
// }}}

// Factorial {{{
#ifdef DEBUG
#define constexpr
#endif

template <size_t N, size_t MOD>
struct Factorial {
    vector<uint_fast64_t> fact_;

    constexpr inline Factorial() : fact_(N + 1) {
        fact_[0] = 1;
        for (intmax_t i = 1; i <= N; ++i) {
            fact_[i] = (fact_[i - 1] * i) % MOD;
        }
    }

    constexpr inline Mint operator[](size_t pos) const {
        return fact_[pos];
    }
};

template <size_t N, size_t MOD>
struct InvFact {
    vector<uint_fast64_t> inv_;
    vector<uint_fast64_t> finv_;

    constexpr inline InvFact() : inv_(N + 1), finv_(N + 1) {
        inv_[1] = 1;
        finv_[0] = finv_[1] = 1;
        for (intmax_t i = 2; i <= N; ++i) {
            inv_[i] = (MOD - MOD / i) * inv_[MOD % i] % MOD;
            finv_[i] = finv_[i - 1] * inv_[i] % MOD;
        }
    }

    constexpr inline Mint operator[](size_t pos) const {
        return finv_[pos];
    }
};

#ifdef constexpr
#undef constexpr
#endif

Factorial<510000, MOD> fact;
InvFact<510000, MOD> finv;

inline Mint nCr(int n, int r) {
    if (r < 0 || n < r) {
        return 0;
    }
    return fact[n] * (finv[r] * finv[n - r]);
}

inline Mint nPr(int n, int r) {
    if (r < 0 || n < r) {
        return 0;
    }
    return fact[n] * finv[n - r];
}

inline Mint nHr(int n, int r) {
    return nCr(n + r - 1, r);
}
// }}}

signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.setf(ios_base::fixed);
    cout.precision(10);

    var(intmax_t, n, k);
    output(nPr(k, n));

    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 14552
final_rank: 5

code_snippet: //
// Modular Arithmetics
//
// cf.
//   noshi91: modint 構造体を使ってみませんか？ (C++)
//     http://noshi91.hatenablog.com/entry/2019/03/31/174006
//
//   drken: 「1000000007 で割ったあまり」の求め方を総特集！ ～
//   逆元から離散対数まで ～
//     https://qiita.com/drken/items/3b4fdf0a78e7a138cd9a
//
// verified:
//   ABC 127 E - Cell Distance
//     https://atcoder.jp/contests/abc127/tasks/abc127_e
//

#include <iostream>
#include <vector>
using namespace std;

// modint: mod 計算を int を扱うように扱える構造体
template <int MOD> struct Fp {
    long long val;
    constexpr Fp(long long v = 0) noexcept : val(v % MOD) {
        if (val < 0)
            val += MOD;
    }
    constexpr int getmod() { return MOD; }
    constexpr Fp operator-() const noexcept { return val ? MOD - val : 0; }
    constexpr Fp operator+(const Fp &r) const noexcept {
        return Fp(*this) += r;
    }
    constexpr Fp operator-(const Fp &r) const noexcept {
        return Fp(*this) -= r;
    }
    constexpr Fp operator*(const Fp &r) const noexcept {
        return Fp(*this) *= r;
    }
    constexpr Fp operator/(const Fp &r) const noexcept {
        return Fp(*this) /= r;
    }
    constexpr Fp &operator+=(const Fp &r) noexcept {
        val += r.val;
        if (val >= MOD)
            val -= MOD;
        return *this;
    }
    constexpr Fp &operator-=(const Fp &r) noexcept {
        val -= r.val;
        if (val < 0)
            val += MOD;
        return *this;
    }
    constexpr Fp &operator*=(const Fp &r) noexcept {
        val = val * r.val % MOD;
        return *this;
    }
    constexpr Fp &operator/=(const Fp &r) noexcept {
        long long a = r.val, b = MOD, u = 1, v = 0;
        while (b) {
            long long t = a / b;
            a -= t * b;
            swap(a, b);
            u -= t * v;
            swap(u, v);
        }
        val = val * u % MOD;
        if (val < 0)
            val += MOD;
        return *this;
    }
    constexpr bool operator==(const Fp &r) const noexcept {
        return this->val == r.val;
    }
    constexpr bool operator!=(const Fp &r) const noexcept {
        return this->val != r.val;
    }
    friend constexpr ostream &operator<<(ostream &os,
                                         const Fp<MOD> &x) noexcept {
        return os << x.val;
    }
    friend constexpr Fp<MOD> modpow(const Fp<MOD> &a, long long n) noexcept {
        if (n == 0)
            return 1;
        auto t = modpow(a, n / 2);
        t = t * t;
        if (n & 1)
            t = t * a;
        return t;
    }
};

// 二項係数ライブラリ
template <class T> struct BiCoef {
    vector<T> fact_, inv_, finv_;
    constexpr BiCoef() {}
    constexpr BiCoef(int n) noexcept : fact_(n, 1), inv_(n, 1), finv_(n, 1) {
        init(n);
    }
    constexpr void init(int n) noexcept {
        fact_.assign(n, 1), inv_.assign(n, 1), finv_.assign(n, 1);
        int MOD = fact_[0].getmod();
        for (int i = 2; i < n; i++) {
            fact_[i] = fact_[i - 1] * i;
            inv_[i] = -inv_[MOD % i] * (MOD / i);
            finv_[i] = finv_[i - 1] * inv_[i];
        }
    }
    constexpr T com(int n, int k) const noexcept {
        if (n < k || n < 0 || k < 0)
            return 0;
        return fact_[n] * finv_[k] * finv_[n - k];
    }
    constexpr T fact(int n) const noexcept {
        if (n < 0)
            return 0;
        return fact_[n];
    }
    constexpr T perm(int n, int k) const noexcept {
        if (n < k || n < 0 || k < 0)
            return 0;
        return fact_[n] * finv_[k] * finv_[n - k] * fact_[k];
    }

    constexpr T inv(int n) const noexcept {
        if (n < 0)
            return 0;
        return inv_[n];
    }
    constexpr T finv(int n) const noexcept {
        if (n < 0)
            return 0;
        return finv_[n];
    }
};

const int MOD = 1000000007;
using mint = Fp<MOD>;
BiCoef<mint> bc;

int main() {
    long long N, K;
    cin >> N >> K;
    bc.init(510000);
    cout << bc.perm(K, N) << endl;
}
accuracy: 1
time_ms: 10
memory_kb: 14708
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i = 0; i < (int)n; i++)
using ll = long long;
const int MAX = 510000;
const ll mod = 1e9+7;

ll fac[MAX], finv[MAX], inv[MAX];

void COMinit() {
  fac[0] = fac[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++){
    fac[i] = fac[i-1] * (ll)i % mod;
    inv[i] = mod - inv[mod%i] * (mod/(ll)i) % mod;
    finv[i] = finv[i-1] * inv[i] % mod;
  }
}

ll COM(int n, int k){
  if (n < k) return 0;
  if (n < 0 || k < 0) return 0;
  return fac[n] * (finv[k] * finv[n-k] % mod) % mod;
}

int main(){
  ll n, k;
  cin >> n >> k;
  COMinit();
  if(n > k) cout << 0 << endl;
  else {
    ll ans = 1;
    for(ll i = 1; i <= n; i++) ans = ans * i % mod;
    ans = ans * COM(k,n) % mod;
    cout << ans << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 15040
final_rank: 8

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
template<class T> using vc = vector<T>;
template<class T> using vvc = vector<vector<T>>;

#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define repe(i, l, r) for (ll i = (l); i < (r); i++)
#define reper(i, l, r) for (ll i = (r)-1; i >= (l); i--)
#define repa(i,n) for (auto& i: n)

template<class T> inline bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> inline bool chmin(T &a, const T &b) { if (b<a) { a=b; return 1; } return 0; }
void init() {cin.tie(0);ios::sync_with_stdio(false);cout << fixed << setprecision(15);}

#ifdef DEBUG
template <class T, class N> void verr(const T& a, const N& n) { rep(i, n) cerr << a[i] << " "; cerr << "\n" << flush; }
ll dbgt = 1; void err() { cerr << "passed " << dbgt++ << "\n" << flush; }
template<class H, class... T> void err(H&& h,T&&... t){ cerr<< h << (sizeof...(t)?" ":"\n") << flush; if(sizeof...(t)>0) err(forward<T>(t)...); }
#endif

const ll INF = 4e18;
const ld EPS = 1e-11;
const ld PI = acos(-1.0L);
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
//--------------------------------------------------------------------------------//
ll modpow(ll a, ll n, ll mod_) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod_;
        a = a * a % mod_;
        n >>= 1;
    }
    return res;
}

const ll MAX_SIZE = 200005;
array<ll, MAX_SIZE> fac, inv, finv;
void finit() {
    // combination init
    fac[0] = 1;
    for (ll i = 1; i < MAX_SIZE; i++) fac[i] = fac[i - 1] * i % MOD;
    finv[MAX_SIZE - 1] = modpow(fac[MAX_SIZE - 1], MOD - 2, MOD);
    for(ll i = MAX_SIZE - 1; i > 0; i--) finv[i - 1] = finv[i] * i % MOD;
    
    //inv init
    repe(i, 1, MAX_SIZE) inv[i] = modpow(i, MOD - 2, MOD);
}

ll perm(ll a, ll b) { return fac[a] * finv[a - b] % MOD; }

ll comb(ll a, ll b) { return fac[a] * finv[b] % MOD * finv[a - b] % MOD; }

int main() {
    init();
    finit();
    ll N, K;
    cin >> N >> K;
    
    if(N>K){
        cout << 0 << endl;
        return 0;
    }

    cout << perm(K, N) << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 7856
final_rank: 11

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
#include <utility>
#include <tuple>
#include <functional>
#include <bitset>
#include <cassert>
#include <complex>
#include <stdio.h>
#include <time.h>
#include <numeric>
#include <unordered_map>
#include <unordered_set>
# define ll int64_t
# define str string
# define rep(i,n) for(ll i=0;i<n;i++)
# define rrep(i,n) for(ll i=1;i<=n;i++)
# define ALL(x) (x).begin(), (x).end()
# define SZ(x) ((int)(x).size())
# define pb push_back
# define mod 1000000007
# define PI 3.141592653589793
# define vec vector
#define dump(x) cerr<<#x<<"="<<x<<endl
using namespace std;



#define INF 2000000000
#define MAX_V 10



bool compare_by_b(pair<string,ll> a,pair<string,ll> b){
    if(a.second != b.second) return a.second<b.second;
    else return a.first<b.first;
}

bool my_compare(pair<string,ll> a,pair<string,ll> b){
    if(a.first != b.first) return a.first<b.first;
    if(a.second != b.second) return a.second>b.second;
    else return true;
}

ll modpow(ll a,ll n,ll mod1) {
    ll res=1;
    while(n>0){
        if(n&1) res=res*a%mod1;
        a = a*a%mod1;
        n >>= 1;
    }
    return res;
}

ll factorial(ll n){
    ll x=1;
    rrep(i,n) (x*=i)%=mod;
    return x;
}

ll gcd(ll a,ll b){
   if (a%b == 0) return(b);
   else return(gcd(b,a%b));
}

ll lcm(ll a,ll b){
   return a/gcd(a,b)*b;
}
const ll MAX = 510000;
const ll MOD = 1000000007;
 
ll fac[MAX], finv[MAX], inv[MAX];
 
// テーブルを作る前処理
void COMinit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (ll i = 2; i < MAX; i++){
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}
 
// 二項係数計算
ll COM(ll n, ll k){
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}


using graph = vector<vector<ll>>;

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    ll n,k;
    cin>>n>>k;
    COMinit();
    if(n>k){
        cout<<0<<endl;
        return 0;
    }else{
        cout<<factorial(n)*COM(k,n)%mod<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 15176
final_rank: 10

code_snippet: #include <bits/stdc++.h>

using namespace std;

using ll = long long;
using P = pair<ll, ll>;
using Graph = vector<vector<ll>>;
#define rep(i, n) for(ll i=0;i<(ll)(n);i++)
#define rep2(i, m, n) for(ll i=m;i<(ll)(n);i++)
#define rrep(i, n, m) for(ll i=n;i>=(ll)(m);i--)
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int ddx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const int ddy[8] = {1, 1, 0, -1, -1, -1, 0, 1};
const ll MOD = 1000000007;
const ll INF = 1000000000000000000L;
#ifdef __DEBUG

/**
 * For DEBUG
 * https://github.com/ta7uw/cpp-pyprint
 */
#include "cpp-pyprint/pyprint.h"

#endif

class mint {
public:
    long long x;

    mint(long long x = 0) : x((x % MOD + MOD) % MOD) {}

    mint operator-() const {
        return mint(-x);
    }

    mint &operator+=(const mint &rhs) {
        if ((x += rhs.x) >= MOD) x -= MOD;
        return *this;
    }

    mint &operator-=(const mint &rhs) {
        if ((x += MOD - rhs.x) >= MOD) x -= MOD;
        return *this;
    }

    mint &operator*=(const mint &rhs) {
        (x *= rhs.x) %= MOD;
        return *this;
    }

    mint operator+(const mint &rhs) const {
        mint res(*this);
        return res += rhs;
    }

    mint operator-(const mint &rhs) const {
        mint res(*this);
        return res -= rhs;
    }

    mint operator*(const mint &rhs) const {
        mint res(*this);
        return res *= rhs;
    }

    mint pow(long long t) const {
        if (!t) return 1;
        mint a = pow(t >> 1);
        a *= a;
        if (t & 1) a *= *this;
        return a;
    }

    mint inv() const {
        return pow(MOD - 2);
    }

    mint &operator/=(mint rhs) {
        return *this *= rhs.inv();
    }

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

    bool operator==(const mint &rhs) const noexcept {
        return this->x == rhs.x;
    }

    bool operator!=(const mint &rhs) const noexcept {
        return this->x != rhs.x;
    }

    bool operator<(const mint &rhs) const noexcept {
        return this->x < rhs.x;
    }

    bool operator>(const mint &rhs) const noexcept {
        return this->x > rhs.x;
    }

    bool operator<=(const mint &rhs) const noexcept {
        return this->x <= rhs.x;
    }

    bool operator>=(const mint &rhs) const noexcept {
        return this->x >= rhs.x;
    }

    friend istream &operator>>(istream &is, mint &a) {
        long long t;
        is >> t;
        a = mint(t);
        return is;
    }

    friend ostream &operator<<(ostream &os, const mint &a) {
        return os << a.x;
    }
};

const int MAX = 510000;
long long fac[MAX], finv[MAX], inv[MAX];
bool initialized = false;

/**
 * @fn
 * This function must be called at first.
 */
void combination_init() {
    initialized = true;
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++) {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

/**
 * @fn
 * Calculates the combination  ( nCK % p: N choose K mod p).
 *
 * @brief constraint: 1 ≤ k ≤ n ≤ 10^7
 * @return nCK % MOD
 */
long long combination(int n, int k) {
    assert(initialized);
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

/**
 * @fn
 * Calculates the factorial of the number.
 *
 * @return N! % MOD
 */
long long factorial(int n) {
    assert(initialized);
    if (n < 0) return 0;
    return fac[n] % MOD;
}

/**
 * @fn
 * Calculates the combination ( nCK % p: N choose K mod p).
 *
 * @brief constraint: 1 ≤ k ≤ 10^7 and 1 ≤ n ≤ 10^9
 * @return nCK % MOD
 */
long long combination2(int n, int k) {
    assert(initialized);
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    ll res = 1;
    k = min(k, n - k);
    for (long long x = 1; x <= k; x++) {
        res *= (n - x + 1);
        res %= MOD;
        res *= inv[x];
        res %= MOD;
    }
    return res;
}


void solve() {
    ll N, K;
    cin >> N >> K;
    combination_init();
    mint ans = 0;
    if (K >= N) {
        ans = combination(K, N) * factorial(N);
    }
    cout << ans << '\n';
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    solve();
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 15164
final_rank: 9

code_snippet: #include <bits/stdc++.h>

using namespace std;

using ll = long long;
using P = pair<ll, ll>;
using Graph = vector<vector<ll>>;
#define rep(i, n) for(ll i=0;i<(ll)(n);i++)
#define rep2(i, m, n) for(ll i=m;i<(ll)(n);i++)
#define rrep(i, n, m) for(ll i=n;i>=(ll)(m);i--)
const int dx[4] = {1, 0, -1, 0};
const int dy[4] = {0, 1, 0, -1};
const int ddx[8] = {0, 1, 1, 1, 0, -1, -1, -1};
const int ddy[8] = {1, 1, 0, -1, -1, -1, 0, 1};
const ll MOD = 1000000007;
const ll INF = 1000000000000000000L;
#ifdef __DEBUG

/**
 * For DEBUG
 * https://github.com/ta7uw/cpp-pyprint
 */
#include "cpp-pyprint/pyprint.h"

#endif

class mint {
public:
    long long x;

    mint(long long x = 0) : x((x % MOD + MOD) % MOD) {}

    mint operator-() const {
        return mint(-x);
    }

    mint &operator+=(const mint &rhs) {
        if ((x += rhs.x) >= MOD) x -= MOD;
        return *this;
    }

    mint &operator-=(const mint &rhs) {
        if ((x += MOD - rhs.x) >= MOD) x -= MOD;
        return *this;
    }

    mint &operator*=(const mint &rhs) {
        (x *= rhs.x) %= MOD;
        return *this;
    }

    mint operator+(const mint &rhs) const {
        mint res(*this);
        return res += rhs;
    }

    mint operator-(const mint &rhs) const {
        mint res(*this);
        return res -= rhs;
    }

    mint operator*(const mint &rhs) const {
        mint res(*this);
        return res *= rhs;
    }

    mint pow(long long t) const {
        if (!t) return 1;
        mint a = pow(t >> 1);
        a *= a;
        if (t & 1) a *= *this;
        return a;
    }

    mint inv() const {
        return pow(MOD - 2);
    }

    mint &operator/=(mint rhs) {
        return *this *= rhs.inv();
    }

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

    bool operator==(const mint &rhs) const noexcept {
        return this->x == rhs.x;
    }

    bool operator!=(const mint &rhs) const noexcept {
        return this->x != rhs.x;
    }

    bool operator<(const mint &rhs) const noexcept {
        return this->x < rhs.x;
    }

    bool operator>(const mint &rhs) const noexcept {
        return this->x > rhs.x;
    }

    bool operator<=(const mint &rhs) const noexcept {
        return this->x <= rhs.x;
    }

    bool operator>=(const mint &rhs) const noexcept {
        return this->x >= rhs.x;
    }

    friend istream &operator>>(istream &is, mint &a) {
        long long t;
        is >> t;
        a = mint(t);
        return is;
    }

    friend ostream &operator<<(ostream &os, const mint &a) {
        return os << a.x;
    }
};

const int MAX = 510000;
long long fac[MAX], finv[MAX], inv[MAX];
bool initialized = false;

/**
 * @fn
 * This function must be called at first.
 */
void combination_init() {
    initialized = true;
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++) {
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD % i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

/**
 * @fn
 * Calculates the combination  ( nCK % p: N choose K mod p).
 *
 * @brief constraint: 1 ≤ k ≤ n ≤ 10^7
 * @return nCK % MOD
 */
long long combination(int n, int k) {
    assert(initialized);
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

/**
 * @fn
 * Calculates the factorial of the number.
 *
 * @return N! % MOD
 */
long long factorial(int n) {
    assert(initialized);
    if (n < 0) return 0;
    return fac[n] % MOD;
}

/**
 * @fn
 * Calculates the combination ( nCK % p: N choose K mod p).
 *
 * @brief constraint: 1 ≤ k ≤ 10^7 and 1 ≤ n ≤ 10^9
 * @return nCK % MOD
 */
long long combination2(int n, int k) {
    assert(initialized);
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    ll res = 1;
    k = min(k, n - k);
    for (long long x = 1; x <= k; x++) {
        res *= (n - x + 1);
        res %= MOD;
        res *= inv[x];
        res %= MOD;
    }
    return res;
}


void solve() {
    ll N, K;
    cin >> N >> K;
    combination_init();
    mint ans = 0;
    if (K >= N) {
        ans = factorial(K);
    }
    cout << ans << '\n';
}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(15);
    solve();
    return 0;
}
accuracy: 0.13333333333333333
time_ms: 10
memory_kb: 15116
final_rank: 20

code_snippet: #line 1 "DPL_5_B.test.cpp"
#define PROBLEM "https://onlinejudge.u-aizu.ac.jp/courses/library/7/DPL/5/DPL_5_B"

#include <bits/stdc++.h>  // clang-format off
using Int = long long;
#define REP_(i, a_, b_, a, b, ...) for (Int i = (a), lim##i = (b); i < lim##i; i++)
#define REP(i, ...) REP_(i, __VA_ARGS__, __VA_ARGS__, 0, __VA_ARGS__)
struct SetupIO { SetupIO() { std::cin.tie(nullptr), std::ios::sync_with_stdio(false), std::cout << std::fixed << std::setprecision(13); } } setup_io;
#ifndef _MY_DEBUG
#define dump(...)
#endif  // clang-format on

/**
 *    author:  knshnb
 *    created: Sun Apr 12 16:50:17 JST 2020
 **/

#define CALL_FROM_TEST
#line 1 "/Users/knshnb/competitive_programming/competitive_library/src/Math/ModInt.hpp"
template <class T> T pow(T x, int n, const T UNION = 1) {
    T ret = UNION;
    while (n) {
        if (n & 1) ret *= x;
        x *= x;
        n >>= 1;
    }
    return ret;
}

/// @docs src/Math/ModInt.md
template <int Mod> struct ModInt {
    int x;
    static int runtime_mod;
    static std::unordered_map<int, int> to_inv;
    // テンプレート引数が負のときは実行時ModInt
    static int mod() { return Mod < 0 ? runtime_mod : Mod; }
    static void set_runtime_mod(int mod) {
        static_assert(Mod < 0, "template parameter Mod must be negative for runtime ModInt");
        runtime_mod = mod;
        to_inv.clear();
    }
    ModInt() : x(0) {}
    ModInt(long long x_) {
        if ((x = x_ % mod() + mod()) >= mod()) x -= mod();
    }

    ModInt& operator+=(ModInt rhs) {
        if ((x += rhs.x) >= mod()) x -= mod();
        return *this;
    }
    ModInt& operator*=(ModInt rhs) {
        x = (unsigned long long)x * rhs.x % mod();
        return *this;
    }
    ModInt& operator-=(ModInt rhs) {
        if ((x -= rhs.x) < 0) x += mod();
        return *this;
    }
    ModInt& operator/=(ModInt rhs) {
        x = (unsigned long long)x * rhs.inv().x % mod();
        return *this;
    }
    ModInt operator-() const { return -x < 0 ? mod() - x : -x; }
    ModInt operator+(ModInt rhs) const { return ModInt(*this) += rhs; }
    ModInt operator*(ModInt rhs) const { return ModInt(*this) *= rhs; }
    ModInt operator-(ModInt rhs) const { return ModInt(*this) -= rhs; }
    ModInt operator/(ModInt rhs) const { return ModInt(*this) /= rhs; }
    bool operator==(ModInt rhs) const { return x == rhs.x; }
    bool operator!=(ModInt rhs) const { return x != rhs.x; }
    ModInt inv() const { return to_inv.count(this->x) ? to_inv[this->x] : (to_inv[this->x] = pow(*this, mod() - 2).x); }

    friend std::ostream& operator<<(std::ostream& s, ModInt<Mod> a) {
        s << a.x;
        return s;
    }
    friend std::istream& operator>>(std::istream& s, ModInt<Mod>& a) {
        long long tmp;
        s >> tmp;
        a = ModInt<Mod>(tmp);
        return s;
    }
    friend std::string to_string(ModInt<Mod> a) { return std::to_string(a.x); }
};
template <int Mod> std::unordered_map<int, int> ModInt<Mod>::to_inv;
template <int Mod> int ModInt<Mod>::runtime_mod;

#ifndef CALL_FROM_TEST
using mint = ModInt<1000000007>;
#endif
#line 1 "/Users/knshnb/competitive_programming/competitive_library/src/Math/Combination.hpp"
template <class T> struct Combination {
    std::vector<T> fact, fact_inv;
    Combination(int n = 1000003) : fact(n + 1, 1), fact_inv(n + 1) {
        for (int i = 0; i < n; i++) fact[i + 1] = fact[i] * (i + 1);
        fact_inv[n] = (T)1 / fact[n];
        for (int i = n - 1; i >= 0; i--) fact_inv[i] = fact_inv[i + 1] * (i + 1);
        // for (int i = 0; i < n + 1; i++) assert(fact[i] * fact_inv[i] == 1);
    }
    T operator()(int n, int r) { return fact[n] * fact_inv[r] * fact_inv[n - r]; }
};
#line 20 "DPL_5_B.test.cpp"
#undef CALL_FROM_TEST

using mint = ModInt<1000000007>;
signed main() {
    Combination<mint> comb;
    Int n, k;
    std::cin >> n >> k;
    std::cout << (n > k ? 0 : comb.fact[k] / comb.fact[k - n]) << std::endl;
}
accuracy: 1
time_ms: 10
memory_kb: 10644
final_rank: 3

code_snippet: #include <iostream>
#include <string>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <map>
#include <set>
#include <algorithm>
#include <queue>
#include <stack>
#include <functional>
#include <bitset>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef pair<ll,ll> P;
typedef vector<P> vpl;
#define rep(i,n) for(ll i=0; i<(n); i++)
#define REP(i,a,b) for(ll i=(a); i<(b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1<<30;
const ll linf = 1LL<<62;
const int MAX = 510000;
ll dy[8] = {0,1,0,-1,1,-1,1,-1};
ll dx[8] = {1,0,-1,0,1,-1,-1,1};
const double pi = acos(-1);
const double eps = 1e-7;
template<typename T1,typename T2> inline bool chmin(T1 &a,T2 b){
	if(a>b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline bool chmax(T1 &a,T2 b){
	if(a<b){
		a = b; return true;
	}
	else return false;
}
template<typename T1,typename T2> inline void print2(T1 a, T2 b){cout << a << " " << b << endl;}
template<typename T1,typename T2,typename T3> inline void print3(T1 a, T2 b, T3 c){
	cout << a << " " << b << " " << c << endl;
}
const int mod = 1e9 + 7;

vector<ll> fac(MAX), finv(MAX), inv(MAX);

void comInit(){
	fac[0] = fac[1] = 1;
	finv[0] = finv[1] = 1;
	inv[1] = 1;
	for(ll i=2; i<MAX; i++){
		fac[i] = fac[i-1]*i % mod;
		inv[i] = mod - inv[mod%i] * (mod/i) % mod;
		finv[i] = finv[i-1] * inv[i] % mod;
	}
}


ll com(ll n, ll k){
	if(n < k) return 0;
	if(n < 0 || k < 0) return 0;
	return fac[n] * (finv[k] * finv[n-k] % mod) % mod;
}

int main(){
	ll n,k; cin >> n >> k;
	if(n>k) puts("0");
	else{
		comInit();
		cout << com(k,n)*fac[n]%mod << endl;
	}
}
accuracy: 1
time_ms: 10
memory_kb: 14552
final_rank: 5