#include <bits/stdc++.h>
using namespace std;
const int N = 20;

int h,w,a,b,ans;
bool vis[N][N];

void dfs(int now,int x,int y,int a,int b){
	if (now==h*w){
		ans++;
		return ;
	}
	int nx=x+1,ny=y;
	if (x==w) nx=1,ny++;
	if (vis[x][y]) return dfs(now+1,nx,ny,a,b);
	if (a){
		if (x!=w&&!vis[nx][ny]){
			vis[x][y]=vis[nx][ny]=true;
			dfs(now+1,nx,ny,a-1,b);
			vis[x][y]=vis[nx][ny]=false;
		}
		if (y<h){
			vis[x][y]=vis[x][y+1]=true;
			dfs(now+1,nx,ny,a-1,b);
			vis[x][y]=vis[x][y+1]=false;
		}
	}
	if (b){
		vis[x][y]=true;
		dfs(now+1,nx,ny,a,b-1);
		vis[x][y]=false;
	}
}

int main(){
	cin>>h>>w>>a>>b;
	dfs(0,1,1,a,b);
	cout<<ans;
	return 0;
}
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define ll long long
#define endl '\n'
#define F first
#define S second
#define test ll cases; cin>>cases; for(ll testCase = 1; testCase <= cases; testCase++)
#define fill(name, val) memset(name, val, sizeof(name));
#define mop(a, op, b) (((a%mod) op (b%mod))%mod + mod)%mod
#define precise fixed<<setprecision(9)
#define vll vector<ll>
#define vvll vector<vll>
#define pll pair<ll, ll>
#define get(a, n) for(ll it = 0; it < n; it++) cin>>a[it];
#define pbds tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update>
template<typename T1, typename T2> ostream& operator<<(ostream& out, const pair<T1, T2>& p){ return(out<<'('<< p.first<< ", "<< p.second<<')'); }
template<typename T> ostream& operator<<(ostream& out, const vector<T>& v){ out<<'['; for(auto i = v.begin(); i != v.end(); i++) out<<(i!=v.begin()?", ":"")<<(*i); return(out<<']'); }
template<typename T> ostream& operator<<(ostream& out, const set<T>& s){ out<<'['; for(auto i = s.begin(); i != s.end(); i++) out<<(i!=s.begin()?", ":"")<<(*i); return(out<<']'); }
template<typename T1, typename T2> ostream& operator<<(ostream& out, const map<T1, T2>& m){ out<<'{'<<endl; for(auto x : m) out<<"    "<<x.first<<" -> "<<x.second<<endl; return(out<<'}'); }
const ll MX = 1000001, mod = 1e9+7, inf = 1e18; const double eps = 1e-9;
template<typename T> T mpow(T x, ll n){ T ans = 1; while(n){ if(n&1) ans = mop(ans, *, x); n >>= 1, x = mop(x, *, x); } return ans; } ll modinv(ll x){ return mpow(x, mod-2); }
vll sieve(ll n = MX){ vll primes; vector<bool> nums(n, 1); primes.push_back(2); for(ll i = 4; i < n; i += 2) nums[i] = 0; for(ll i = 3; i < n; i += 2){ if(nums[i]){ primes.push_back(i); for(ll j = i*i; j < n; j += i) nums[j] = false; } } return primes; }
vll FACT(1, 1); ll ncr(ll n, ll r){ if(n < r) return 0; while(n >= FACT.size()) FACT.push_back(mop(FACT[FACT.size()-1], *, FACT.size())); return mop(FACT[n],*,mop(modinv(FACT[r]),*,modinv(FACT[n-r]))); } ll fact(ll n){ while(n >= FACT.size()) FACT.push_back(mop(FACT[FACT.size()-1], *, FACT.size())); return FACT[n]; }
void init(){
	ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); 
	#ifndef ONLINE_JUDGE
		freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);
	#endif
}

/*	Author: 🆉🅴🅽🅾🅻🆄🆂	*/

ll h, w, a, b;
map<ll, map<ll, map<ll, map<ll, set<vvll>>>>> dp;
vvll g;	set<vvll> ans;	ll ctr = 0;
void calc(ll a, ll b, ll i, ll j){
	if(i == h){
		vvll v = g;
		ans.insert(v);
		return;
	}
	if(dp[a][b][i][j].count(g))	return;
	dp[a][b][i][j].insert(g);
	if(j == w)	return calc(a, b, i+1, 0);
	if(g[i][j])	return calc(a, b, i, j+1);
	if(b > 0)	calc(a, b-1, i, j+1);
	if(i+1 < h && !g[i+1][j] && a > 0){
		g[i][j] = g[i+1][j] = 1;
		calc(a-1, b, i, j+1);
		g[i][j] = g[i+1][j] = 0;
	}
	if(j+1 < w && !g[i][j+1] && a > 0){
		g[i][j] = g[i][j+1] = 2;
		calc(a-1, b, i, j+1);
		g[i][j] = g[i][j+1] = 0;
	}
}
int main(){
	init();
	cin>>h>>w>>a>>b;
	g.resize(h, vll(w));
	calc(a, b, 0, 0);
	// for(auto x : ans){
	// 	for(auto y : x){
	// 		for(auto z : y)	cout<<z<<' ';
	// 		cout<<endl;
	// 	}
	// 	cout<<endl;
	// }
	cout<<ans.size();
}