#include<iostream>
#include<cstdlib>
#include<queue>
#define MAX 22
#define BLOCK 1
#define START 2
#define GOAL 3
#define REP(i,a,e) for(int i=(a);i<=(e);++i)
#define REPD(i,a,e) for(int i=(a);i>=(e);--i)
using namespace std;
struct Map{
	Map(){
		REP(i,0,MAX-1)REP(j,0,MAX-1)map[i][j]=0;
	}
	int h,w;
	char map[MAX][MAX];
	int depth;
	pair<int, int> stone;
};
int BFS(Map &m){
	queue<Map> q;
	
	q.push( m );
	while( !q.empty() ){
		Map t = q.front();
		q.pop();

		/* up */
		REPD(i,t.stone.first,0){
			if( t.map[i][ t.stone.second ] == BLOCK ){
				if( abs(i-t.stone.first) > 1 ){
					Map tt = t;
					tt.map[ i ][ t.stone.second ] = 0;
					tt.stone = make_pair( i + 1, t.stone.second );
					if( ++tt.depth < 10 )
						q.push( tt );
				}
				break;
			}else if( t.map[i][ t.stone.second ] == GOAL ){
				return t.depth+1;
			}
		}
		/* down */
		REP(i,t.stone.first,t.h+1){
			if( t.map[i][ t.stone.second ] == BLOCK ){
				if( abs(i-t.stone.first) > 1 ){
					Map tt = t;
					tt.map[ i ][ t.stone.second ] = 0;
					tt.stone = make_pair( i - 1, t.stone.second );
					if( ++tt.depth < 10 )
						q.push( tt );
				}
				break;
			}else if( t.map[i][ t.stone.second ] == GOAL ){
				return t.depth+1;
			}
		}
		/* right */
		REP(j,t.stone.second,t.w+1){
			if( t.map[ t.stone.first ][ j ] == BLOCK ){
				if( abs(j-t.stone.second) > 1 ){
					Map tt = t;
					tt.map[ t.stone.first ][ j ] = 0;
					tt.stone = make_pair( t.stone.first, j - 1 );
					if( ++tt.depth < 10 )
						q.push( tt );
				}
				break;
			}else if( t.map[ t.stone.first ][ j ] == GOAL ){
				return t.depth+1;
			}
		}
		/* left */
		REPD(j,t.stone.second,0){
			if( t.map[ t.stone.first ][ j ] == BLOCK ){
				if( abs(j-t.stone.second) > 1 ){
					Map tt = t;
					tt.map[ t.stone.first ][ j ] = 0;
					tt.stone = make_pair( t.stone.first, j + 1 );
					if( ++tt.depth < 10 )
						q.push( tt );
				}
				break;
			}else if( t.map[ t.stone.first ][ j ] == GOAL ){
				return t.depth+1;
			}
		}
	}
	return -1;
}
int main(){
	while(true){
		Map m;
		scanf("%d%d", &m.w, &m.h);
		if( m.w==0 && m.h==0 )break;

		REP(i,1,m.h)REP(j,1,m.w){
			scanf("%d", &m.map[i][j]);
			if( m.map[i][j] == START ){
				m.stone=make_pair(i,j);
			}
		}
		m.depth = 0;

		printf("%d\n", BFS( m ));
	}
}
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

const int INF = 1 << 30;
const int dx[] = {1, 0, -1, 0};
const int dy[] = {0, -1, 0, 1};

int w, h, field[20][20];

int solve(int x, int y, int t)
{
  if (t > 9)
    return INF;

  int ans = INF;
  for (int i = 0; i < 4; ++i) {
    int xx = x + dx[i];
    int yy = y + dy[i];
    if (xx < 0 || xx >= w || yy < 0 || yy >= h || field[yy][xx] == 1)
      continue;

    bool infield = true;
    while (field[yy][xx] == 0) {
      xx += dx[i];
      yy += dy[i];
      if (xx < 0 || xx >= w || yy < 0 || yy >= h) {
	infield = false;
	break;
      }
    }
    if (!infield)
      continue;

    if (field[yy][xx] == 3)
      return t+1;

    if (field[yy][xx] == 1) {
      field[yy][xx] = 0;
      ans = min(ans, solve(xx-dx[i], yy-dy[i], t+1));
      field[yy][xx] = 1;
    }
  }
  return ans;
}

int main()
{
  while (scanf("%d %d", &w, &h) != EOF) {
    if (w == 0 && h == 0)
      break;

    int x, y;
    for (int i = 0; i < h; ++i) {
      for (int j = 0; j < w; ++j) {
	scanf("%d", &field[i][j]);
	if (field[i][j] == 2) {
	  x = j;
	  y = i;
	  field[i][j] = 0;
	}
      }
    }

    int ans = solve(x, y, 0);
    if (ans == INF)
      ans = -1;
    printf("%d\n", ans);
  }
  return 0;
}