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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

int h,w;
int res;
int crtnum;
int num[22][22];

void dfs(int i,int j){
  if(i==h){
    bool ok=true;
    rep(a,h-1){
      rep(b,w-1){
        vector<int> tmp;
        tmp.push_back(num[a][b]); tmp.push_back(num[a][b+1]); tmp.push_back(num[a+1][b]); tmp.push_back(num[a+1][b+1]);
        sort(all(tmp)); uni(tmp);
        if(tmp.size()==4){
          ok=false;
          break;
        }
      }
      if(!ok)break;
    }
    if(ok)res++;
    return ;
  }
  int ni,nj;
  if(j==w-1){
    ni=i+1; nj=0;
  }else{
    ni=i; nj=j+1;
  }

  if(j+1<w&&num[i][j]==-1&&num[i][j+1]==-1){
    num[i][j]=num[i][j+1]=crtnum++;

    bool ok=true;
    for(int ci=max(0,i-1);ci<=min(h-1,i);ci++){
      for(int cj=max(0,j-1);cj<=min(w-1,j+1);cj++){
        vector<int> tmp;
        tmp.push_back(num[ci][cj]); tmp.push_back(num[ci][cj+1]); tmp.push_back(num[ci+1][cj]); tmp.push_back(num[ci+1][cj+1]);
        sort(all(tmp)); uni(tmp);
        if(tmp[0]!=-1&&tmp.size()==4){
          ok=false;
          break;
        }
      }
      if(!ok)break;
    }

    if(ok)dfs(ni,nj);
    num[i][j]=num[i][j+1]=-1;
    crtnum--;
  }
  if(i+1<h&&num[i][j]==-1&&num[i+1][j]==-1){
    num[i][j]=num[i+1][j]=crtnum++;
    
    bool ok=true;
    for(int ci=max(0,i-1);ci<=min(h-1,i+1);ci++){
      for(int cj=max(0,j-1);cj<=min(w-1,j);cj++){
        vector<int> tmp;
        tmp.push_back(num[ci][cj]); tmp.push_back(num[ci][cj+1]); tmp.push_back(num[ci+1][cj]); tmp.push_back(num[ci+1][cj+1]);
        sort(all(tmp)); uni(tmp);
        if(tmp[0]!=-1&&tmp.size()==4){
          ok=false;
          break;
        }
      }
      if(!ok)break;
    }

    if(ok)dfs(ni,nj);

    num[i][j]=num[i+1][j]=-1;
    crtnum--;
  }
  if(num[i][j]!=-1){
    dfs(ni,nj);
  }
}

int main(){
  while(1){
    cin>>h>>w;
    if(h==0)break;
    crtnum=0; res=0;
    memset(num,-1,sizeof(num));
    dfs(0,0);
    cout<<res<<endl;
  }
  return 0;
}


### Prompt

In Cpp, your task is to solve 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;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

int h,w;
int res;
int crtnum;
int num[22][22];

void dfs(int i,int j){
  if(i==h){
    bool ok=true;
    rep(a,h-1){
      rep(b,w-1){
        vector<int> tmp;
        tmp.push_back(num[a][b]); tmp.push_back(num[a][b+1]); tmp.push_back(num[a+1][b]); tmp.push_back(num[a+1][b+1]);
        sort(all(tmp)); uni(tmp);
        if(tmp.size()==4){
          ok=false;
          break;
        }
      }
      if(!ok)break;
    }
    if(ok)res++;
    return ;
  }
  int ni,nj;
  if(j==w-1){
    ni=i+1; nj=0;
  }else{
    ni=i; nj=j+1;
  }

  if(j+1<w&&num[i][j]==-1&&num[i][j+1]==-1){
    num[i][j]=num[i][j+1]=crtnum++;

    bool ok=true;
    for(int ci=max(0,i-1);ci<=min(h-1,i);ci++){
      for(int cj=max(0,j-1);cj<=min(w-1,j+1);cj++){
        vector<int> tmp;
        tmp.push_back(num[ci][cj]); tmp.push_back(num[ci][cj+1]); tmp.push_back(num[ci+1][cj]); tmp.push_back(num[ci+1][cj+1]);
        sort(all(tmp)); uni(tmp);
        if(tmp[0]!=-1&&tmp.size()==4){
          ok=false;
          break;
        }
      }
      if(!ok)break;
    }

    if(ok)dfs(ni,nj);
    num[i][j]=num[i][j+1]=-1;
    crtnum--;
  }
  if(i+1<h&&num[i][j]==-1&&num[i+1][j]==-1){
    num[i][j]=num[i+1][j]=crtnum++;
    
    bool ok=true;
    for(int ci=max(0,i-1);ci<=min(h-1,i+1);ci++){
      for(int cj=max(0,j-1);cj<=min(w-1,j);cj++){
        vector<int> tmp;
        tmp.push_back(num[ci][cj]); tmp.push_back(num[ci][cj+1]); tmp.push_back(num[ci+1][cj]); tmp.push_back(num[ci+1][cj+1]);
        sort(all(tmp)); uni(tmp);
        if(tmp[0]!=-1&&tmp.size()==4){
          ok=false;
          break;
        }
      }
      if(!ok)break;
    }

    if(ok)dfs(ni,nj);

    num[i][j]=num[i+1][j]=-1;
    crtnum--;
  }
  if(num[i][j]!=-1){
    dfs(ni,nj);
  }
}

int main(){
  while(1){
    cin>>h>>w;
    if(h==0)break;
    crtnum=0; res=0;
    memset(num,-1,sizeof(num));
    dfs(0,0);
    cout<<res<<endl;
  }
  return 0;
}


```