import Control.Monad (replicateM, filterM, forM)
import Control.Monad.ST (ST, runST)
import Data.Array (Array, listArray, (!), bounds)
import qualified Data.Array.ST as STArr

type Field = Array (Int,Int) Bool
type Visited s = STArr.STUArray s (Int,Int) Bool

main = do
    m <- readLn
    n <- readLn
    if all (==0) [m,n] then return () else do
        lines <- replicateM n (getLine >>= return . map (=="1") . words)
        let field = listArray ((1,1),(n,m)) (concat lines)
        print $ solve m n field

        main

solve :: Int -> Int -> Field -> Int
solve m n field = runST $ do
    visited <- STArr.newArray ((1,1),(n,m)) False :: ST s (Visited s)
    maximum `fmap` mapM (longestFrom field visited) starts

    where
    starts = filter (field !) [(y,x)|y<-[1..n],x<-[1..m]]

longestFrom :: Field -> Visited s -> (Int,Int) -> ST s Int
longestFrom field visited (y,x) = do
    STArr.writeArray visited (y,x) True

    nexts <- filterM visitable [(y-1,x),(y+1,x),(y,x-1),(y,x+1)]
    longest <- ((1+) . maximum') `fmap` forM nexts (longestFrom field visited)

    STArr.writeArray visited (y,x) False
    return longest

    where
    (_,(n,m)) = bounds field

    maximum' [] = 0
    maximum' xs = maximum xs

    visitable (y,x)
        | x < 1 || y < 1 || x > m || y > n = return False
        | not (field ! (y,x)) = return False
        | otherwise = not `fmap` STArr.readArray visited (y,x)