#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <map>
using namespace std;

#define REP(i, s, e) for (int i = (s); i < (e); i++)
#define REPI(i, s, e) for (int i = (s); i <= (e); i++)
#define rep(i, n) REP(i, 0, n)
#define repi(i, n) REPI(i, 0, n)
#define ALL(v) (v).begin(), (v).end()

#define dump(x) (cout << #x << " = " << x << endl)
#define dump2(x, y) (cout << "(" << #x << ", " << #y << ") = (" << x << ", " << y << ")" << endl)
#define dump3(x, y, z) (cout << "(" << #x << ", " << #y << ", " << #z << ") = (" << x << ", " << y << ", "<< z << ")" << endl)

typedef long long ll;
typedef pair<int, int> pii;

#define VACANT 0
#define BLOCK 1
#define START 2
#define GOAL 3

#define INF (1<<29)
#define MAX 21

int w, h;
int brd[MAX][MAX];
int ans;

int sx, sy;
int gx, gy;

int dx[] = { -1, 1, 0, 0 };
int dy[] = { 0, 0, -1, 1 };

void dfs(int depth, int y, int x)
{
/*
rep(j, h) {
	rep(i, w) {
		char ch;
		switch(brd[j][i]) {
		case VACANT: ch = '.'; break;
		case BLOCK: ch = '#'; break;
		}
		if (j == y && i == x)
			ch = 'X';
		if (j == gy && i == gx)
			ch = 'G';
		printf("%c ", ch);
	}
	puts("");
}
puts("-------");
*/
	if (depth >= 10) return;

	rep(i, 4) {
		REP(t, 1, max(w, h)) {
			int ny = y+dy[i]*t, nx = x+dx[i]*t;
			if (ny == gy && nx == gx) {
				ans = min(ans, depth+1);
				return;
			}
			if (!(0 <= ny && ny < h)) goto NEXT;
			if (!(0 <= nx && nx < w)) goto NEXT;
			if (t == 1 && brd[ny][nx] == BLOCK) goto NEXT;
			if (brd[ny][nx] == BLOCK) {
				int ty = ny-dy[i], tx = nx-dx[i];
				brd[ny][nx] = VACANT;
				dfs(depth+1, ty, tx);
				brd[ny][nx] = BLOCK;
				break;
			}
		}
NEXT:
		;
	}
}

int main(void)
{
	while (cin >> w >> h, w|h) {
		rep(j, h)
			rep(i, w) {
				cin >> brd[j][i];
				if (brd[j][i] == START) {
					brd[j][i] = VACANT;
					sx = i, sy = j;
				} else if (brd[j][i] == GOAL) {
					brd[j][i] = VACANT;
					gx = i, gy = j;
				}
			}

		ans = INF;
		dfs(0, sy, sx);
		printf("%d\n", ans==INF?-1:ans);
	}
	return 0;
}
// clang-format off
#include <bits/stdc++.h>
#define int long long
#define main signed main()
// #define main int main()
#define loop(i, a, n) for (int i = (a); i < (n); i++)
#define rep(i, n) loop(i, 0, n)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define prec(n) fixed << setprecision(n)
#define stlice(from, to) substr(from, (to) - (from) + 1)
#define pb push_back
#define mp make_pair
#define mt make_tuple
#define fi first
#define se second
using namespace std;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<double> vd;
typedef vector<char> vc;
typedef vector<bool> vb;
typedef vector<string> vs;
typedef vector<pii> vpii;
typedef vector<vi> vvi;
typedef vector<vb> vvb;
typedef vector<vpii> vvpii;
const int INF = sizeof(int) == sizeof(long long) ? 1000000000000000000LL : 1000000000;
const int MOD = 1000000007;
const double PI = acos(-1);
template<typename A, typename B> bool cmin(A &a, const B &b) { return a > b ? (a = b, true) : false; }
template<typename A, typename B> bool cmax(A &a, const B &b) { return a < b ? (a = b, true) : false; }
bool odd(const int &n) { return n & 1; }
bool even(const int &n) { return !odd(n); }
void solve();
main { solve(); return 0; }
// clang-format on

int di[] = {1, 0, -1, 0}, dj[] = {0, 1, 0, -1};

void solve() {
  for (;;) {
    vs s(12);
    rep(i, 12) if (!(cin >> s[i])) return;
    int c = 0;
    rep(i, 12) rep(j, 12) {
      function<void(int, int)> dfs = [&](int i, int j) {
        if (i < 0 || j < 0 || i >= 12 || j >= 12 || s[i][j] == '0') return;
        s[i][j] = '0';
        rep(k, 4) dfs(i + di[k], j + dj[k]);
      };
      c += s[i][j] == '1';
      dfs(i, j);
    }
    cout << c << endl;
  }
}