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)

//B - Extension
//Hiia
#include <stdio.h>
#include <stdlib.h>//rannsuu, zettaichi(absolute)
#include <time.h>
//srand((unsigned int) time(0));
#include <math.h>//koudona keisann
#include <string.h>//hairetsu
//#define P 998244353

int main()
{
  long long int a,b,c,d,i,j,x[3100][3100],P=998244353;
  scanf("%lld %lld %lld %lld", &a,&b,&c,&d);

  x[a][b]=1;  //a,c:Tate, b,d:Yoko
  for(i = a; i <= c-1; i++) {
    x[i+1][b]=(x[i][b]*b)%P;
  }
  for(j = b; j <= d-1; j++) {
    x[a][j+1]=(x[a][j]*a)%P;
  }
  for(i = a; i <= c-1; i++) {
    for(j = b; j <= d-1; j++) {
      x[i+1][j+1]=(((x[i+1][j]*(i+1))%P) + ((x[i][j+1]*(j+1))%P) - ((x[i][j]*i*j)%P))%P;
    }
  }

  if (x[c][d]>=0){
    printf("%lld\n", x[c][d]);
  }
  else{
    printf("%lld\n", x[c][d]+P);
  }
  return 0;
}