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

using vi=vector<int>;
using vvi=vector<vi>;
int h,w;
int dfs(vvi &f,int x,int i);
vi flags;
bool check(const vvi &f,int k,int l){
    for(int i=max(k-1,0);i+1<h && i<=k+1;i++){
        for(int j=max(l-1,0);j+1<w && j<=l+1;j++){
            int zcnt=0;
            set<int> s;
            for(int di=0;di<2;di++){
                for(int dj=0;dj<2;dj++){
                    if(f[i+di][j+dj]!=0) s.insert(f[i+di][j+dj]);                      
                }
            }
            if(zcnt+s.size()==4) return false;
        }
    }
    return true;
}
int impl(vvi &f,int i,int j,int x){
    int res=0;
    int k=1;
    if(0<=i+k-1 && i+k<h && f[i+k-1][j]==f[i+k][j]){
        f[i+k-1][j]=f[i+k][j]=x;
        if(check(f,i,j)) res+=dfs(f,x+1,i);
        f[i+k-1][j]=f[i+k][j]=0;
    }
    if(0<=j+k-1 && j+k<w && f[i][j+k-1]==f[i][j+k]){
        f[i][j+k-1]=f[i][j+k]=x;
        if(check(f,i,j)) res+=dfs(f,x+1,i);
        f[i][j+k-1]=f[i][j+k]=0;
    }
    return res;
}
int dfs(vvi &f,int x,int i){
    if(i==h) return 1;
    for(int j=0;j<w;j++){
        if(!f[i][j]){
            return impl(f,i,j,x);
        }
    }
    return dfs(f,x,i+1);
}
int solve(){
    flags.assign(h*w,0);
    vvi tmpf(h,vi(w,0));
    return dfs(tmpf,1,0);
}

int main(){
    while(cin>>h>>w,h){
        cout<<solve()<<endl;
    }
    return 0;
}

### Prompt

Construct a cpp code solution to the problem outlined:

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>;
int h,w;
int dfs(vvi &f,int x,int i);
vi flags;
bool check(const vvi &f,int k,int l){
    for(int i=max(k-1,0);i+1<h && i<=k+1;i++){
        for(int j=max(l-1,0);j+1<w && j<=l+1;j++){
            int zcnt=0;
            set<int> s;
            for(int di=0;di<2;di++){
                for(int dj=0;dj<2;dj++){
                    if(f[i+di][j+dj]!=0) s.insert(f[i+di][j+dj]);                      
                }
            }
            if(zcnt+s.size()==4) return false;
        }
    }
    return true;
}
int impl(vvi &f,int i,int j,int x){
    int res=0;
    int k=1;
    if(0<=i+k-1 && i+k<h && f[i+k-1][j]==f[i+k][j]){
        f[i+k-1][j]=f[i+k][j]=x;
        if(check(f,i,j)) res+=dfs(f,x+1,i);
        f[i+k-1][j]=f[i+k][j]=0;
    }
    if(0<=j+k-1 && j+k<w && f[i][j+k-1]==f[i][j+k]){
        f[i][j+k-1]=f[i][j+k]=x;
        if(check(f,i,j)) res+=dfs(f,x+1,i);
        f[i][j+k-1]=f[i][j+k]=0;
    }
    return res;
}
int dfs(vvi &f,int x,int i){
    if(i==h) return 1;
    for(int j=0;j<w;j++){
        if(!f[i][j]){
            return impl(f,i,j,x);
        }
    }
    return dfs(f,x,i+1);
}
int solve(){
    flags.assign(h*w,0);
    vvi tmpf(h,vi(w,0));
    return dfs(tmpf,1,0);
}

int main(){
    while(cin>>h>>w,h){
        cout<<solve()<<endl;
    }
    return 0;
}

```