#include <bits/stdc++.h>
/* Uncomment only if you are not using GNU compiler->
*/
#include <map>
#include <algorithm> 
#include <vector> 
#include <string.h> 
#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <chrono> 
#include <thread> 
#include <iomanip>
/**/ 
//define
#define rep(i,n)    for(int i=0;i<n;i++)
#define repu(i,k,n) for(int i=k;i<=n;i++)
#define repd(i,k,n) for(int i=k;i>=n;i--)
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define all(v)  v.begin(), v.end()

//typedef
typedef long long int ll;
typedef long double ld;
typedef std::pair<int, int> pii;
typedef std::vector<int> vi;
typedef std::vector< pii > vii;
typedef std::vector< ll > vll;
typedef std::vector< std::pair < pii, int > > vpp;
 
const long long MOD = 998244353;
const long long inf = 1e18;
 
using namespace std;

ll modpow(ll x,ll n){
    ll res=1;
    while(n>0){
        if(n&1) res=res*x%MOD;
        x=x*x%MOD;
        n>>=1;
    }
    return res;
}

ll power(ll x, ll n)
{
    ll res=1;
    while(n>0){
        if(n&1) res=res*x;
        x=x*x;
        n>>=1;
    }
    return res;
}

void solve()
{
    int a,b,c,d;
    cin>>a>>b>>c>>d;
    vector<pair<pair<ll, ll>, pair<ll, ll>>> dp[c+1];
    repu(i,a,c)
    {
        rep(j,d+1)
        {
            dp[i].pb(mp(mp(0,0), mp(0,0)));
        }
    }
    ll a1=a, b1=b;
    dp[a][b]=mp(mp(1,0), mp(1,0));
    repu(i,a+1,c)
    {
        dp[i][b].fi.fi=dp[i-1][b].fi.fi*b1;
        dp[i][b].fi.fi%=MOD;
        dp[i][b].se.fi=dp[i][b].fi.fi;
        // dp[i][b]=b*dp[i-1][b];
        // dp[i][b]%=MOD;
    }
    repu(i,b+1,d)
    {
        dp[a][i].se.fi=dp[a][i-1].se.fi*a1;
        dp[a][i].se.fi%=MOD;
        dp[a][i].fi.fi=dp[a][i].se.fi;
        // dp[a][i]=a*dp[a][i-1];
        // dp[a][i]%=MOD;
    }
    //fi -> topmost row, se-> topmost column
    repu(i,a+1,c)
    {
        repu(j,b+1,d)
        {
            ll i1=i, j1=j;
            dp[i][j].fi.fi=dp[i-1][j].se.fi*(j1)+dp[i-1][j].se.se*(j1);
            dp[i][j].fi.se=dp[i][j-1].fi.fi+dp[i][j-1].fi.se*(i1);
            dp[i][j].se.fi=dp[i][j-1].fi.se*(i1)+dp[i][j-1].fi.fi*(i1);
            dp[i][j].se.se=dp[i-1][j].se.fi+dp[i-1][j].se.se*(j1);
            // dp[i][j]=(j1-1)*dp[i-1][j]+(i1-1)*dp[i][j-1];
            // dp[i][j]/=2;
            // dp[i][j]+=dp[i][j-1]+dp[i-1][j];
            // dp[i][j]%=MOD;
            dp[i][j].fi.fi%=MOD;
            dp[i][j].fi.se%=MOD;
            dp[i][j].se.fi%=MOD;
            dp[i][j].se.se%=MOD;
        }
    }
    // int xx=2, yy=2;
    // cout<<dp[xx][yy].fi.fi<<" "<<dp[xx][yy].fi.se<<" "<<dp[xx][yy].se.fi<<" "<<dp[xx][yy].se.se<<endl;
    ll ans=dp[c][d].fi.fi+dp[c][d].fi.se+dp[c][d].se.fi+dp[c][d].se.se;
    if(ans%2==1)
    {
        ans+=MOD;
    }
    ans/=2LL;
    ans%=MOD;
    cout<<ans<<endl;
}

int main() {
    #ifndef ONLINE_JUDGE
        // for getting input from input.txt
        freopen("input.txt", "r", stdin);
        // for writing output to output.txt
        freopen("oo.txt", "w", stdout);
    #endif
    
    ios_base::sync_with_stdio(0);
    cin.tie(NULL);
    int t = 1, tt=1;
    // cin>>t;
    while(tt<=t)
    {
        // cout<<"Case #"<<tt<<": ";
        solve();
        tt++;
    } 
    cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
}

Measured memory_bytes: 291352