#include <bits/stdc++.h>
using namespace std;

int index(int y, int x)
{
    return y * 16 + x;
}
int search(bitset<256> ttm, int H, int W, int a, int b)
{
    if (a == 0 && b == 0)
        return 1;
    int ans = 0;
    int cx = 0, cy = 0;
    bool flag = true;
    for (int y = 0; y < H && flag; y++)
    {
        for (int x = 0; x < W && flag; x++)
        {
            if (!ttm[index(y, x)])
            {
                cx = x;
                cy = y;
                flag = false;
            }
        }
    }
    ttm.set(index(cy, cx));
    if (b != 0)
        ans += search(ttm, H, W, a, b - 1);
    if (a != 0)
    {
        if (cx + 1 < W && !ttm[index(cy, cx + 1)])
        {
            ttm.set(index(cy, cx + 1));
            ans += search(ttm, H, W, a - 1, b);
            ttm.reset(index(cy, cx + 1));
        }

        if (cy + 1 < H && !ttm[index(cy + 1, cx)])
        {
            ttm.set(index(cy + 1, cx));
            ans += search(ttm, H, W, a - 1, b);
            ttm.reset(index(cy + 1, cx));
        }
    }

    return ans;
}

void solve(long long H, long long W, long long A, long long B)
{
    bitset<256> ttm(0);
    cout << search(ttm, H, W, A, B) << endl;
}

// Generated by 2.2.0 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
int main()
{
    long long H;
    scanf("%lld", &H);
    long long W;
    scanf("%lld", &W);
    long long A;
    scanf("%lld", &A);
    long long B;
    scanf("%lld", &B);
    solve(H, W, A, B);
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i, l, n) for (int i = (int)(l); i < (int)(n); i++)
#define drep(i, n, l) for (int i = (int)(n); i > (int)(l); i--)
#define INF INT_MAX
#define def (200007)
#define MOD (1000000007)
typedef vector<int> veci;
typedef vector<vector<int>> Veci;
typedef vector<int64_t> vecit;
typedef vector<vector<int64_t>> Vecit;
typedef int64_t intt;
typedef vector<vector<double>> Vecd;
typedef vector<double> vecd;
typedef pair<int, int> P;
/*veci のときdist.resize(N) Veciのとき2回resize;*/
//powはdouble型
Veci dp;
int sum=0;
int H,W,A,B;

void dfs(int nx,int index){
  if(H*W==(2*index+B)){
    sum++;
    return;
  }
  if(nx>=H*W)return;
  if(dp[nx/W][nx%W]!=0){
    return dfs(nx+1,index);
  }
  if(nx<H*W)dp[nx/W][nx%W]=index+3;
  
  if((nx+1)%W>(nx%W)){
    if(dp[(nx+1)/W][(nx+1)%W]==0){
      dp[(nx+1)/W][(nx+1)%W]=2;
      dfs(nx+2,index+1);
      dp[(nx+1)/W][(nx+1)%W]=0;
    }
  }
  if((nx+W)/W<H){
    if(dp[(nx+W)/W][(nx+W)%W]==0){
      dp[(nx+W)/W][(nx+W)%W]=1;
      dfs(nx+1,index+1);
      dp[(nx+W)/W][(nx+W)%W]=0;
    }
  }
  dp[nx/W][nx%W]=0;
}

int next_combination(int sub){
  int x=sub&-sub,y=sub+x;
  return(((sub&~y)/x)>>1)|y;
}

//3*10^6 10!
//16C8 1.2*10^4
//0何もない 1:1*1の畳 2:1*2の畳
int main(){
  cin>>H>>W>>A>>B;
  dp.resize(H);
  if(B>0){
	int bit = (1<<B)-1;
    for(;bit<(1<<H*W);bit=next_combination(bit)){
      rep(i,0,H){
        dp[i].assign(W,0);
      }
      rep(i,0,H*W){
        if(bit & (1<<i)){
          rep(j,1,H+1){
            if(i<W*j){
              dp[j-1][i-W*(j-1)]=1;
              break;
            }
          }
        }
      }
      int nex=0;
      rep(i,0,H*W){
        if(dp[i/W][i%W] == 0 ){
          nex=i;
          break;
        }
      }
      dfs(nex,0);
    }
  }else{
    rep(i,0,H)dp[i].assign(W,0);
    dfs(0,0);
  }
  cout<<sum<<endl;

}