{-
URL: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1144&lang=jp
?????????: Curling 2.0
?????°:
2017/06/26
20:03	curling2.0???c++??§?§£????????¨?????????c++??????????????????????????????????????£????????§??????????¨??????§??????Haskell??§????£????????????????
20:04	?????????????????????????????°???????????°?????????????????£????????????????????????Haskell??§?????§????????§??????????????????????????¶??????TLE????????£?????????????????§?????????????????????
-}

import Control.Monad
import Control.Applicative
import Data.List
import Data.Either

type Board = [[Foo]]
data Foo = Empty | Block | Rock | Finir deriving(Show,Eq,Ord)

fromStr :: String -> Foo
fromStr "0" = Empty
fromStr "1" = Block
fromStr "2" = Rock
fromStr "3" = Finir

main = do
 [w,h] <- (map read . words)<$> getLine
 unless(w==0 && h==0) $ do
  arr <- replicateM h (words<$>getLine)
  let num = analyze (map (map fromStr) arr)
  print num
  main

analyze :: Board -> Int
analyze board
 | ans == 11  = -1
 | otherwise = ans
 where ans = length . takeWhile (/=Nothing) . take 11 $ iterate (>>== throwOnce) (Just[board])
 -- ????????¶???????????????????????????iterate??§???????????????11????????????Nothing??????????????????????????????????????????

(>>==) :: (Monad m) => m[a] -> (a -> m[b]) -> m[b] -- ??????????????¢???????£???§???????????????bind?????????
m_l_a >>== f = do
 l_a <- m_l_a
 ll_b <- mapM f l_a
 return(concat ll_b)


throwOnce :: Board -> Maybe [Board] -- NOTE: Nothing MEANS SUCCESS
throwOnce b
 | Left True `elem` arr = Nothing -- ??´????????????1???????????°??´??????
 | otherwise = Just(rights arr) -- ??±?????????????????????????£??????????
 where arr = map ($b) [throwLeft,throwDown,throwRight,throwUp]

throwLeft :: Board -> Either Bool Board
throwLeft = fmap(map reverse) . throwRight . map reverse

throwDown :: Board -> Either Bool Board
throwDown = fmap transpose . throwRight . transpose

throwUp :: Board -> Either Bool Board
throwUp = fmap transpose . throwLeft . transpose

-- Left True: goal
-- Left False: outside-the-board failure, or the rock is next to the block
-- This function only throws to the right.
throwRight :: Board -> Either Bool Board
throwRight = mapM step where
 step :: [Foo] -> Either Bool [Foo]
 step arr = case break (==Rock) arr of -- Rock???????????§?????¶??????
  (_,[]) -> Right arr -- A row without a rock cannot be altered
  (_,[_]) -> Left False -- no wall => outside-the-board failure
  (_,_:Block:_) -> Left False -- rock is next to the block
  (a,_:b) -> case span (==Empty) b of -- Empty?????????????????????
   (es,Block:c) -> Right(a ++ es ++ [Rock,Empty]++c) -- c????????????????????´??????Empty???????????´??????Rock???es???Rock???????????????1??????????????????
   (es,Finir:c) -> Left True -- ??´??????
   (es,[]) -> Left False -- no wall => outside-the-board failure