#include <algorithm>
#include <cmath>
#include <deque>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <string>
#include <unordered_set>
#include <vector>

#define REP(i, n) for(int i = 0; i < n; ++i)
using namespace std;
using LLONG = long long;
const LLONG MOD = 1000000007;

int H, W;

pair<int, int> Next(int r, int c)
{
	if (c == W)
	{
		return { r + 1, 1 };
	}
	else
	{
		return { r, c + 1 };
	}
}

LLONG Count(
	int r, int c, int remA, int remB,
	set<pair<int, int>>& used)
{
	auto[nR, nC] = Next(r, c);

	// 使用済みは飛ばす
	if (used.count({ r, c }))
	{
		if (r == H && c == W)
		{
			return 1;
		}
		return Count(nR, nC, remA, remB, used);
	}

	// A を使い切ったら残りの敷き方は1通り
	if (remA == 0)
	{
		return 1;
	}

	// A を使い切れなかったら0通り
	if (r == H && c == W && remA != 0)
	{
		return 0;
	}

	LLONG ret = 0;
	if (remA > 0)
	{
		// 縦にAを敷く場合
		if (r < H && !used.count({ r + 1, c }))
		{
			used.insert({ r + 1, c });
			ret += Count(nR, nC, remA - 1, remB, used);
			used.erase({ r + 1, c });
		}
		// 横にAを敷く場合
		if (c < W && !used.count({ r, c + 1 }))
		{
			used.insert({ r, c + 1 });
			ret += Count(nR, nC, remA - 1, remB, used);
			used.erase({ r, c + 1 });
		}
	}
	if (remB > 0)
	{
		ret += Count(nR, nC, remA, remB - 1, used);
	}
	return ret;
}

int main()
{
	int A, B; cin >> H >> W >> A >> B;
	set<pair<int, int>> used;
	cout << Count(1, 1, A, B, used) << endl;
}

//#include <atcoder/maxflow.hpp>
#include <memory>
#include <iostream>
#include <map>
#include <list>
#include <set>
#include <algorithm>
#include <vector>
#include <sstream>
#include <string>
#include <functional>
#include <queue>
#include <deque>
#include <stack>
#include <limits>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <fstream>
#include <iterator>
#include <random>
#include <chrono>
#include <complex>


#define forr(i,start,count) for (int i = (start); i < (start)+(count); ++i)
#define set_map_includes(set, elt) (set.find((elt)) != set.end())
#define readint(i) int i; cin >> i
#define readll(i) ll i; cin >> i
#define readdouble(i) double i; cin >> i
#define readstring(s) string s; cin >> s

typedef long long ll;

using namespace std;
//using namespace atcoder;

//ll modd = 1000 * 1000 * 1000 + 7;
ll modd = 998244353;

int main()   {

      ios_base::sync_with_stdio(false);

      cout.precision(17);
      mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
      uniform_int_distribution<int> rand_gen(0, modd);   // rand_gen(rng) gets the rand no

//      auto start = chrono::steady_clock::now(); 

//    readint(test_cases);
    int test_cases = 1;
    forr(t, 1, test_cases) {
       readll(a); readll(b); readll(c);
       ll ans = ((a*(a+1))/2) % modd;
       ans *= ((b*(b+1))/2) % modd; ans %= modd;
       ans *= ((c*(c+1))/2) % modd; ans %= modd;
       cout << ans << endl;
    }
    return 0;
}

//        auto stop = chrono::steady_clock::now(); 
//        auto duration = chrono::duration_cast<chrono::milliseconds>(stop - start);
//        cout << "Duration: " << duration.count() << endl;
