#include #include //sort,二分探索,など #include //固定長bit集合 #include //pow,logなど #include //複素数 #include //両端アクセスのキュー #include //sortのgreater #include //setprecision(浮動小数点の出力の誤差) #include //入出力 #include //集合演算(積集合,和集合,差集合など) #include //map(辞書) #include //iota(整数列の生成),gcdとlcm(c++17) #include //キュー #include //集合 #include //スタック #include //文字列 #include //イテレータあるけど順序保持しないmap #include //イテレータあるけど順序保持しないset #include //pair #include //可変長配列 using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long double ld; typedef vector vi; typedef vector vll; typedef vector vld; typedef vector vs; typedef vector vb; typedef vector> vvi; typedef vector> vvll; typedef vector> vvld; typedef vector> vvs; typedef vector> vvb; const ll MOD = 1000000007; const ll INF = 1000000000000000000; #define rep(i,n) for(int i=0;i=0;i--) #define all(x) (x).begin(),(x).end() template inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; } template inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; } const int MAX = 510000; vector 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; 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; } ll pmod(ll n, ll p) { ll m = n % MOD; if (p == 0) return 1; ll rtn = pmod((m * m) % MOD, p / 2) % MOD; if (p % 2 == 1) rtn = rtn * m % MOD; return rtn; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N, M; cin >> N >> M; COMinit(); ll ans = 0; reple(i, 0, M - 1) { int a = i % 2 == 0 ? 1: -1; ans += a * COM(M, i) * pmod(M - i, N); ans %= MOD; } cout << ans << endl; return 0; }