#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;
}