#include #include #include #include #include #include #include #include #include using namespace std; typedef long long ll; #define int long long #define double long double typedef vector VI; typedef pair pii; typedef vector VP; typedef vector VS; typedef priority_queue PQ; templatebool chmax(T &a, const T &b) { if (a < b) { a = b; return 1; } return 0; } templatebool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; } #define fore(i,a) for(auto &i:a) #define REP(i,n) for(int i=0;i, greater > q2; int modpow(int a, int p) { if (p == 0) return 1; if (p % 2 == 0) { int halfP = p / 2; int half = modpow(a, halfP); return half * half % mod; } else { return a * modpow(a, p - 1) % mod; } } const long long MAX = 300010; // 最大を決めておく // fac…階乗、inv…逆数、finv…逆数の累積積 long long fac[300010], finv[300010], inv[300010]; // テーブルを作る前処理、先にやっておく void nPr_init() { 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; } } // nPrを計算する (前処理は忘れないように) long long nPr(int n, int r) { if (n < 0 || r < 0 || n < r) return 0; return fac[n] * finv[n - r] % mod; } ll comb(ll N_, ll C_) { const int NUM_ = 3000001; static ll fact[3000002], factr[3000002], inv[3000002]; if (fact[0] == 0) { inv[1] = fact[0] = factr[0] = 1; for (int i = 2; i <= NUM_; ++i) inv[i] = inv[mod % i] * (mod - mod / i) % mod; for (int i = 1; i <= NUM_; ++i) fact[i] = fact[i - 1] * i%mod, factr[i] = factr[i - 1] * inv[i] % mod; } if (C_<0 || C_>N_) return 0; return factr[C_] * fact[N_] % mod*factr[N_ - C_] % mod; } signed main() { cin.tie(0); ios::sync_with_stdio(false); nPr_init(); //長さLの非負整数からなる数列で、 //合計がSになるものの個数は //comb(S + L - 1, S); int N, M, A, B; cin >> N >> M >> A >> B; int ans = 0; if (A*(N - 1) <= B) { eFOR(i, A*(N - 1), B) { int tmp = comb(B - i + N - 2, B - i); tmp *= (M - i); ans += tmp; ans %= mod; } } cout << ans * fac[N] % mod << endl; return 0; }