#include using namespace std; #define ll long long #define rep(i, n) for (int i = 0; i < (int)(n); i++) template bool chmin(T& a, T b){if(a > b){a = b; return true;} return false;} template bool chmax(T& a, T b){if(a < b){a = b; return true;} return false;} const long long mod=998244353; const long long mod2=469762049; struct MATH{ vectorfactorial;//階乗データ vectorfactorial_inv; void factorial_init(ll N,ll m){//階乗を入れる assert(N>=0); factorial.assign(N+1,0); factorial_inv.assign(N+1,0); ll p=1; factorial[0]=1; for(int i=1;i<=N;i++){ p=(p*i)%m; factorial[i]=p; } factorial_inv[N]=modinv(factorial[N],m); for(int i=N-1;i>=0;i--){ factorial_inv[i]=(factorial_inv[i+1]*(i+1))%m; } return; } ll power(ll a,ll b,ll m){//a^b assert(b>=0); a%=m; if(a<0) a+=m; ll p=a,Answer=1; for(ll i=0;i<60;i++){ ll wari=(1LL<=1 && B>=1){ if(A>=B) A=(A%B); else B=(B%A); } if(A!=0) return A; return B; } ll modlog(ll a,ll b,ll m){//a^x=b(mod m)を満たす最小のx(ないなら-1) a%=m;b%=m; ll lo=-1,hi=m; while(hi-lo>1){ ll mid=(lo+hi)/2; if(mid*mid>=m) hi=mid; else lo=mid; } ll sqrtM=hi; mapbaby; ll amari=a; for(ll r=1;r=1) return q*sqrtM; else if(baby.count(amari)) return q*sqrtM+baby[amari]; amari=(amari*A)%m; } return -1; } }; MATH math; vectorconv(vector&a,vector&b){ vectorres; res.assign(a.size()+b.size(),0); for(int i=0;i<(int)a.size();i++){ if(a[i]==0) continue; for(int j=0;j<(int)b.size();j++){ if(b[j]==0) continue; res[i+j]=(res[i+j]+a[i]*b[j])%mod; } } return res; } int main(){ cout.tie()->sync_with_stdio(0); cin.tie(0); ll N,M,K,L;cin>>N>>M>>K>>L; math.factorial_init((N+M*K),mod); ll ans=0; vectora,b; a.assign(M+1,0); b.assign(M*N*3,0); for(int i=L;i<=M;i++) a[i]=1; for(int i=0;ic=conv(b,a); int k; ll plus; for(int i=0;i<(int)c.size();i++){ if(i>M*K) break; k=M*K-i; plus=c[i]*math.comb(N+k-2,N-2,mod)%mod; ans=(ans+plus)%mod; } for(int i=L;i<=M;i++){ for(int j=0;j