Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
	)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	for scanner.Scan() {
		buf := strings.Split(scanner.Text(), " ")
		X, _ := strconv.Atoi(buf[0])
		Y, _ := strconv.Atoi(buf[1])
		if X == 0 && Y == 0 {
			break
		}
		tbl := make([][]int, Y+2)
		field := make([][]int, Y+2)
		for i := range field {
			field[i] = make([]int, X+2)
			tbl[i] = make([]int, X+2)
			for j := range field[i] {
				field[i][j] = 2
				tbl[i][j] = 0
			}
		}
		buf_ := make([][]string, Y)
		for i := range buf_ {
			scanner.Scan()
			buf_[i] = strings.Split(scanner.Text(), " ")
		}
		for i := 1; i <= Y; i++ {
			for j := 1; j <= X; j++ {
				field[i][j], _ = strconv.Atoi(buf_[i-1][j-1])
				switch field[i][j] {
				case 0:
					if i == 1 {
						tbl[i][j] = 1 // スタートy=1
					} else {
						if field[i-1][j-1] != 2 {
							tbl[i][j] += tbl[i-1][j-1] // 左上からやってくる
						}
						if field[i-1][j] != 2 {
							tbl[i][j] += tbl[i-1][j] // 真上からやってくる
						}
						if field[i-1][j+1] != 2 {
							tbl[i][j] += tbl[i-1][j+1] // 右上からやってくる
						}
						if field[i-2][j] == 2 {
							tbl[i][j] += tbl[i-2][j] // ジャンプしてくる
						}
					}
				case 1:
					tbl[i][j] = 0 // 障害物あり
				case 2:
					if field[i-1][j] != 2 {
						tbl[i][j] += tbl[i-1][j] // 真上からくる
					}
					if field[i-2][j] == 2 {
						tbl[i][j] += tbl[i-2][j] // ジャンプ台からジャンプしてくる
					}
				}
			}
		}
		sum := 0
		for i := 1; i <= X; i++ {
			sum += tbl[Y][i] // とびこさないでゴール
			if field[Y-1][i] == 2 {
				sum += tbl[Y-1][i] // 飛び越してゴール
			}
		}
		fmt.Println(sum)
	}
}

C++: #include<iostream>
#include<cstring>
using namespace std;
int X, Y;
int c[17][17];
int dp[17][17];
int solve(int x, int y, int bx);
int main(){
  long long int ans;
  while(1){
    ans = 0;
    cin >> X >> Y;
    if(X == 0 && Y == 0) break;
    memset(dp, 0, sizeof(dp));
    for(int i = 0; i < Y; i++){
      for(int j = 0; j < X; j++){
	cin >> c[i][j];
      }
    }
    for(int i = 0; i < X; i++){
      ans += solve(i, 0, i); 
    }
    cout << ans << endl;
  }
}

int solve(int x, int y, int bx){
  if(x < 0 || x >= X || c[y][x] == 1 || c[y][x] == 2 && x != bx) return 0;
  if(y >= Y - 1) return 1;
  if(dp[y][x] > 0) return dp[y][x];
  if(bx == x && c[y][x] == 2) return solve(x, y + 2, x);
  else if(c[y][x] == 0) return dp[y][x] = solve(x - 1, y + 1, x) + solve(x, y + 1, x) + solve(x + 1, y + 1, x);
}

C++: // 基本テンプレート
 
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
using namespace std;
 
#define rep(i,a,n) for(int (i)=(a); (i)<(n); (i)++)
#define repq(i,a,n) for(int (i)=(a); (i)<=(n); (i)++)
#define repr(i,a,n) for(int (i)=(a); (i)>=(n); (i)--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {1, 1, 1};
int dy[] = {-1, 0, 1};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

int board[20][20], dp[30][30];
 
signed main() {
    int W, H;
    while(cin >> W >> H, W || H) {
        for(int i=0; i<H; i++) {
            for(int j=0; j<W; j++) {
                cin >> board[i][j];
            }
        }

        memset(dp, 0, sizeof(dp));
        for(int i=0; i<W; i++) if(board[0][i] == 0) dp[0][i] = 1;

        int ans = 0;
        for(int i=0; i<H; i++) {
            for(int j=0; j<W; j++) {
                for(int k=0; k<3; k++) {
                    if(board[i][j] == 2 and k != 1) continue;
                    int dbl = (board[i][j] == 2 ? 2 : 1);

                    int ni = i + dx[k] * dbl, nj = j + dy[k];
                    if(ni < 0 or nj < 0 or nj >= W) continue;
                    if(board[ni][nj] == 1) continue;
                    if(board[ni][nj] == 2 and k != 1) continue;

                    if(ni < H - 1) {
                        dp[ni][nj] += dp[i][j];
                    }
                    else {
                        ans += dp[i][j];
                    }
                }
            }
        }

        cout << ans << endl;
    }
    return 0;
}

C++: #include<iostream>
#include<cstring>

using namespace std;

