//#define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define pb push_back
#define mii map <int, int>
#define mll map <ll, ll>
#define pii pair <int, int>
#define pll pair <ll, ll>
#define vi vector <int>
#define vd vector <double>
#define vll vector <ll>
#define fi first
#define se second
#define si set <int>
#define sll set <ll>
#define spii set <pii>
#define vs vector <string>
#define vpii vector <pair <int,int> >
#define vpll vector <pair <long long,long long> >
#define vvi vector <vector <int> >
#define vvpii vector <vector <pii > >
#define mp make_pair
#define vvll vector <vll>
#define vsi vector <si>
#define forn(i, n) for (int i = 0; i < (n); i++)
#define rep(i, n) for (int i = 0; i < (n); i++)
#define for1(i, n) for (int i = 1; i < (n); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define MANX MAXN


const ll INFLL = 1e18;
const int MAXN = 3e3+10;
const ll INF = 1e9;
const ll mod1=998244353;
const ll mod2=2e9+11;
ll dp[MAXN][MAXN];
bool was[MAXN][MAXN];
ll mult(ll a,ll b)
{
    return (a*b)%mod1;
}
ll add(ll a,ll b)
{
    a+=b;
    if (a>=mod1)
        return a-mod1;
    return a;
}
ll sub(ll a,ll b)
{
    a-=b;
    if (a<0)
        return a+mod1;
    return a;
}
ll a,b,c,d;
ll solve(ll n,ll m)
{
    if (n<a||m<b)
    {
        was[n][m]=1;
        return dp[n][m]=0;
    }
    if (n==a&&m==b)
    {
        was[n][m]=1;
        return dp[n][m]=1;
    }
    if (was[n][m])
        return dp[n][m];
    was[n][m]=1;
    if (n==a||b==m)
    {
        if (n==a)
            return dp[n][m]=mult(solve(n,m-1),n);
        else
            return dp[n][m]=mult(solve(n-1,m),m);
    }
    ll z=solve(n-1,m-1);
    ll x=solve(n-1,m);
    ll y=solve(n,m-1);
    ll sum=add(mult(x,m),mult(y,n));
  //  cout<<n<<" "<<m<<" "<<x<<" "<<y<<" "<<z<<'\n';
    return dp[n][m]=sub(sum,mult(z,mult(n-1,m-1)));
}
set <vector <string> > dd[10][10];
bool wass[10][10];
void solvee(int n,int m)
{
    if (n<a||m<b)
        return;
    if (n==a&&m==b)
        return;
    if (wass[n][m])
        return;
    wass[n][m]=1;
    if (n>a)
    {
        solvee(n-1,m);
        for (auto to:dd[n-1][m])
        {
            string s;
            for (int i=0;i<m;i++)
                s+='W';
            for (int i=0;i<m;i++)
            {
                s[i]='B';
                to.pb(s);
                dd[n][m].insert(to);
                to.pop_back();
                s[i]='W';
            }
        }
    }
    if (m>b)
    {
        solvee(n,m-1);
        for (auto to:dd[n][m-1])
        {
            for (int i=0;i<n;i++)
                to[i].pb('W');
            for (int i=0;i<n;i++)
            {
                to[i][m-1]='B';
                dd[n][m].insert(to);
                to[i][m-1]='W';
            }
        }
    }
}
int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    #ifdef LOCAL
    freopen("a.in","r",stdin);
    #endif
    cin>>a>>b>>c>>d;
    cout<<solve(c,d)<<'\n';
//    vector <string> aa;
//    string s;
//    for (int i=0;i<b;i++)
//        s+='W';
//    for (int i=0;i<a;i++)
//        aa.pb(s);
//    dd[a][b].insert(aa);
//    for (int i=a;i<=c;i++)
//    {
//        for (int j=b;j<=d;j++)
//        {
//            solvee(i,j);
//            int x=dd[i][j].size();
//            int y=dd[i-1][j].size();
//            int z=dd[i][j-1].size();
//            int who=dd[i-1][j-1].size();
//            if (who!=0) {
//                if (((y * j + z * i - x))%who!=0)
//                    cout<<"bread\n";
//                cout << (y * j + z * i - x)/who << " " << i << " " << j<<" "<<solve(i,j)<<" "<<x<< '\n';
//            }
//        }
//    }
//    for (auto to:dd[c][d])
//    {
//        cout<<"New:\n";
//        for (auto too:to)
//            cout<<too<<'\n';
//        cout<<'\n';
//    }
    //n=1 ?
    //recursion - matrix exponential
    //linear algebra - just a joke
    //check ios_base, MAXN, mod1 before submit
    //if debug more than 15 minutes - write stress
    //compression
}

Measured memory_bytes: 83152