import           Control.Monad
import           Data.Array.ST
import           Data.Array.Unboxed    (UArray)
import qualified Data.Array.Unboxed    as U
import qualified Data.ByteString.Char8 as BS
import           Data.List

getAsCharArray1DWithLength :: IO (Int, UArray Int Char)
getAsCharArray1DWithLength = BS.getLine >>= \cs ->
  let n = BS.length cs
      ary = (U.listArray (1,n) $ unfoldr BS.uncons cs) :: UArray Int Char
  in return (n, ary)

main :: IO ()
main = do
  nsa <- getAsCharArray1DWithLength
  mta <- getAsCharArray1DWithLength
  print $ solve1 nsa mta U.! (fst nsa, fst mta)

solve1 :: (Int, UArray Int Char) -> (Int, UArray Int Char) -> UArray (Int,Int) Int
solve1 (n',sa) (m',ta) = runSTUArray $ do
  dp <- newArray ((0,0),(n',m')) 0
  forM_ [(n_,m_) | n_ <- [1..n'], m_ <- [1..m']] $ \(n,m) -> do
    a <- readArray dp (n-1,m-1)
    b <- readArray dp (n,m-1)
    c <- readArray dp (n-1,m)
    d <- readArray dp (n,m)
    if sa U.! n == ta U.! m
      then writeArray dp (n,m) $ maximum [a+1,b,c,d]
      else writeArray dp (n,m) $ maximum [b,c,d]
  return dp
