// #define USE_CPP11
// #define USE_PRINTF
 
#include <iostream>
#include <iomanip>
#include <map>
#include <set>
#include <utility>
#include <vector>
#include <string>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <climits>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <numeric>
#include <complex>
#include <memory>
#include <sstream>
 
#ifdef USE_CPP11
#include <unordered_map>
#include <unordered_set>
#include <functional>
#endif
 
#define PRINT(obj) cout << obj << endl
#define REP(i, n) for(int (i) = 0; (i) < (n); i++)
#define SPACE " "
 
typedef long long ll;
 
using namespace std;

const int INF = 1e9 + 10;
 
namespace Scanner {
#ifdef USE_PRINTF
  int    nextInt()    { int    d; scanf("%d" , &d); return d; }
  float  nextFloat()  { float  f; scanf("%f" , &f); return f; }
  double nextDouble() { double f; scanf("%lf", &f); return f; }  
  string nextString() { string s; scanf("%s" , &s); return s; }
  ll     nextll()     { ll     l; scanf("%ll", &l); return l; }
#else
  int    nextInt()    { int    d; cin >> d; return d; }
  float  nextFloat()  { float  f; cin >> f; return f; }
  double nextDouble() { double f; cin >> f; return f; }  
  string nextString() { string s; cin >> s; return s; }
  ll     nextll()     { ll     l; cin >> l; return l; }
#endif
 
  string getLine() { 
    string input;
    getline(cin, input);
    return input;
  }
};
 
namespace myLibrary {
  vector<string> split(const string& str, char delim) {
    vector<string> ret;
    size_t current = 0, found;
    while ((found = str.find_first_of(delim, current)) != string::npos) {
      ret.push_back(string(str, current, found - current));
      current = found + 1;
    }
    ret.push_back(string(str, current, str.size() - current));
    return ret;
  }
   
#ifdef USE_CPP11
  ///
  /// higher-order functional
  /// This is something like map in haskell, python, etc.
  /// Sample usage:
  ///   vector<int> a = {1, 2, 3, 4, 5};
  ///   vector<int> b = myLibrary::_Map<int, int>(a, [](int n){
  ///     return n * n;
  ///   });
  /// Result:
  ///   b = 1, 4, 9, 16, 25
  ///
  template<typename T_IN, typename T_OUT, class Functor>
  vector<T_OUT> _Map(vector<T_IN> src, Functor func) {
    vector<T_OUT> ret;
    for (int i = 0; i < src.size(); i++) {
      ret.push_back(func(src[i]));
    }
    return ret;
  }
#endif
 
};
 
/// BEGIN //////////////////////////////////////////////////////////
 
enum Square {
  EMPTY = 0, OBJECT  
};

struct Point {
public:
  int y, x;
  Point() { }
  Point(int y, int x): y(y), x(x) { }
  bool operator==(const Point& p) {
    return (p.y == y) && (p.x == x);
  }
};


int w, h;
Square field[21][21];
Point start, goal;

int solve(Point p, int step) {
  if (step > 9) {
    return INF;
  }
 
 
  int dy[4] = { -1, 0, 0, 1 }; 
  int dx[4] = { 0, -1, 1, 0 };

  
  int score, score_min = INF;
  
  REP(i, 4) {
    int ny = p.y + dy[i];
    int nx = p.x + dx[i];
    if (field[ny][nx] == OBJECT) {
      continue;
    }
    for (int j = 1; ; j++) {
      ny = p.y + j * dy[i];
      nx = p.x + j * dx[i];
      
      if (ny < 0 || ny >= h) {
        break;
      }
      
      if (nx < 0 || nx >= w) {
        break;
      }
      
      if (goal.y == ny && goal.x == nx) {
        return step + 1;  
      }
      
      if (field[ny][nx] == OBJECT) {
        field[ny][nx] = EMPTY;
        score = solve(Point(ny - dy[i], nx - dx[i]), step + 1);
        field[ny][nx] = OBJECT;
        score_min = min(score, score_min);
        break;
      }
    }
  }
  
  return score_min;
};

int main() {
  while (true) {
    w = Scanner::nextInt();
    h = Scanner::nextInt();
    if (w + h == 0) break;
    
    memset(field, 0, sizeof(field));
 
    REP(y, h) {
      REP(x, w) {
        int s = Scanner::nextInt();
        switch (s) {
          case 2: {
            start = Point(y, x);   
            field[y][x] = EMPTY;
            break;         
          }
          case 3: {
            goal = Point(y, x);
            field[y][x] = EMPTY;
            break;
          }
          case 0: {
            field[y][x] = EMPTY;
            break;
          }
          case 1: {
            field[y][x] = OBJECT;
            break;
          }
        }
      }
    }
   
    int ans = solve(start, 0);
    
    if (ans == INF) {
      PRINT(-1);
    } else {
      PRINT(ans);
    }
  }
  
  return 0;
}
 
/// END   //////////////////////////////////////////////////////////

Measured memory_bytes: 1164