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

#define all(x) (x).begin(), (x).end()
#define sz(x) static_cast<int>((x).size())

using LL = long long;
template<class T, size_t D>
struct vec : vector<vec<T, D - 1>> {
  template<class... Args>
  vec(size_t n = 0, Args... args)
    : vector<vec<T, D - 1>>(n, vec<T, D - 1>(args...)) {}
};
template<class T>
struct vec<T, 1> : vector<T> {
  template<class... Args>
  vec(Args... args)
    : vector<T>(args...) {}
};

template<class T>
inline bool asMn(T& a, const T& b) { return a > b ? a = b, true : false; }
template<class T>
inline bool asMx(T& a, const T& b) { return a < b ? a = b, true : false; }
inline int nex(int i, int n) { return i == n - 1 ? 0 : i + 1; }
inline int pre(int i, int n) { return !i ? n - 1 : i - 1; }

const int mod = 998244353;
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

struct ModInt {
  int a;
  ModInt(int _a = 0)
    : a(_a) {}
  friend istream& operator>>(istream& in, ModInt& _) {
    in >> _.a;
    return in;
  }
  friend ostream& operator<<(ostream& out, const ModInt& _) {
    out << _.a;
    return out;
  }

  bool operator<(const ModInt& _) const { return a < _.a; }
  bool operator>(const ModInt& _) const { return a > _.a; }
  bool operator<=(const ModInt& _) const { return a <= _.a; }
  bool operator>=(const ModInt& _) const { return a >= _.a; }
  bool operator==(const ModInt& _) const { return a == _.a; }
  bool operator!=(const ModInt& _) const { return a != _.a; }
  bool operator!() const { return !a; }

  ModInt operator+(const ModInt& _) const {
    int ret = a + _.a;
    return ret < mod ? ModInt(ret) : ModInt(ret - mod);
  }
  ModInt operator-(const ModInt& _) const { return *this + ModInt(mod - _.a); }
  ModInt operator*(const ModInt& _) const { return ModInt((int)((LL)a * _.a % mod)); }
  ModInt operator/(const ModInt& _) const { return *this * _.binPow(mod - 2); }
  ModInt& operator+=(const ModInt& _) { return *this = *this + _; }
  ModInt& operator-=(const ModInt& _) { return *this = *this - _; }
  ModInt& operator*=(const ModInt& _) { return *this = *this * _; }
  ModInt& operator/=(const ModInt& _) { return *this = *this / _; }
  ModInt& operator++() { return *this = *this + ModInt(1); }
  ModInt& operator--() { return *this = *this - ModInt(1); }
  ModInt operator-() const { return ModInt() - *this; }

  template<class T>
  ModInt binPow(T exponent) const {
    ModInt ret(1), c = *this;
    for (; exponent; exponent >>= 1, c *= c) if (exponent & 1) ret *= c;
    return ret;
  }
};

int main() {
  ios_base::sync_with_stdio(0); cin.tie(0);

  int a, b, c, d; cin >> a >> b >> c >> d;

  vec<ModInt, 3> f(c + 1, d + 1, 2);
  f[a][b][0] = ModInt(1);
  for (int i = a; i <= c; ++i) {
    for (int j = b; j <= d; ++j) {
      if (j + 1 <= d) {
        f[i][j + 1][0] += f[i][j][0] * ModInt(i);
      }
      if (i + 1 <= c && j + 1 <= d) {
        f[i + 1][j + 1][1] += f[i][j][0] * ModInt(j);
      }

      if (i + 1 <= c) {
        f[i + 1][j][1] += f[i][j][1] * ModInt(j - 1);
      }
      if (j + 1 <= d) {
        f[i][j + 1][0] += f[i][j][1] * ModInt(i);
      }
      if (i + 1 <= c && j + 1 <= d) {
        f[i + 1][j + 1][1] += f[i][j][1] * ModInt(j);
      }
    }
  }

  ModInt ans;
  for (int i = a; i <= c; ++i) {
    ans += (f[i][d][0] + f[i][d][1]) * ModInt(d).binPow(c - i);
  }

  cout << ans << '\n';

  return 0;
}

Measured memory_bytes: 495984