import sys

input = sys.stdin.readline

sys.setrecursionlimit(10 ** 7)



import numpy as np

S = np.array(list(input().rstrip()), dtype='U1')

T = np.array(list(input().rstrip()), dtype='U1')



equal = (S[:,None] == T[None,:])



LS = len(S)

LT = len(T)



dp = [np.zeros(LT+1, dtype=np.int16)]



for i in range(LS):

    prev = dp[-1]

    x = prev.copy()

    np.maximum(x[1:], prev[:-1] + equal[i] * 1, out = x[1:])

    np.maximum.accumulate(x, out = x)

    dp.append(x)



x = LS

y = LT

rev_ans = []



while x >= 1 and y >= 1:

    if equal[x-1][y-1]:

        rev_ans.append(str(S[x-1]))

        x -= 1

        y -= 1

        continue

    n1 = dp[x-1][y]

    n2 = dp[x][y-1]

    if n1 < n2:

        y -= 1

        continue

    x -= 1

    continue



answer = ''.join(rev_ans[::-1])



print(answer)
import sys

import numpy as np



read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



S = np.array(list(readline().decode()), 'U1')[:-1]

T = np.array(list(readline().decode()), 'U1')[:-1]



def longest_common_subsequence(S, T):

    """compute table dp satisfying: 

    dp[i,j] = LCS(S[:i], T[:j])"""

    LS, LT = len(S), len(T)

    dp = np.zeros((LS + 1, LT + 1), np.int32)

    for n in range(1, LS + 1):

        dp[n, 1:] = dp[n - 1, :-1] + (S[n - 1] == T)  # 左上から

        np.maximum(dp[n], dp[n - 1], out=dp[n])  # 上から

        np.maximum.accumulate(dp[n], out=dp[n])  # 左から

    return dp



dp = longest_common_subsequence(S, T)



answer = []

i, j = len(S), len(T)

while i > 0 and j > 0:

    if dp[i, j] == dp[i - 1, j - 1] + (S[i - 1] == T[j - 1]):

        i, j = i - 1, j - 1

        if S[i] == T[j]:

            answer.append(S[i])

    elif dp[i, j] == dp[i - 1, j]:

        i -= 1

    elif dp[i, j] == dp[i, j - 1]:

        j -= 1

    else:

        raise ValueError



answer = ''.join(reversed(answer))

print(answer)
import sys

input = sys.stdin.readline
sys.setrecursionlimit(10**7)
import numpy as np

S = np.array(list(input().rstrip()), dtype="U1")
T = np.array(list(input().rstrip()), dtype="U1")
equal = S[:, None] == T[None, :]
LS = len(S)
LT = len(T)
dp = [np.zeros(LT + 1, dtype=np.int16)]
for i in range(LS):
    prev = dp[-1]
    x = prev.copy()
    np.maximum(x[1:], prev[:-1] + equal[i] * 1, out=x[1:])
    np.maximum.accumulate(x, out=x)
    dp.append(x)
x = LS
y = LT
rev_ans = []
while x >= 1 and y >= 1:
    if equal[x - 1][y - 1]:
        rev_ans.append(str(S[x - 1]))
        x -= 1
        y -= 1
        continue
    n1 = dp[x - 1][y]
    n2 = dp[x][y - 1]
    if n1 < n2:
        y -= 1
        continue
    x -= 1
    continue
answer = "".join(rev_ans[::-1])
print(answer)

import sys
import numpy as np

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
S = np.array(list(readline().decode()), "U1")[:-1]
T = np.array(list(readline().decode()), "U1")[:-1]


def longest_common_subsequence(S, T):
    """compute table dp satisfying:
    dp[i,j] = LCS(S[:i], T[:j])"""
    LS, LT = len(S), len(T)
    dp = np.zeros((LS + 1, LT + 1), np.int32)
    for n in range(1, LS + 1):
        dp[n, 1:] = dp[n - 1, :-1] + (S[n - 1] == T)  # 左上から
        np.maximum(dp[n], dp[n - 1], out=dp[n])  # 上から
        np.maximum.accumulate(dp[n], out=dp[n])  # 左から
    return dp


dp = longest_common_subsequence(S, T)
answer = []
i, j = len(S), len(T)
while i > 0 and j > 0:
    if dp[i, j] == dp[i - 1, j - 1] + (S[i - 1] == T[j - 1]):
        i, j = i - 1, j - 1
        if S[i] == T[j]:
            answer.append(S[i])
    elif dp[i, j] == dp[i - 1, j]:
        i -= 1
    elif dp[i, j] == dp[i, j - 1]:
        j -= 1
    else:
        raise ValueError
answer = "".join(reversed(answer))
print(answer)

- -input = sys.stdin.readline -sys.setrecursionlimit(10**7) -S = np.array(list(input().rstrip()), dtype="U1") -T = np.array(list(input().rstrip()), dtype="U1") -equal = S[:, None] == T[None, :] -LS = len(S) -LT = len(T) -dp = [np.zeros(LT + 1, dtype=np.int16)] -for i in range(LS): -    prev = dp[-1] -    x = prev.copy() -    np.maximum(x[1:], prev[:-1] + equal[i] * 1, out=x[1:]) -    np.maximum.accumulate(x, out=x) -    dp.append(x) -x = LS -y = LT -rev_ans = [] -while x >= 1 and y >= 1: -    if equal[x - 1][y - 1]: -        rev_ans.append(str(S[x - 1])) -        x -= 1 -        y -= 1 -        continue -    n1 = dp[x - 1][y] -    n2 = dp[x][y - 1] -    if n1 < n2: -        y -= 1 -        continue -    x -= 1 -    continue -answer = "".join(rev_ans[::-1]) +read = sys.stdin.buffer.read +readline = sys.stdin.buffer.readline +readlines = sys.stdin.buffer.readlines +S = np.array(list(readline().decode()), "U1")[:-1] +T = np.array(list(readline().decode()), "U1")[:-1] + + +def longest_common_subsequence(S, T): +    """compute table dp satisfying: +    dp[i,j] = LCS(S[:i], T[:j])""" +    LS, LT = len(S), len(T) +    dp = np.zeros((LS + 1, LT + 1), np.int32) +    for n in range(1, LS + 1): +        dp[n, 1:] = dp[n - 1, :-1] + (S[n - 1] == T)  # 左上から +        np.maximum(dp[n], dp[n - 1], out=dp[n])  # 上から +        np.maximum.accumulate(dp[n], out=dp[n])  # 左から +    return dp + + +dp = longest_common_subsequence(S, T) +answer = [] +i, j = len(S), len(T) +while i > 0 and j > 0: +    if dp[i, j] == dp[i - 1, j - 1] + (S[i - 1] == T[j - 1]): +        i, j = i - 1, j - 1 +        if S[i] == T[j]: +            answer.append(S[i]) +    elif dp[i, j] == dp[i - 1, j]: +        i -= 1 +    elif dp[i, j] == dp[i, j - 1]: +        j -= 1 +    else: +        raise ValueError +answer = "".join(reversed(answer))