using namespace std;
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <cassert>

#define INF INT_MAX/3

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define DECFOR(i,a,b) for(int i=(a);i>(b);--i)
#define REP(i,n)  FOR(i,0,n)

#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

#define MAX_W 20
#define MAX_H 20
#define MOVING_LIMIT 10

#define NORTH 1
#define EAST 2
#define SOUTH 3
#define WEST 4

enum CellState {
  EMPTY,
  OBSTACLE,
  START,
  STOP
};

struct Position {
  int x;
  int y;
};

struct GameState {
  int width;
  int height;
  CellState field[MAX_H][MAX_W];
  Position pos;
  int dir;
};

struct Moving {
  Position begin;
  Position end;
  int dir;
};

int load(GameState* state) {
  int w, h;
  scanf("%d %d", &w, &h);
  if( w == 0 && h == 0 ) return 0;
  state->width = w;
  state->height = h;
  REP(i, h) REP(j, w) {
    scanf("%d", &(state->field[i][j]));
    if( state->field[i][j] == START ) {
      state->pos.x = j;
      state->pos.y = i;
    }
  }
  return 1;
}

int move(Moving* mv, GameState* state) {
  mv->begin = state->pos;
  mv->dir = state->dir;
  switch(state->dir) {
  case NORTH:
    if( state->field[state->pos.y+1][state->pos.x] == OBSTACLE ) {
      return 0;
    }
    FOR(i, state->pos.y, state->height) {
      if( state->field[i][state->pos.x] == STOP ) {
        state->pos.y = i;
        return 2;
      }
      if( state->field[i][state->pos.x] == OBSTACLE ) {
        state->field[i][state->pos.x] = EMPTY;
        state->pos.y = i-1;
        mv->end.x = state->pos.x;
        mv->end.y = i;
        return 1;
      }
    }
    return 0;
  case EAST:
    if( state->field[state->pos.y][state->pos.x+1] == OBSTACLE ) {
      return 0;
    }
    FOR(j, state->pos.x, state->width) {
      if( state->field[state->pos.y][j] == STOP ) {
        state->pos.x = j;
        mv->end.x = j;
        mv->end.y = state->pos.y;
        return 2;
      }
      if( state->field[state->pos.y][j] == OBSTACLE ) {
        state->field[state->pos.y][j] = EMPTY;
        state->pos.x = j-1;
        mv->end.x = j;
        mv->end.y = state->pos.y;
        return 1;
      }
    }
    return 0;
  case SOUTH:
    if( state->field[state->pos.y-1][state->pos.x] == OBSTACLE ) {
      return 0;
    }
    DECFOR(i, state->pos.y, -1) {
      if( state->field[i][state->pos.x] == STOP ) {
        state->pos.y = i;
        mv->end.x = state->pos.x;
        mv->end.y = i;
        return 2;
      }
      if( state->field[i][state->pos.x] == OBSTACLE ) {
        state->field[i][state->pos.x] = EMPTY;
        state->pos.y = i+1;
        mv->end.x = state->pos.x;
        mv->end.y = i;
        return 1;
      }
    }
    return 0;
  case WEST:
    if( state->field[state->pos.y][state->pos.x-1] == OBSTACLE ) {
      return 0;
    }
    DECFOR(j, state->pos.x, -1) {
      if( state->field[state->pos.y][j] == STOP ) {
        state->pos.x = j;
        return 2;
      }
      if( state->field[state->pos.y][j] == OBSTACLE ) {
        state->field[state->pos.y][j] = EMPTY;
        state->pos.x = j+1;
        mv->end.x = j;
        mv->end.y = state->pos.y;
        return 1;
      }
    }
    return 0;
  default:
    return -1;
  }
}

int rotate(GameState* state) {
  state->dir = (state->dir+1) % 5;
  return state->dir;
}

void revert_move(Moving* mv, GameState* state) {
  state->pos = mv->begin;
  state->dir = mv->dir;
  state->field[mv->end.y][mv->end.x] = OBSTACLE;
}

int solve(GameState* state) {
  Moving stack[MOVING_LIMIT];
  int count = 0;
  int ret = MOVING_LIMIT;
  state->dir = NORTH;
  while(1) {
    switch( move(&stack[count], state) ) {
    case 0:
      rotate(state);
      break;
    case 1:
      if( count+1 == MOVING_LIMIT ) {
        revert_move(&stack[count], state);
        rotate(state);
      } else {
        ++count;
        state->dir = NORTH;
      }
      break;
    case 2:
      ret = min(ret, count);
      --count;
      if( count < 0 ) break;
      revert_move(&stack[count], state);
      rotate(state);
      break;
    default:
      --count;
      if( count < 0 ) break;
      revert_move(&stack[count], state);
      rotate(state);
      break;
    }
    if( count < 0 ) break;
  }
  if( ret == MOVING_LIMIT ) return -1;
  return ret+1;
}

int main() {
  GameState state;
  while( load(&state) ) {
    printf("%d\n", solve(&state));
  }
  return 0;
}

Measured memory_bytes: 1188