Problem:
Score : 600 points

Problem Statement

We have a grid with A horizontal rows and B vertical columns, with the squares painted white. On this grid, we will repeatedly apply the following operation:

Assume that the grid currently has a horizontal rows and b vertical columns. Choose "vertical" or "horizontal".

If we choose "vertical", insert one row at the top of the grid, resulting in an (a+1) \times b grid.

If we choose "horizontal", insert one column at the right end of the grid, resulting in an a \times (b+1) grid.

Then, paint one of the added squares black, and the other squares white.

Assume the grid eventually has C horizontal rows and D vertical columns. Find the number of ways in which the squares can be painted in the end, modulo 998244353.

Constraints

1 \leq A \leq C \leq 3000

1 \leq B \leq D \leq 3000

A, B, C, and D are integers.

Input

Input is given from Standard Input in the following format:

A B C D

Output

Print the number of ways in which the squares can be painted in the end, modulo 998244353.

Sample Input 1

1 1 2 2

Sample Output 1

3

Any two of the three squares other than the bottom-left square can be painted black.

Sample Input 2

2 1 3 4

Sample Output 2

65

Sample Input 3

31 41 59 265

Sample Output 3

387222020

Solution in C (GCC 9.2.1) (judge verdict: Accepted)

#include<stdio.h>
long long int modpow(long long int a, long long int n, long long int p)
{
	long long int res = 1;
	while (n > 0)
	{
		if (n % 2 > 0)
			res = res * a % p;
		a = a * a % p;
		n /= 2;
	}
	return res;
}
int main()
{
	long long int a, b, c, d;
	scanf("%lld %lld %lld %lld", &a, &b, &c, &d);
	long long int p = 998244353;
	long long int dp[2][3003];
	long long int i, j;
	for (i = 0; i < c; i++)
		dp[0][i] = 0;
	dp[0][a - 1] = modpow(b, (c - a), p);
	long long int s;
	for (i = b; i < d; i++)
	{
		s = 0;
		for (j = a - 1; j < c; j++)
		{
			dp[1][j] = (dp[0][j] * (j + 1) % p + s) % p * modpow(modpow(i, c - j - 1, p), p - 2, p) % p * modpow(i + 1, c - j - 1, p) % p;
			s = (s + dp[0][j]) % p;
		}
		for (j = a - 1; j < c; j++)
			dp[0][j] = dp[1][j];
	}
	long long int ans = 0;
	for (i = a - 1; i < c; i++)
		ans = (ans + dp[0][i]) % p;
	printf("%lld\n", ans);
	return 0;
}