import std.stdio, std.string, std.algorithm, std.conv, std.array, std.container;

immutable int LEFT = 0;
immutable int DOWN = 1;
immutable int RIGHT = 2;
immutable int UP = 3;
immutable int INF = 10_0000_0000;

void set( bool[][][] canMove, int l, int dir, int[] val ) {
  switch( dir ) {
  case LEFT:
	foreach ( x; 1 .. canMove[ 0 ].length ) {
	  canMove[ l ][ x ][ dir ] = ( val[ x - 1 ] == 0 );
	}
	break;
  case DOWN:
  case UP:
	foreach ( x; 0 .. canMove[ 0 ].length ) {
	  canMove[ l ][ x ][ dir ] = ( val[ x ] == 0 );
	}
	break;
  case RIGHT:
	foreach ( x; 0 .. canMove[ 0 ].length - 1 ) {
	  canMove[ l ][ x ][ dir ] = ( val[ x ] == 0 );
	}
	break;
  default:
	break;
  }
}

struct Point {
  int y;
  int x;

  this( int y, int x ) {
	this.y = y;
	this.x = x;
  }
}

void main() {
  while ( true ) {
  	auto wh = split( strip( readln ) );
  	immutable int w = to!int( wh[ 0 ] );
  	immutable int h = to!int( wh[ 1 ] );
  	if ( w == 0 && h == 0 ) break;
	
	int[][] turn = new int[][]( h, w );
  	bool[][][] canMove = new bool[][][]( h, w, 4 );

	foreach ( i; 0 .. h - 1 ){
	  auto tokens = array( map!( to!int )( split( strip( readln ) ) ) );
	  set( canMove, i, LEFT, tokens );
	  set( canMove, i, RIGHT, tokens );
	  tokens = array( map!( to!int )( split( strip( readln ) ) ) );
	  set( canMove, i, DOWN, tokens );
	  if ( i != h - 2 ) {
		set( canMove, i + 1, UP, tokens );
	  }
  	}
	auto tokens = array( map!( to!int )( split( strip( readln ) ) ) );
	set( canMove, h - 1, LEFT, tokens );
	set( canMove, h - 1, RIGHT, tokens );
	
	immutable int[] dx = [ -1, 0, 1, 0 ];
  	immutable int[] dy = [ 0, 1, 0, -1 ];

	auto queue = SList!Point();
	queue.insertFront( Point( 0, 0 ) );
	foreach ( ary; turn ) {
	  ary[] = INF;
	}
	turn[ 0 ][ 0 ] = 1;
	
	while ( !queue.empty ) {
	  auto p = queue.front;
	  queue.removeFront;
	  if ( p.y == h - 1 && p.x == w - 1 ) {
		break;
	  }
	  foreach ( dir; 0 .. 4 ) {
		int ny = p.y + dy[ dir ];
		int nx = p.x + dx[ dir ];
		if ( canMove[ p.y ][ p.x ][ dir ] && turn[ ny ][ nx ] == INF ) {
		  queue.insert( Point( ny, nx ) );
		  turn[ ny ][ nx ] = turn[ p.y ][ p.x ] + 1;
		}
	  }
	}
	writeln( turn[ h - 1 ][ w - 1 ] == INF ? 0 : turn[ h - 1 ][ w - 1 ] );
  }
}