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 <algorithm>
#include <vector>
#include <cassert>
using namespace std;

int grid[30][30];

inline bool isAtObstacle(int x, int y) {
  return grid[y][x] == 1;
}

inline bool isAtSkiJump(int x, int y) {
  return grid[y][x] == 2;
}

int main() {
  int n, m;
  
  while(cin >> n >> m && n) {
    fill(grid[0], grid[0]+900, 0);
    for(int i=0; i<n; i++) {
      for(int j=0; j<m; j++) {
	cin >> grid[i][j];
      }
    }
    
    long long dp[30][30][2] = {};
    
    for(int j=0; j<m; j++) {
      if(grid[0][j]==0) { dp[0][j][0] = 1; }
    }
    
    int extra = 0;
    for(int i=0; i<n-1; i++) {
      for(int j=0; j<m; j++) {
	
	// there is no case such that skier is at obstacle.
	if(isAtObstacle(j, i)) {
	  dp[i][j][0] = dp[i][j][1] = 0;
	  continue;
	}
	
	// A skier is at a ski jump.
	if(isAtSkiJump(j, i)) {
	  if(i+2 > n-1) extra += dp[i][j][0];
	  else {
	    if(isAtObstacle(j, i+2)) continue;
	    dp[i+2][j][0] += dp[i][j][0];
	  }
	}
	
	// skiing without jump.
	else {
	  // from the upper left
	  if( j-1 >= 0
	      && !isAtObstacle(j-1, i+1)
	      && !isAtSkiJump (j-1, i+1) ) {
	    dp[i+1][j-1][1] += dp[i][j][0] + dp[i][j][1];
	  }
	  
	  // from the above
	  if( !isAtObstacle(j, i+1) ) {
	    dp[i+1][j][0] += dp[i][j][0] + dp[i][j][1];
	  }
	  
	  // from the upper right
	  if( j+1 < m
	      && !isAtObstacle(j+1, i+1)
	      && !isAtSkiJump (j+1, i+1) ) {
	    dp[i+1][j+1][1] += dp[i][j][0] + dp[i][j][1];
	  }
	}
	
      }
    }
    
    for(int i=0; i<m; i++) {
      if(isAtObstacle(i, n-1)) {
	dp[n-1][i][0] = dp[n-1][i][1] = 0;
      }
    }
    
    int ans = 0;
    for(int i=0; i<m; i++) {
      ans += dp[n-1][i][0] + dp[n-1][i][1];
    }
    
    cout << ans + extra << endl;
  }
  
  return 0;
}

C++: #include <cstring>
#include <iostream>
using namespace std;
const int MAX_W = 15;
const int MAX_H = 15;

int w, h;
int field[MAX_H + 1][MAX_W];
int dp[MAX_H + 1][MAX_W];

void printfield() {
	for (int i = 0; i <= h; i++) {
		for (int j = 0; j < w; j++) {
			cout << '\t' << dp[i][j];
		}
		cout << endl;
	}
}

int main () {
	while (cin >> w >> h, w || h) {
		memset(field, 0, sizeof(field));
		memset(dp, 0, sizeof(dp));
		for (int i = 1; i <= h; i++) {
			for (int j = 0; j < w; j++) {
				cin >> field[i][j];
			}
		}
		for (int i = 0; i < w; i++) {
			if (field[1][i] == 0) dp[1][i] = 1;
		}
		
		for (int i = 2; i <= h; i++) {
			for (int j = 0; j < w; j++) {
				if (field[i - 2][j] == 2 && field[i][j] != 1) {
					dp[i][j] += dp[i - 2][j];
				}
				if (field[i][j] == 0) {
					for (int dx = -1; dx <= 1; dx++) {
						int fx = j + dx;
						if (fx < 0 || w <= fx) continue;
						int fy = i - 1;
						if (field[fy][fx] != 0) continue;
						dp[i][j] += dp[fy][fx];
					}
				}
				else if (field[i][j] == 2) {
					dp[i][j] += dp[i - 1][j];
				}
			}
		}
		int sum = 0;
		for (int i = 0; i < w; i++) {
			sum += dp[h][i];
			if (field[h - 1][i] == 2) sum += dp[h - 1][i];
		}
		cout << sum << endl;
	}
	return 0;
}

C++: #include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <cassert>
using namespace std;
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,n) FOR(i,0,(n)-1)
const double EPS = 1e-10;
const double PI  = acos(-1.0);
const int INF = INT_MAX/10;

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

int main() {
	int X, Y;
	while(cin >> X >> Y, X) {
		vvi field(Y+1, vi(X));
		REP(i, Y) {
			REP(j, X) {
				cin >> field[i][j];
			}
		}

		vvi dp(Y+1, vi(X, 0));
		REP(j, X) {
			dp[0][j] = 1;
		}

		REP(i, Y) {
			REP(j, X) {
				if(i == Y-1) {
					switch(field[i][j]) {
					case 0:
					case 2:
						dp[i+1][j] += dp[i][j];
						break;
					case 1:
						break;
					}
				} else {
					switch(field[i][j]) {
					case 0:
						REP(d, 3) {
							int ny = i+1;
							int nx = j+dx[d];
							if(0 <= nx && nx < X) {
								switch(field[ny][nx]) {
								case 0:
									dp[ny][nx] += dp[i][j];
									break;
								case 1:
									break;
								case 2:
									if(d == 1) {
										dp[ny][nx] += dp[i][j];
									}
									break;
								}
							}
						}
						break;
					case 1:
						break;
					case 2:
						int ny = min(i+2, Y);
						if(field[ny][j] != 1) {
							dp[ny][j] += dp[i][j];
						}
						break;
					}
				}
			}
		}

		int ans = 0;
		REP(i, X) {
			ans += dp[Y][i];
		}

		cout << ans << endl;
	}

	return 0;
}

C++: #include<iostream>
using namespace std;

int DP[17][17];
int field[17][17];
int x,y;

int main(){
	while(true){
		cin >> x >> y;
		if(!x && !y)
			return 0;
		
		for(int i=1; i<=y; i++)
			for(int k=1; k<=x; k++)
				cin >> field[i][k];
		for(int i=1; i<=x; i++)
			field[y+1][i] = 0;
		
		for(int i=1; i<=y+1; i++)
			for(int k=0; k<=x+1; k++){
				DP[i][k]=0;
				if(i==1 && k>0 && k<=x)
					if(field[i][k] == 0)
						DP[i][k] = 1;
			}
		
		for(int i=2; i<=y; i++){
			for(int k=1; k<=x; k++){
				if(field[i][k] == 0)
					DP[i][k] += DP[i-1][k-1] + DP[i-1][k] + DP[i-1][k+1];
				else if(field[i][k] == 2)
					int n = i+2;
					while(true){
						if(field[n][k] == 0){
							DP[n][k] += DP[i-1][k];
							break;
						}else if(field[n][k] == 1)
							break;
						else
							n+=2;
					}
				}
			}
		}
		
		int ans=0;
		for(int i=y; i<=y+1; i++)
			for(int k=1; k<=x; k++)
				ans += DP[i][k];
		cout << ans << endl;
	}
}