{-# LANGUAGE BangPatterns, OverloadedStrings #-}
import Control.Arrow
import Control.Monad.Fix
import Data.Int
import Data.Foldable
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import qualified Data.ByteString.Char8 as B
import Data.ByteString.Internal (accursedUnutterablePerformIO)
import qualified Data.Set as S
import System.IO.Unsafe
import Debug.Trace

unew :: VUM.Unbox a => Int -> VUM.IOVector a
unew !n = accursedUnutterablePerformIO $ VUM.unsafeNew n

uread :: VUM.Unbox a => Int -> VUM.IOVector a -> a
uread !i !v = accursedUnutterablePerformIO $ VUM.unsafeRead v i

uwrite :: VUM.Unbox a => Int -> a -> VUM.IOVector a -> VUM.IOVector a
uwrite !i !a !v =
  accursedUnutterablePerformIO $ VUM.unsafeWrite v i a >> return v

uthaw :: VUM.Unbox a => VU.Vector a -> VUM.IOVector a
uthaw !v = accursedUnutterablePerformIO $ VU.unsafeThaw v

ufreeze :: VUM.Unbox a => VUM.IOVector a -> VU.Vector a
ufreeze !v = accursedUnutterablePerformIO $ VU.unsafeFreeze v

solve :: B.ByteString -> B.ByteString -> String
solve !s !t = walk
 where
  toIndex !i !j = j * succ (B.length s) + i
  fromIndex !n = (n `mod` succ (B.length s), n `div` succ (B.length s))

  dp :: VU.Vector Int16
  dp = ufreeze $ foldl'
    ( \(!dp) (!n) ->
      let (!i, !j) = fromIndex n
      in  uwrite
            n
            ( if i == 0 || j == 0
              then 0
              else
                let dpij  = uread (toIndex (i - 1) (j - 1)) dp
                    dpisj = uread (toIndex i (j - 1)) dp
                    dpsij = uread (toIndex (i - 1) j) dp
                    si    = s `B.index` (i - 1)
                    tj    = t `B.index` (j - 1)
                in  if si == tj then dpij + 1 else max dpisj dpsij
            )
            dp
    )
    (unew $ succ (B.length s) * succ (B.length t))
    [0 .. succ (B.length s) * succ (B.length t) - 1]

  walk = fst $ fix
    ( \(!f) (!acc, (!i, !j)) -> if i == 0 || j == 0
      then (acc, (i, j))
      else if s `B.index` (i - 1) == t `B.index` (j - 1)
        then f (s `B.index` (i - 1) : acc, (i - 1, j - 1))
        else if dp VU.! toIndex (i - 1) j < dp VU.! toIndex i (j - 1)
          then f (acc, (i, j - 1))
          else f (acc, (i - 1, j))
    )
    ([], (B.length s, B.length t))

main = do
  s <- B.getLine
  t <- B.getLine
  putStrLn $ solve s t
