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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

int W, H;
int memo[21][21];
int dfs(int x, int y, int i){
  if(y == H)
	return 1;
  if(x == W)
	return dfs(0, y+1, i);

  if(memo[y][x])
	return dfs(x+1, y, i);

  int res = 0;
  if(x+1 < W && !memo[y][x+1]){
	if(!(y > 0 && x > 0 && memo[y-1][x-1] != memo[y-1][x] && memo[y-1][x-1] != memo[y][x-1])){
	  memo[y][x] = memo[y][x+1] = i;
	  res += dfs(x+1, y, i+1);
	  memo[y][x] = memo[y][x+1] = 0;
	}
  }
  if(y+1 < H && !memo[y+1][x]){
	if(!(y > 0 && x > 0 && memo[y-1][x-1] != memo[y-1][x] && memo[y-1][x-1] != memo[y][x-1])){
	  memo[y][x] = memo[y+1][x] = i;
	  res += dfs(x+1, y, i+1);
	  memo[y][x] = memo[y+1][x] = 0;
	}
  }
  return res;
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  while(cin>>W>>H,W){
	cout << dfs(0,0,1) << endl;
  }

  return 0;
}
### Prompt

Create a solution in cpp for the following problem:

A tatami mat, a Japanese traditional floor cover, has a rectangular form with aspect ratio 1:2. When spreading tatami mats on a floor, it is prohibited to make a cross with the border of the tatami mats, because it is believed to bring bad luck.

Your task is to write a program that reports how many possible ways to spread tatami mats of the same size on a floor of given height and width.



Input

The input consists of multiple datasets. Each dataset cosists of a line which contains two integers H and W in this order, separated with a single space. H and W are the height and the width of the floor respectively. The length of the shorter edge of a tatami mat is regarded as a unit length.

You may assume 0 < H, W ≤ 20.

The last dataset is followed by a line containing two zeros. This line is not a part of any dataset and should not be processed.

Output

For each dataset, print the number of possible ways to spread tatami mats in one line.

Example

Input

3 4
4 4
0 0


Output

4
2

### Response

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

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))
#define UNIQ(c) (c).erase(unique(ALL((c))), end((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;

int W, H;
int memo[21][21];
int dfs(int x, int y, int i){
  if(y == H)
	return 1;
  if(x == W)
	return dfs(0, y+1, i);

  if(memo[y][x])
	return dfs(x+1, y, i);

  int res = 0;
  if(x+1 < W && !memo[y][x+1]){
	if(!(y > 0 && x > 0 && memo[y-1][x-1] != memo[y-1][x] && memo[y-1][x-1] != memo[y][x-1])){
	  memo[y][x] = memo[y][x+1] = i;
	  res += dfs(x+1, y, i+1);
	  memo[y][x] = memo[y][x+1] = 0;
	}
  }
  if(y+1 < H && !memo[y+1][x]){
	if(!(y > 0 && x > 0 && memo[y-1][x-1] != memo[y-1][x] && memo[y-1][x-1] != memo[y][x-1])){
	  memo[y][x] = memo[y+1][x] = i;
	  res += dfs(x+1, y, i+1);
	  memo[y][x] = memo[y+1][x] = 0;
	}
  }
  return res;
}

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  while(cin>>W>>H,W){
	cout << dfs(0,0,1) << endl;
  }

  return 0;
}
```