{-# LANGUAGE ViewPatterns #-}
import qualified Data.Map as M
import qualified Data.ByteString.Char8 as BS

type DP = M.Map (Int,Int) Int

solve :: BS.ByteString -> BS.ByteString -> (Int,Int) -> DP -> DP
solve _ (BS.uncons -> Nothing) _ dp = dp
solve ss (BS.uncons -> Just (t, ts)) point dp =
  loop ss t point dp
  where
    loop :: BS.ByteString -> Char -> (Int,Int) -> DP -> DP
    loop (BS.uncons -> Nothing) _ (y,x) dp = solve ss ts (y+1,1) dp
    loop (BS.uncons -> Just (a, as)) b (y,x) dp
      | a == b = 
        case M.lookup (y-1,x-1) dp of
          Just v -> loop as b (y,x+1) $ M.insert (y,x) (v+1) dp
          Nothing -> loop as b (y,x+1) $ M.insert (y,x) 1 dp
      | otherwise = 
        let f = findFromPair (y-1,x) (y,x-1) dp in loop as b (y,x+1) $ M.insert (y,x) f dp
    
    findFromPair :: (Int,Int) -> (Int,Int) -> DP -> Int
    findFromPair p q dp =
      case [(M.lookup p dp), (M.lookup q dp)] of
        [Nothing, Nothing] -> 0
        [Just v, Nothing] -> v
        [Nothing, Just w] -> w
        [Just v, Just w] -> if v >= w then v else w

main = do
  s <- BS.getLine
  t <- BS.getLine
  let dp = solve s t (1,1) M.empty
  print $ M.deleteFindMax dp