Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Longest Common Subsequence

For given two sequences $X$ and $Y$, a sequence $Z$ is a common subsequence of $X$ and $Y$ if $Z$ is a subsequence of both $X$ and $Y$. For example, if $X = \{a,b,c,b,d,a,b\}$ and $Y = \{b,d,c,a,b,a\}$, the sequence $\{b,c,a\}$ is a common subsequence of both $X$ and $Y$. On the other hand, the sequence $\{b,c,a\}$ is not a longest common subsequence (LCS) of $X$ and $Y$, since it has length 3 and the sequence $\{b,c,b,a\}$, which is also common to both $X$ and $Y$, has length 4. The sequence $\{b,c,b,a\}$ is an LCS of $X$ and $Y$, since there is no common subsequence of length 5 or greater.

Write a program which finds the length of LCS of given two sequences $X$ and $Y$. The sequence consists of alphabetical characters.

Input

The input consists of multiple datasets. In the first line, an integer $q$ which is the number of datasets is given. In the following $2 \times q$ lines, each dataset which consists of the two sequences $X$ and $Y$ are given.

Output

For each dataset, print the length of LCS of $X$ and $Y$ in a line.

Constraints

$1 \leq q \leq 150$

$1 \leq$ length of $X$ and $Y$ $\leq 1,000$

$q \leq 20$ if the dataset includes a sequence whose length is more than 100

Sample Input 1

3
abcbdab
bdcaba
abc
abc
abc
bc

Sample Output 1

4
3
2

Reference

Introduction to Algorithms, Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein. The MIT Press.

Solution in Haskell (judge verdict: Time Limit Exceeded)

{-# LANGUAGE BangPatterns #-}
import Control.Monad
import qualified Data.ByteString.Char8 as B

main :: IO ()
main = do
  n <- readLn
  -- xs <- replicateM (2 * n) getLine :: IO [String]
  -- solve xs

  xs <- replicateM (2 * n) B.getLine :: IO [B.ByteString]
  solveBs xs

solveBs :: [B.ByteString] -> IO ()
solveBs [] = return ()
solveBs (x:y:z) = do
  -- print $ lcs' (B.unpack x) (B.unpack y) []
  print $ lcs'2 (B.unpack x) (B.unpack y)
  solveBs z

solve :: [String] -> IO ()
solve [] = return ()
solve (x:y:z) = do
--  print $ lcs x y 0
  print $ lcs' x y []
  solve z

lcs :: String -> String -> Int -> Int
lcs xs [] v = v
lcs [] ys v = v
lcs (x:xs) (y:ys) v
  | x == y = lcs xs ys (v + 1)
  | otherwise = max (lcs xs (y:ys) v) (lcs (x:xs) ys v)


lcs' :: String -> String -> [Int] -> Int
lcs' !x !y !table
  | i >= m * n = head table
  | x !! j == y !! k = lu `seq` lcs' x y $! lu:table
  | otherwise = let !maxlu = (max l u)
                in lcs' x y $! maxlu:table
  where
    m = length x
    n = length y
    i = length table
    j = mod i m
    k = div i m
    l = if j > 0 then head table else 0
    u = if k > 0 then table !! (m - 1) else 0
    lu = 1 + if j > 0 && k > 0 then table !! m else 0

lcs'2 :: String -> String -> Int
lcs'2 !x !y = lcs x y m n 0 []
  where
    m = length x
    n = length y
    lcs !x !y m n i !table
      | i >= m * n = head table
      | x !! j == y !! k = let !ii = i + 1
                           in lu `seq` lcs x y m n ii $! lu:table
      | otherwise = let !maxlu = (max l u)
                    in let !ii = (i + 1)
                    in lcs x y m n ii $! maxlu:table
        where
          j = mod i m
          k = div i m
          l = if j > 0 then head table else 0
          u = if k > 0 then table !! (m - 1) else 0
          lu = 1 + if j > 0 && k > 0 then table !! m else 0