// 題意:一個n*m的矩陣,求用I型(1 * 2)和L型的兩種方塊進行填滿有多少種方法
// 方法:這題和poj2411有點類似 做過方塊填充的應該都認得出來要用狀壓
// 但是要比poj2411複雜 思路也是類似 不過因爲要考慮L型 情況也複雜的多
// 語文有點不太好 可能有點說不清楚
// 利用兩個參數 b1 表示前面的放置方式對now(當前行狀態)的當前列的影響,b2 表示對pre(上一行狀態)的當前列的影響
// 有影響爲1 沒影響爲0 其實可以這麼理解 如果爲1就代表有方塊從左邊凸出來會佔用當前列 爲0就代表沒有凸出來
// 這裏我提出一些自己遇到的問題
// 首先枚舉當前狀態和上一狀態要分成兩種情況考慮
// 不僅要考慮b1,b2 還要考慮從下往下凸出來的這種情況,就是上一行的上一行有方塊凸下來佔用上一行 說起來有點繞
// 舉個例子 如果當前 b1 == 0 && b2 == 0
// 那麼這一列我們可以這麼放
// 1 1 1 1 1 1
// 或者 或者 或者 (這四種是上一行的上一行沒有從上往下凸出來的方塊的放置方法)
// 1 1 1 1 1
// 1
// 或者 或者 不放 (這三種是上一行的上一行有從上往下凸出來的方塊的放置方法)
// 1 1 1 1
// 上面總共7種 上面的每種都滿足把上一行的當前列填滿了 只不過是分爲是由左邊凸出來的 和 上面凸出來的
// 填滿我起初也有疑問爲什麼下面的這三种放置也可以
// 語文果然不太好 看下面幾張圖一定有用
#include <algorithm>
#include <iostream>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
int n, m;
long long ans[10][10];
long long dp[10][1<<10];
// 一 二 三 四 五 六
// 1 1 1 1 1 1 1
// 1 1 1 1 1 1 1 1 1
void dfs(int line, int k, int now, int pre, int b1, int b2)
{
if(k == m){
if(!b1 && !b2) dp[line][now] += dp[line - 1][pre];
return;
}
if(!b1 && !b2){
dfs(line, k + 1, now<<1|1, pre<<1, 0, 0); // 第一種方法放置
dfs(line, k + 1, now<<1|1, pre<<1, 1, 0); // 第二種方法放置
dfs(line, k + 1, now<<1|1, pre<<1, 0, 1); // 第三種方法放置
dfs(line, k + 1, now<<1|b1, pre<<1, 1, 1); // 第五種方法放置
dfs(line, k + 1, now<<1|1, pre<<1|1, 1, 1); // pre當前位的1是從上向下凸出來的 第四種方法放置
dfs(line, k + 1, now<<1|1, pre<<1|1, 1, 0); // pre當前位的1是從上向下凸出來的 第六種方法放置
dfs(line, k + 1, now<<1|0, pre<<1|1, 0, 0); // 當前位置不放
}
else if( b1 && !b2)
{
dfs(line, k + 1, now<<1|1, pre<<1, 1, 1); // 第五種方法放置
dfs(line, k + 1, now<<1|1, pre<<1|1, 0, 0); // pre當前位的1是從上向下凸出來的
}
else if(!b1 && b2)
{
dfs(line, k + 1, now<<1|1, pre<<1, 1, 1); // 第四種方法放置
dfs(line, k + 1, now<<1|1, pre<<1, 1, 0); // 第六種方法放置
dfs(line, k + 1, now<<1, pre<<1, 0, 0); // 當前位置不放
}
else{
dfs(line, k + 1, now<<1|1, pre<<1, 0, 0); // 因爲b1和b2都爲1 所以直接跳到下一行
}
}
int main()
{
memset(ans, 0, sizeof ans);
memset(dp, 0, sizeof dp);
while(cin>>n>>m)
{
if(ans[n][m]){
cout<<ans<<endl;
continue;
}
if(n < m)
swap(n, m);
dp[0][(1<<m) - 1] = 1;
for(int i = 1; i <= n; i++)
dfs(i, 0, 0, 0, 0, 0);
ans[n][m] = ans[m][n] = dp[n][(1<<m) - 1];
cout<<ans[n][m]<<endl;
}
return 0;
}