#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) REP(i, 0, (n))
#define REP(i, a, n) for(int i=(a); i<(n); i++)

#define ISIN(i, j) (0<=i && i<h && 0<=j && j < w)
#define ISOK(i, j) (ISIN(i, j) && (b[i][j]==NONE || b[i][j]==GOAL))
#define UNREACHABLE 100

enum Grid {NONE, BLOCK, START, GOAL};
enum Dir {NORTH, SOUTH, EAST, WEST};

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

tuple<int, int, bool, bool> move(int i, int j, Dir d) {
    assert(ISOK(i, j));
    switch(d) {
    case NORTH:
        for(; ISIN(i, j) && b[i][j]==NONE; i--);
        if(!ISIN(i, j)) return make_tuple(-1, -1, false, true);
        if(b[i][j]==BLOCK) {
            b[i][j] = NONE;
            return make_tuple(i+1, j, true, false);
        }
        break;
    case SOUTH:
        for(; ISIN(i, j) && b[i][j]==NONE; i++);
        if(!ISIN(i, j)) return make_tuple(-1, -1, false, true);
        if(b[i][j]==BLOCK) {
            b[i][j] = NONE;
            return make_tuple(i-1, j, true, false);
        }
        break;
    case EAST:
        for(; ISIN(i, j) && b[i][j]==NONE; j++);
        if(!ISIN(i, j)) return make_tuple(-1, -1, false, true);
        if(b[i][j]==BLOCK) {
            b[i][j] = NONE;
            return make_tuple(i, j-1, true, false);
        }
        break;
    case WEST:
        for(; ISIN(i, j) && b[i][j]==NONE; j--);
        if(!ISIN(i, j)) return make_tuple(-1, -1, false, true);
        if(b[i][j]==BLOCK) {
            b[i][j] = NONE;
            return make_tuple(i, j+1, true, false);
        }
        break;
    }
    return make_tuple(i, j, false, false);
}

int search(int i, int j, int cnt) {
    assert(ISOK(i, j));
    if(cnt > 10) return UNREACHABLE;
    if(b[i][j] == GOAL) return cnt;
    
    int ret = UNREACHABLE;
    if(ISOK(i-1, j)) {
        auto t = move(i, j, NORTH);
        int p = get<0>(t), q = get<1>(t);
        bool removed = get<2>(t), out = get<3>(t);
        
        ret = min(ret, out? UNREACHABLE:search(p, q, cnt+1));
        if(removed) b[p-1][q] = BLOCK;
    }
    if(ISOK(i+1, j)) {
        auto t = move(i, j, SOUTH);
        int p = get<0>(t), q = get<1>(t);
        bool removed = get<2>(t), out = get<3>(t);
        
        ret = min(ret, out? UNREACHABLE:search(p, q, cnt+1));
        if(removed) b[p+1][q] = BLOCK;
    }
    if(ISOK(i, j+1)) {
        auto t = move(i, j, EAST);
        int p = get<0>(t), q = get<1>(t);
        bool removed = get<2>(t), out = get<3>(t);
        
        ret = min(ret, out? UNREACHABLE:search(p, q, cnt+1));
        if(removed) b[p][q+1] = BLOCK;
    }
    if(ISOK(i, j-1)) {
        auto t = move(i, j, WEST);
        int p = get<0>(t), q = get<1>(t);
        bool removed = get<2>(t), out = get<3>(t);
        
        ret = min(ret, out? UNREACHABLE:search(p, q, cnt+1));
        if(removed) b[p][q-1] = BLOCK;
    }

    return ret;
}


int main() {
	while(cin>>w>>h, w+h) {
	    int p, q;
	    rep(i, h) {
	        rep(j, w) {
	            cin >> b[i][j];
	            if(b[i][j] == START) {
	                p = i;
	                q = j;
	                b[i][j] = NONE;
	            }
	        }
	    }
	    int ans = search(p, q, 0);
	    cout << (ans==UNREACHABLE? -1:ans) << endl;
	}
}



Measured memory_bytes: 3092