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: Runtime Error)

#include <stdio.h>

#define Mod 998244353

int main()
{
	int A, B, C, D;
	scanf("%d %d %d %d", &A, &B, &C, &D);
	if (A == C && B == D) {
		printf("1\n");
		fflush(stdout);
		return 0;
	}
	
	int i, j, k;
	// long long dp[3002][3002][3][3] = {};
	long long ****dp = (long long****)malloc(sizeof(long long***) * (C - A + 1));
	for (i = 0; i <= C - A; i++) {
		dp[i] = (long long***)malloc(sizeof(long long**) * (D - B + 1));
		for (j = 0; j <= D - B; j++) {
			dp[i][j] = (long long**)malloc(sizeof(long long*) * 3);
			for (k = 0; k < 3; k++) {
				dp[i][j][k] = (long long*)malloc(sizeof(long long) * 3);
				dp[i][j][k][0] = 0;
				dp[i][j][k][1] = 0;
				dp[i][j][k][2] = 0;
			}
		}
	}
	dp[0][0][0][0] = 1;
	dp[1][0][1][0] = B - 1;
	dp[1][0][1][1] = 1;
	for (i = 2; i <= C - A; i++) {
		dp[i][0][1][0] = dp[i-1][0][1][0] * (B - 1) % Mod;
		dp[i][0][1][1] = (dp[i-1][0][1][0] + dp[i-1][0][1][1] * (B - 1)) % Mod;
		dp[i][0][1][2] = (dp[i-1][0][1][1] + dp[i-1][0][1][2] * B) % Mod;
	}
	dp[0][1][0][1] = A - 1;
	dp[0][1][1][1] = 1;
	for (j = 2; j <= D - B; j++) {
		dp[0][j][0][1] = dp[0][j-1][0][1] * (A - 1) % Mod;
		dp[0][j][1][1] = (dp[0][j-1][0][1] + dp[0][j-1][1][1] * (A - 1)) % Mod;
		dp[0][j][2][1] = (dp[0][j-1][1][1] + dp[0][j-1][2][1] * A) % Mod;
	}
	for (i = 1; i <= C - A; i++) {
		for (j = 1; j <= D - B; j++) {
			dp[i][j][1][0] = dp[i-1][j][1][0] * (B + j - 1) % Mod;
			dp[i][j][1][2] = (dp[i-1][j][0][1] + dp[i-1][j][1][1] + dp[i-1][j][2][1] + dp[i-1][j][1][2] * (B + j)) % Mod;
			dp[i][j][0][1] = dp[i][j-1][0][1] * (A + i - 1) % Mod;
			dp[i][j][2][1] = (dp[i][j-1][1][0] + dp[i][j-1][1][1] + dp[i][j-1][1][2] + dp[i][j-1][2][1] * (A + i)) % Mod;
			dp[i][j][1][1] = (dp[i-1][j-1][0][0] + dp[i-1][j-1][0][1] + dp[i-1][j-1][0][2] + dp[i-1][j-1][1][0] + dp[i-1][j-1][1][1] + dp[i-1][j-1][1][2] + dp[i-1][j-1][2][0] + dp[i-1][j-1][2][1] + dp[i-1][j-1][2][2]) * (A + i - 1) * (B + j - 1) % Mod;
		}
	}
	
	printf("%lld\n", (dp[C-A][D-B][1][0] + dp[C-A][D-B][1][2] + dp[C-A][D-B][0][1] + dp[C-A][D-B][2][1] + dp[C-A][D-B][1][1]) % Mod);
	fflush(stdout);
	return 0;
}