int X, Y;
int status[17][18];	//status[x][y]
int memo[17][18];
int i, j;
int count;

int check(int x, int y);

int main(){

	while(1){

		count = 0;

		cin >> X >> Y;

		if(X == 0 && Y == 0){break;}

		else{

			//フィールドの入力
			//i行目について( 1 <= i <= Y+2 )
			for(i = 1; i <= Y+2; i++){
				//j文字目について( 0 <= j <= X+1)
				for(j = 0; j <= X+1; j++){

					//Y+1, Y+2列目に移動できるようにする。
					if(i > Y){
						status[j][i] = 0;
					}
					//両サイドには障害物を敷き詰める。
					else if(j == 0 || j == X+1){
						status[j][i] = 1;
					}
					else{
						cin >> status[j][i];
					}
				}
			}

/*//フィールド出力
			for(i = 1; i <= Y+2; i++){
				for(j = 0; j <= X+1; j++){
					cout << status[j][i];
				}
				cout << endl;
			}
*/

			for(i = 1; i <= X; i++){
				memset(memo, 0, sizeof(memo));
				count += check(i, 1);
			}

			cout << count << endl;
		}
	}

	return 0;
}


int  check(int x, int y){

//	cout << "x:" << x << "y:" << y << " : "<< status[x][y] << endl;

	//関数のメモが残っているならメモを返す
	if(memo[x][y] > 0){return memo[x][y];}

	//status[x][y]の次でゴール
	if(status[x][y] == 1){return 0;}
	if(status[x][y] == 0 && y == Y){return 1;}
	if(status[x][y] == 2 && (y == Y-1 || y == Y)){return 1;}

	//それ以外
	else{
		//ジャンプ台
		if(status[x][y] == 2){
			memo[x][y] += check(x, y+2);
		}
		//平地
		else{
			if(status[x-1][y+1] == 0){
				memo[x][y] += check(x-1, y+1);
			}
			if(status[x][y+1] == 0 || status[x][y+1] == 2){
				memo[x][y] += check(x, y+1);
			}
			if(status[x+1][y+1] == 0){
				memo[x][y] += check(x+1, y+1);
			}
		}

		return memo[x][y];
	}
}

C++: #include <iostream>
#define rep2(x,from,to) for(int x=(from);(x)<(to);(x)++)
#define rep(x,to) rep2(x,0,to)
using namespace std;
int main(){
	int x, y;
	while(cin >> x >> y && (x||y) ) {
		int b[15][15] = {};
		rep(i,y) {
			rep(j,x) {
				cin >> b[i][j];
			}
		}
		int ret[20][20] = {};
		rep(i,x) {
			if(b[0][i] == 0) {
				ret[0][i+1] = 1;
			}
		}
		rep2(i,1,y) {
			rep(j,x) {
				if(b[i][j] == 0) {
					ret[i][j+1] += ret[i-1][j] + ret[i-1][j+1] + ret[i-1][j+2];
					rep2(k,-1,1) {
						if(b[i-1][j+k] == 2) ret[i][j+1] -= ret[i-1][j+k+1];
					}
				} else if(b[i][j] == 2) {
					ret[i+2][j+1] += ret[i-1][j+1];
				}
			}
		}
		int ans = 0;
		rep2(i,y-1,y+2) {
			rep(j,x) {
				ans += ret[i][j+1];
			}
		}
		cout << ans << endl;
	}
}

C++: #include <cstdio>
#include <cstring>
#define NORMAL 0
#define TREE 1
#define JUMP 2
#define DR_NUM 3 // 方向数

using namespace std;

const int dy[DR_NUM] = {1,1,1}, dx[DR_NUM] = {-1,0,1};

int main(void){
	int x, y, course[15][15], dp[17][15], i, j, k, l, ans;
	while(1){
		scanf("%d%d",&x,&y);
		if(x == 0 && y == 0){
			break;
		}
		for(i = 0;i < y;i++){
			for(j = 0;j < x;j++){
				scanf("%d",&course[i][j]);
			}
		}
		memset(dp,0,sizeof(dp));
		for(i = 0;i < x;i++){
			if(course[0][i] != TREE)
				dp[0][i] = 1;
		}
		for(j = 0;j < y;j++){
			for(k = 0;k < x;k++){
				if(course[j + 2][k] != TREE && (course[j][k] == JUMP || j == y - 1)){
					dp[j + 2][k] += dp[j][k];
				}else if(course[j][k] == NORMAL){
					for(l = 0;l < DR_NUM;l++){
						if(k + dx[l] >= 0 && k + dx[l] < x && course[j + dy[l]][k + dx[l]] != TREE && !(l != 1 && course[j + dy[l]][k + dx[l]] == JUMP)){
							dp[j + dy[l]][k + dx[l]] += dp[j][k];
						}
					}
				}
			}
		}
		ans = 0;
		for(i = 0;i < x;i++){
			ans += dp[y][i] + dp[y + 1][i];
		}
		printf("%d\n",ans);
	}
	return 0;
}