import qualified Data.Text.Lazy as T
import qualified Data.Text.Lazy.IO as T
import qualified Data.Text.Lazy.Read as T
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector as V

main :: IO ()
main = do
  [h, w] <- map unsafeTextToInt . T.words <$> T.getLine :: IO [Int]
  let
    encode :: (Int, Int) -> Int
    encode (i, j) = i * w + j
    decode :: Int -> (Int, Int)
    decode ij = ij `divMod` w
  xs <- VU.fromList . map ('.' ==) . concat . lines <$> getContents :: IO (VU.Vector Bool)
  let
    ls = V.generate (h * w) (f . decode)
      where
        f :: (Int, Int) -> Int
        f ij@(i, j) | not (xs VU.! encode ij) = 0
                    | j == 0                  = 1
                    | otherwise               = ls V.! encode (i, j - 1) + 1
    rs = V.generate (h * w) (f . decode)
      where
        f :: (Int, Int) -> Int
        f ij@(i, j) | not (xs VU.! encode ij) = 0
                    | j == w - 1              = 1
                    | otherwise               = rs V.! encode (i, j + 1) + 1
    us = VU.constructN (h * w) rec
      where
        rec :: VU.Vector Int -> Int
        rec v | not (xs VU.! ij) = 0
              | w <= l           = v VU.! (l - w) + 1
              | otherwise        = 1
          where
            l = VU.length v :: Int
            ij = l :: Int
    ds = VU.constructrN (h * w) rec
      where
        rec :: VU.Vector Int -> Int
        rec v | not (xs VU.! ij) = 0
              | w <= l           = v VU.! (w - 1) + 1
              | otherwise        = 1
          where
            l = VU.length v :: Int
            ij = h * w - l - 1 :: Int
    
    ys = op <$> [0 .. (h - 1)] <*> [0 .. (w - 1)]
      where
        op :: Int -> Int -> Int
        op i j = max 0 . subtract 3 $ ls V.! ij + rs V.! ij + us VU.! ij + ds VU.! ij
          where
            ij = encode (i, j)
  print . maximum $ ys

unsafeTextToInt :: T.Text -> Int
unsafeTextToInt s = case T.signed T.decimal s of
  Right (n, _) -> n
{-# INLINE unsafeTextToInt #-}
