Problem:
Problem I: Tatami

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.

Sample Input

3 4
4 4
0 0

Output for the Sample Input

4
2

Solution in C++11 (judge verdict: Accepted)

#include<iostream>
#include<array>
#include<map>

using namespace std;

int main(){
  for(int H,W;cin>>H>>W,H;){
    map<array<int,20>,int> m[21][21];
    m[0][0][array<int,20>()]=1;
    for(int i=0;i<H;i++){
      for(int j=0;j<W;j++){
	for(auto e:m[i][j]){
	  auto v=e.first;
	  auto d=e.second;
	  if(j&&v[j-1]==2){
	    v[j]=3;
	    m[i][j+1][v]+=d;
	  }else if(i&&v[j]==0){
	    v[j]=1;
	    m[i][j+1][v]+=d;
	  }else if(i==0||v[j]==3||j==0||v[j-1]==1){
	    if(i+1<H){
	      auto nv=v;
	      nv[j]=0;
	      m[i][j+1][nv]+=d;
	    }
	    if(j+1<W&&(i==0||v[j+1]!=0)){
	      auto nv=v;
	      nv[j]=2;
	      m[i][j+1][nv]+=d;
	    }
	  }
	}
	m[i][j].clear();
      }
      m[i+1][0]=m[i][W];
    }
    int a=0;
    for(auto e:m[H][0]){
      a+=e.second;
    }
    cout<<a<<endl;
  }
}