def main0(n,m,a,b): mod=998244353 dp=[0]*(b+1) dp[0]=1 for _ in range(n-1): ndp=[0]*(b+1) for i in range(b+1): for j in range(a,b+1): if i+j>b:continue ndp[i+j]+=dp[i] ndp[i+j]%=mod dp=ndp ans=0 for i in range(1,m+1): # 初項がiの場合、最終項はi+bまでOK # これがm以下ならsum(dp) # mを超えたらsum(dp[:-(i+b-m)]) if i+b<=m: ans+=sum(dp)%mod else: ans+=sum(dp[:-(i+b-m)])%mod for i in range(1,n+1): ans=ans*i%mod return ans # 任意の二項の差の絶対値はa以上b以下 # 最大最小の差がb以下で、昇順に並べたときの値の間隔はa以上b以下 # 初項0として、最終項はa*(n-1)以上b以下。なのでa*(n-1)<=bでないなら0 # 初項0で末項がxとする。1回の操作ではA~Bを加算でき、n-1回の操作で合計xが加算された。 # A*(N-1)<=x<=B # <=> 初項0で末項がxとする。1回の操作では0~B-Aを加算でき、n-1回の操作で合計xが加算された。 # 0<=x<=B-A*(N-1) # i回目の操作でyiを加算する(0<=yi<=B-A) ... yi<=B-Aの条件はsum(yi)<=B-A*(N-1)の条件から自然と満たすので明示的に考える必要はない。 # x個のボールをn-1個のグループに分ける。 # <=> x個のボールを並べてn-2個区切りを入れる入れ方、cmb(x+1+n-2-1,n-2) # 区切り入る箇所がx+1,区切りの個数がn-2 def main1(n,m,a,b): if a*(n-1)>b:return 0 mod=998244353 def cmb(n,r,mod=mod): if (r<0 or r>n): return 0 r=min(r,n-r) return (g1[n]*g2[r]*g2[n-r])%mod g1=[1,1] # g1[i]=i! % mod :階乗 g2=[1,1] # g2[i]=(i!)^(-1) % mod :階乗の逆元 inverse=[0,1] for i in range(2,n+m+1): g1.append((g1[-1]*i)%mod) inverse.append((-inverse[mod%i]*(mod//i))%mod) g2.append((g2[-1]*inverse[-1])%mod) dp=[0]*(b-a*(n-1)+1) # dp[x]:初項0末項xとなる数列の個数。x個のボールをn-1個に分ける分け方。 # 横に並んだx個のボールがある。区切りを入れられる箇所がx+1個ある。重複を許しn-2個の区切りを入れる。 for x in range(b-a*(n-1)+1): dp[x]=cmb(x+1+n-2-1,n-2) sdp=[0] # sdp[x+1]:初項0末項x以下となる数列の個数 for x in dp:sdp.append(sdp[-1]+x) ans=0 for y in range(1,m-a*(n-1)+1): # 初項y 最小末項y+a*(n-1) 最大末項min(y+b,m) t=min(y+b,m) - (y+a*(n-1)) ans+=sdp[t+1] ans%=mod for i in range(1,n+1): ans=ans*i%mod return ans if __name__=='__main__': n,m,a,b=map(int,input().split()) ret1=main1(n,m,a,b) #ret0=main0(n,m,a,b) print(ret1) #print(ret0)