Problem:
会津山スキー場の新企画

会津山スキー場の経営者である油木屋さんは、上級者向けとして障害物やジャンプ台を配置したコースを用意しました。コースにはいろいろな滑り方があり、シーズン中に全てのパターンの滑り方が出来た利用者には、プレゼントを贈ることになっています。

油木屋さんのために、コースの見取り図をもとに滑り方のパターン数を出力するプログラムを作ってあげましょう。

コースは上図のような X × Y 個のマスからなるグリッドで表されます。左上を原点とし、x 座標は右に行くにつれて大きくなり、y 座標は下にいくにつれて大きくなるものとします。

各滑り方のパターンは、最も高いところ(y = 1 、ただし障害物の無いところ) からスタートし、ゴール(y = Y) に向かって進んでいきます。グリッドのマス(x, y) にいる滑走者は、(x − 1, y + 1)、(x, y + 1)、 (x + 1, y + 1) のいずれかに移動することができます。マスには、障害物やジャンプ台があり、障害物のあるマスには進入できず、ジャンプ台があるマスに進入すると(x, y + 2) へ移動します。ただし、いちばん高いマス (y = 1 のマス) にはジャンプ台は存在せず、ジャンプ台のあるマスに進入する際には x 座標が同じマスからしか進入できません。コースの上端(y = 1) からスタートし、コースからはずれることなく下端を超えれば(y ≥ Y) 1つの滑り方とみなし、滑り終わります。

コースの情報を入力とし、滑り方の総数を出力するプログラムを作成してください。

Input

複数のデータセットの並びが入力として与えられます。入力の終わりはゼロふたつの行で示されます。各データセットは以下の形式で与えられます。

X Y
c11 c21 ... cX1
c12 c22 ... cX2
:
c1Y c2Y ... cXY

1 行目にコースの大きさX, Y (1 ≤ X, Y ≤ 15) が与えられます。続く Y 行にコースの情報が与えられます。cij (0 , 1 , 2 のいずれか) はx = i, y = j のマスの情報を表す整数で、0 が移動可能なマス、1 が障害物があるマス、2 がジャンプ台があるマスを表します。

データセットの数は 50 を超えません。

Output

入力データセットごとに、コースの滑り方のパターン数を1行に出力します。

Sample Input

5 5
0 0 0 0 1
2 1 0 2 0
1 0 0 1 1
0 2 1 2 0
0 1 0 0 0
5 5
0 0 1 0 0
2 1 0 2 0
1 0 0 1 1
0 2 1 2 0
0 1 0 0 0
15 15
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0

Output for the Sample Input

8
6
52694573

Solution in JAVA (judge verdict: Accepted)

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		
		while(true){
			final int X = sc.nextInt();
			final int Y = sc.nextInt();
			
			if(X == 0 && Y == 0){
				break;
			}
			
			int[][] map = new int[Y][X];
			
			for(int i = 0; i < Y; i++){
				for(int j = 0; j < X; j++){
					map[i][j] = sc.nextInt();
				}
			}
			
			int[][] dp = new int[Y+2][X];
			
			for(int i = 0; i < Y; i++){
				for(int j = 0; j < X; j++){
					if(map[i][j] == 1){
						dp[i][j] = 0;
						//System.out.print(dp[i][j] + " ");
						continue;
					}
					
					if(i == 0){
						dp[i][j] = 1;
					}else{
						dp[i][j] += (map[i-1][j] == 0 ? dp[i-1][j] : 0);
						if(map[i][j] != 2){
							dp[i][j] += j != 0 ? (map[i-1][j-1] == 0 ? dp[i-1][j-1] : 0) : 0;
							dp[i][j] += j != X-1 ? (map[i-1][j+1] == 0 ? dp[i-1][j+1] : 0) : 0;
						}
					}
					
					if(map[i][j] == 2){
						dp[i+2][j] = dp[i][j];
					}
					
					//System.out.print(dp[i][j] + " ");
				}
				
				//System.out.println();
			}
			/*
			for(int i = Y; i < Y+2; i++){
				for(int j = 0; j < X; j++){
					System.out.print(dp[i][j] + " ");
				}
				System.out.println();
			}
			*/
			for(int i = Y; i < Y+2; i++){
				for(int j = 0; j < X; j++){
					if(i == Y && map[i-1][j] == 2){
						continue;
					}
					dp[i][j] += dp[i-1][j];
				}
			}
			/*
			System.out.println("--------------------------");
			for(int i = Y; i < Y+2; i++){
				for(int j = 0; j < X; j++){
					System.out.print(dp[i][j] + " ");
				}
				System.out.println();
			}
			*/
			int sum = 0;
			for(int j = 0; j < X; j++){
				sum += dp[Y+1][j];
			}
			
			System.out.println(sum);
		}
		
	}

}