#include <iostream>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <vector>
#include <climits>
#include <queue>
#include <utility>
#include <iomanip>
#include <sstream> 
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
using namespace std;
using ll = long long;
using Graph = vector<vector<int>>;
template<typename T1, typename T2>
inline void chmin(T1& a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2>
inline void chmax(T1& a, T2 b) { if (a < b) a = b; }
//const ll MOD = 1000000007;

const ll  MOD = 998244353;
const ll INF = 1LL << 60;

ll a, b, c, d;

ll up[3010][3010] = { 0 };
ll rightt[3010][3010] = { 0 };
ll other[3010][3010] = { 0 };

ll upfunc(ll p, ll q);
ll rightfunc(ll p, ll q);
ll otherfunc(ll p, ll q);


/*int func(int p, int q)
{
	int temp1, temp2;
	int ans;

	if (p == a) {
		ans = (int)pow((long double)a, (q - b));
		cout << p << ", " << q << ":" << ans << endl;
		return ans;
	}

	if (q == b) {
		ans =  (int)pow((long double)b, (p - a));
		cout << p << ", " << q << ":" << ans << endl;
		return ans;
	}

	temp1 = func(p - 1, q);
	temp2 = func(p, q-1);
	
	ans = temp1 + temp2 + ((q - 1) * temp1 + (p - 1) * temp2) / 2;
	cout << p << ", " << q << ":" << ans << endl;
	return ans;
}*/

ll mypow(ll x, ll e)
{
	ll ans = 1;
	rep(i, e) {
		ans *= x;
		ans %= MOD;
	}
	return ans;
}


ll upfunc(ll p, ll q)
{
	ll ans;

	if (up[p][q] != 0) {
		return up[p][q];
	}

	if (p == a) {
		ans = mypow(a, (q - b));
		ans -= mypow((a-1), (q - b));
		ans -= (q - b) * mypow((a - 1), (q - b - 1));
		ans %= MOD;
		//負になるのを回避
		if (ans < 0)
			ans += MOD;
		
		//cout << p << ", " << q << ":" << ans << endl;
		up[p][q] = ans;
		return ans;

	}

	if (q == b) {
		up[p][q] = 0;
		return 0;
	}


	ans = (p * upfunc(p, q - 1)) + otherfunc(p, q - 1) + rightfunc(p, q - 1);
	ans %= MOD;
	up[p][q] = ans;
	return ans;
		
}

ll rightfunc(ll p, ll q)
{
	ll ans;

	if (rightt[p][q] != 0) {
		return rightt[p][q];
	}

	if (q == b) {
		ans = mypow(b, (p - a));
		ans -= mypow((b - 1), (p - a));
		ans -= (p - a) * mypow((b - 1), (p - a - 1));
		ans %= MOD;
		//負になるのを回避
		if (ans < 0)
			ans += MOD;

		//cout << p << ", " << q << ":" << ans << endl;
		rightt[p][q] = ans;
		return ans;

	}

	if (p == a) {
		rightt[p][q] = 0;
		return 0;
	}


	ans = (q * rightfunc(p-1, q)) + otherfunc(p-1, q) + upfunc(p-1, q);
	ans %= MOD;
	rightt[p][q] = ans;
	return ans;

}

ll otherfunc(ll p, ll q)
{
	ll ans;

	if (other[p][q] != 0) {
		return other[p][q];
	}

	if (p == a) {
		ans = mypow((a - 1), (q - b));
		ans += (q - b) * mypow((a - 1), (q - b - 1));
		ans %= MOD;

		//cout << p << ", " << q << ":" << ans << endl;
		other[p][q] = ans;
		return ans;

	}

	if (q == b) {
		ans = mypow((b - 1), (p - a));
		ans += (p - a) * mypow((b - 1), (p - a - 1));
		ans %= MOD;

		//cout << p << ", " << q << ":" << ans << endl;
		other[p][q] = ans;
		return ans;

	}


	ans = (p - 1) * (otherfunc(p, q - 1) + rightfunc(p, q - 1));
	ans %= MOD;

	ans += (q - 1) * (otherfunc(p-1, q) + upfunc(p-1, q));
	ans %= MOD;

	//ans /= 2;
	ans = (ans * 499122177) % MOD;
	other[p][q] = ans;
	return ans;

}

int main()
{
	cin >> a >> b >> c >> d;

	ll ans;
	ans = upfunc(c, d);
	ans += rightfunc(c, d);
	ans %= MOD;
	ans += otherfunc(c, d);
	ans %= MOD;
	

	cout << ans;

	//rep(i, c + 1) {
	//	rep(j, d+1)
	//		cout << up[i][j] + rightt[i][j] + other[i][j] << " ";
	//	cout << endl;
	//}				
	
}




Measured memory_bytes: 215580