#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
int N, M;//棋盘的宽和长
long long dp[15][4096];dp[i][j]用于存储填充i-1列状态为j时,i列可能出现的方法数
void dfs(int i, int j, int state, int next) { //i代表列数,j代表当前位数(也可以说是行数-1,初始时为0)
//state代表状态数,nex代表下一列出现的状态
if(j == N) {
dp[i+1][next] += dp[i][state];
return;
}
if(((1<<j)&state) > 0) { //如果这个位置已经被占用,跳过
dfs(i, j + 1, state, next);
}
if(((1<<j)&state) == 0) { //如果这个位置是空的,尝试放一个左右覆盖1*2的木块
dfs(i, j + 1, state, next | (1 << j));
}
if(j+1<N && ((1<<j)&state) == 0 && ((1<<j+1)&state) ==0 ) { //如果这个位置和下一个位置空的,尝试放一个上下覆盖2*1的木块,而此时要跳过下一个木块
dfs(i, j + 2, state, next);
//注意j+1<N
}
//return;
}
int main() {
freopen("data.in", "r", stdin);
while(cin >> N >> M && N != 0 && M != 0) {//n行m列
memset(dp, 0, sizeof(dp));
dp[1][0]=1; //初始化第一列状态为0的方法数等于1
for(int i = 1; i <= M; i++) { //外层遍历每一列
for(int j = 0; j < (1<<N); j++) { //内层遍历每一行的各种状态
if(dp[i][j]) { //
dfs(i, 0, j, 0);//如果方法数不空,就执行dfs
}
}
}
cout<<dp[M+1][0]<<endl;
}
return 0;
}