#include <stdio.h>
#include <limits.h>
#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3

/* 各方向への移動ベクトル (dx,dy) */
int MOVEMENT[4][2] = { {0, -1}, {0, 1}, {-1, 0}, {1, 0} };
/* 迷路 */
int w, h; /* 大きさ */
int wall[30][30][4]; /* 各マスの各方向の壁の有無 */

/* 幅優先探索 */
int memo[30][30]; /* 探索のメモ (あるマスに到達するまでの最短経路長) */
int UNREACHED = INT_MAX;
typedef struct { int step; int x; int y; } Log; /* 探索状態 */

/* FIFOキュー */
typedef Log Data;
Data queue[2000]; int queue_size = 2000; int queue_head; int queue_length;
void initqueue() {
	queue_length = 0;
}
void enqueue(Data d) {
	queue[(queue_head + queue_length) % queue_size] = d;
	queue_length++;
}
Data dequeue() {
	Data d = queue[queue_head];
	queue_head = (queue_head + 1) % queue_size;
	queue_length--;
	return d;
}

/* 幅優先探索をして入口から出口までの最短経路長を返す */
int search(Log l) {
	int min = UNREACHED;
	int i;
	/* この試行が現在いるマスまでの最短経路か確認する */
	if (l.step > memo[l.y][l.x]) return UNREACHED;

	/* 次のマス */
	for (i = 0; i < 4; i++) {
		/* 壁がある方向へは進めない */
		if (wall[l.y][l.x][i]) continue;

		/* 次の動作を行った場合の状態を作る */
		Log next;
		next.x = l.x + MOVEMENT[i][0];
		next.y = l.y + MOVEMENT[i][1];
		next.step = l.step + 1;

		if (next.x == w - 1 && next.y == h - 1) {
			/* ゴールに到達 */
			if (next.step < min) min = next.step;
		} else {
			/* 次に探索する状態をキューに入れる */
			if (next.step < memo[next.y][next.x]) {
				memo[next.y][next.x] = next.step;
				enqueue(next);
			}
		}
	}

	return min;
}

int main(void) {
	int min, i, j;
	int p[59][30];

	/* データセット毎の処理 */
	while (scanf("%d%d", &w, &h) == 2 && w >= 2 && h >= 2) {
		/* 迷路の壁を読み込む */
		for (i = 0; i < h * 2 - 1; i++) {
			for (j = 0; j < w - (i + 1) % 2; j++) {
				scanf("%d", &p[i][j]);
			}
		}
		/* 壁の情報を使いやすい形式に変換する */
		for (i = 0; i < h; i++) {
			for (j = 0; j < w; j++) {
				/* 各マスの各方向に壁があるか (迷路の端には必ず壁があるとする) */
				wall[i][j][UP] = (i == 0) ? 1 : p[i*2-1][j];
				wall[i][j][DOWN] = (i == h-1) ? 1 : p[i*2+1][j];
				wall[i][j][LEFT] = (j == 0) ? 1 : p[i*2][j-1];
				wall[i][j][RIGHT] = (j == w-1) ? 1 : p[i*2][j];
			}
		}

		/* メモを初期化する */
		for (i = 0; i < h; i++) for (j = 0; j < w; j++) memo[i][j] = UNREACHED;

		/* 探索の始点をキューに入れる */
		Log l = {1, 0, 0};
		enqueue(l);

		/* 幅優先探索する */
		min = UNREACHED;
		while (queue_length > 0) {
			int step = search(dequeue());
			if (step < min) min = step;
		}

		/* 結果を出力する */
		if (min == UNREACHED) min = 0;
		printf("%d\n", min);
	}

	return 0;
}