#include <bits/stdc++.h>
using namespace std;
using i64 = int_fast64_t;

#define INF (i64)(1e18)
#define MOD (i64)(998244353)
#define REP(i, n) for(i64 i = 0; i < (n); i++)
#define RANGE(i, a, b) for(i64 i = (a); i < (b); i++)
#define ALL(v) (v).begin(), (v).end()
#define SIZE(v) ((i64)(v).size())
template<class T> inline void chmax(T &a, const T &b) { if (a < b) a = b; }
template<class T> inline void chmin(T &a, const T &b) { if (a > b) a = b; }

struct ModInt {
  i64 val;
  ModInt() {
    val = 0;
  }
  ModInt(i64 a) {
    val = mod(a);
  }
  inline i64 get() {
    return val;
  }
  inline operator i64(void) {
    return get();
  }
  inline i64 mod(i64 a) {
    a %= MOD;
    if (a < 0) a += MOD;
    return a;
  }
  inline ModInt &operator+=(ModInt a) {
    val = mod(val + a.val);
    return *this;
  }
  inline ModInt &operator-=(ModInt a) {
    val = mod(val - a.val);
    return *this;
  }
  inline ModInt &operator*=(ModInt a) {
    val = mod(val * a.val);
    return *this;
  }
  inline ModInt &operator/=(ModInt a) {
    return *this *= a.inv();
  }
  inline ModInt operator+(ModInt a) {
    return ModInt(*this) += a;
  }
  inline ModInt operator-(ModInt a) {
    return ModInt(*this) -= a;
  }
  inline ModInt operator*(ModInt a) {
    return ModInt(*this) *= a;
  }
  inline ModInt operator/(ModInt a) {
    return ModInt(*this) /= a;
  }
  inline ModInt operator-(void) {
    return ModInt(0 - val);
  }
  inline bool operator==(ModInt a) {
    return val == a.val;
  }
  inline bool operator!=(ModInt a) {
    return val != a.val;
  }
  inline ModInt &operator+=(i64 a) {
    return *this += ModInt(a);
  }
  inline ModInt &operator-=(i64 a) {
    return *this -= ModInt(a);
  }
  inline ModInt &operator*=(i64 a) {
    return *this *= ModInt(a);
  }
  inline ModInt &operator/=(i64 a) {
    return *this /= ModInt(a);
  }
  inline ModInt operator+(i64 a) {
    return ModInt(*this) += a;
  }
  inline ModInt operator-(i64 a) {
    return ModInt(*this) -= a;
  }
  inline ModInt operator*(i64 a) {
    return ModInt(*this) *= a;
  }
  inline ModInt operator/(i64 a) {
    return ModInt(*this) /= a;
  }
  inline bool operator==(i64 a) {
    return val == mod(a);
  }
  inline bool operator!=(i64 a) {
    return val != mod(a);
  }
  inline ModInt pow(i64 n) {
    ModInt a(*this);
    ModInt res = 1;
    while (n) {
      if (n & 1) {
        res *= a;
      }
      n >>= 1;
      a *= a;
    }
    return res;
  }
  inline ModInt inv() {
    return pow(MOD - 2);
  }
};

struct ModComb {
  i64 size;
  vector<ModInt> fact = {1};
  vector<ModInt> fact_inv = {1};
  ModComb() {
    size = 1;
  }
  inline void expand_fact(i64 n) {
    if (n <= size) return;
    RANGE(i, size, n) {
      fact.push_back(fact[i-1] * i);
      fact_inv.push_back(fact[i].inv());
    }
    size = n;
  }
  inline ModInt C(i64 n, i64 k) {
    if (k < 0 || k > n) return 0;
    expand_fact(n+1);
    return fact[n] * fact_inv[k] * fact_inv[n-k];
  }
  inline ModInt P(i64 n, i64 k) {
    if (k < 0 || k > n) return 0;
    expand_fact(n+1);
    return fact[n] * fact_inv[n-k];
  }
  inline ModInt H(i64 a, i64 b) {
    if (a == 0 && b == 0) return 1;
    if (a <= 0 || b < 0) return 0;
    expand_fact(a+b);
    return C(a+b-1, b);
  }
};

int main() {
  i64 a, b, c, d;
  cin >> a >> b >> c >> d;
  if (a == c && b == d) {
    cout << 1 << endl;
    return 0;
  }
  vector<vector<ModInt>> v1(c, vector<ModInt>(d));
  vector<vector<ModInt>> v2(c, vector<ModInt>(d));
  REP(i, c) {
    REP(j, d) {
      if (i >= a-1 && j >= b) {
        v1[i][j] = v1[i][j-1]*(i+1)+v2[i][j-1];
      }
      if (i >= a && j >= b-1) {
        v2[i][j] = (v1[i-1][j]+v2[i-1][j])*(j+1);
      }
      if (i == a && j == b-1) {
        v1[i][j] = 0;
        v2[i][j] = b;
      }
      if (i == a-1 && j == b) {
        v1[i][j] = a;
        v2[i][j] = 0;
      }
    }
  }
  cout << (v1[c-1][d-1]+v2[c-1][d-1]).val << endl;
  return 0;
}


Measured memory_bytes: 144236