Buggy python submission (verdict: Time Limit Exceeded):
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""
def main():
        
    S = input()
    T = input()

    """
    dp[i+1]][j+1]
    Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
    """
    dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

    prev = {}
    # 部分列の最大長さを求める
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            if s == t:
                #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
                dp[i+1][j+1] = dp[i][j] + 1
                prev[(i+1, j+1)] = (i,j)
            else:
                #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
                prev[(i+1, j+1)] = (i+1,j) if dp[i+1][j] >= dp[i][j+1] else (i,j+1)

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

    substr = ""
    while i != 0 and j != 0:
        if S[i-1] == T[j-1]:
            substr +=S[i-1] 
        i,j = prev[(i,j)]

    print(substr[::-1])

if __name__ == "__main__":
    main()

Fixed submission:
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""
def main():
        
    S = input()
    T = input()

    """
    dp[i+1]][j+1]
    Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
    """
    dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

    #prev = {}
    # 部分列の最大長さを求める
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            if s == t:
                #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
                dp[i+1][j+1] = dp[i][j] + 1
                #prev[(i+1, j+1)] = (i,j)
            else:
                #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
                #prev[(i+1, j+1)] = (i+1,j) if dp[i+1][j] >= dp[i][j+1] else (i,j+1)

    i, j = len(S), len(T)
    """
    なんかi+1,j+1がどのDPノードから更新されてできたのかをたどって、S[i],T[j]が同じであればそれを部分列に加えられるから～みたいな感じで部分列の後ろから作って最後にひっくり返すといいらしい
    
    """

    substr = ""
    while i != 0 and j != 0:
        # 同じ文字で＋１になっていた場合、その文字を部分列に加える
        if S[i-1] == T[j-1]:
            substr += S[i-1]
            i,j = i-1, j-1
        else:
            i,j = (i, j-1) if dp[i][j-1] >= dp[i-1][j] else (i-1, j)


    #TLEなのでやめた
    """
    while i != 0 and j != 0:
        if S[i-1] == T[j-1]:
            substr +=S[i-1] 
        i,j = prev[(i,j)]
    """
    print(substr[::-1])

if __name__ == "__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""
def main():
        
    S = input()
    T = input()

    """
    dp[i+1]][j+1]
    Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
    """
    dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

    prev = {}
    # 部分列の最大長さを求める
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            if s == t:
                #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
                dp[i+1][j+1] = dp[i][j] + 1
                prev[(i+1, j+1)] = (i,j)
            else:
                #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
                prev[(i+1, j+1)] = (i+1,j) if dp[i+1][j] >= dp[i][j+1] else (i,j+1)

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

    substr = ""
    while i != 0 and j != 0:
        if S[i-1] == T[j-1]:
            substr +=S[i-1] 
        i,j = prev[(i,j)]

    print(substr[::-1])

if __name__ == "__main__":
    main()

Fixed submission:
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""
def main():
        
    S = input()
    T = input()

    """
    dp[i+1]][j+1]
    Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
    """
    dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

    #prev = {}
    # 部分列の最大長さを求める
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            if s == t:
                #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
                dp[i+1][j+1] = dp[i][j] + 1
                #prev[(i+1, j+1)] = (i,j)
            else:
                #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
                #prev[(i+1, j+1)] = (i+1,j) if dp[i+1][j] >= dp[i][j+1] else (i,j+1)

    i, j = len(S), len(T)
    """
    なんかi+1,j+1がどのDPノードから更新されてできたのかをたどって、S[i],T[j]が同じであればそれを部分列に加えられるから～みたいな感じで部分列の後ろから作って最後にひっくり返すといいらしい
    
    """

    substr = ""
    while i != 0 and j != 0:
        # 同じ文字で＋１になっていた場合、その文字を部分列に加える
        if S[i-1] == T[j-1]:
            substr += S[i-1]
            i,j = i-1, j-1
        else:
            i,j = (i, j-1) if dp[i][j-1] >= dp[i-1][j] else (i-1, j)


    #TLEなのでやめた
    """
    while i != 0 and j != 0:
        if S[i-1] == T[j-1]:
            substr +=S[i-1] 
        i,j = prev[(i,j)]
    """
    print(substr[::-1])

if __name__ == "__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""
def main():
        
    S = input()
    T = input()

    """
    dp[i+1]][j+1]
    Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
    """
    dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

    next = {}
    prev = {}
    # 部分列の最大長さを求める
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            if s == t:
                #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
                dp[i+1][j+1] = dp[i][j] + 1
                prev[(i+1, j+1)] = (i,j)
            else:
                #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
                if dp[i+1][j] >= dp[i][j+1]:
                    dp[i+1][j+1] = dp[i+1][j]
                    prev[(i+1, j+1)] = (i+1,j)
                else:
                    dp[i+1][j+1] = dp[i][j+1]
                    prev[(i+1, j+1)] = (i,j+1)

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

    substr = ""
    while i != 0 and j != 0:
        if S[i-1] == T[j-1]:
            substr +=S[i-1] 
        i,j = prev[(i,j)]

    print(substr[::-1])

if __name__ == "__main__":
    main()

Fixed submission:
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""
def main():
        
    S = input()
    T = input()

    """
    dp[i+1]][j+1]
    Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
    """
    dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

    #prev = {}
    # 部分列の最大長さを求める
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            if s == t:
                #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
                dp[i+1][j+1] = dp[i][j] + 1
                #prev[(i+1, j+1)] = (i,j)
            else:
                #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
                #prev[(i+1, j+1)] = (i+1,j) if dp[i+1][j] >= dp[i][j+1] else (i,j+1)

    i, j = len(S), len(T)
    """
    なんかi+1,j+1がどのDPノードから更新されてできたのかをたどって、S[i],T[j]が同じであればそれを部分列に加えられるから～みたいな感じで部分列の後ろから作って最後にひっくり返すといいらしい
    
    """

    substr = ""
    while i != 0 and j != 0:
        # 同じ文字で＋１になっていた場合、その文字を部分列に加える
        if S[i-1] == T[j-1]:
            substr += S[i-1]
            i,j = i-1, j-1
        else:
            i,j = (i, j-1) if dp[i][j-1] >= dp[i-1][j] else (i-1, j)


    #TLEなのでやめた
    """
    while i != 0 and j != 0:
        if S[i-1] == T[j-1]:
            substr +=S[i-1] 
        i,j = prev[(i,j)]
    """
    print(substr[::-1])

if __name__ == "__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""

S = input()
T = input()

"""
dp[i+1]][j+1]
Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
"""
dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

next = {}
prev = {}
# 部分列の最大長さを求める
for i, s in enumerate(S):
    for j, t in enumerate(T):
        if s == t:
            #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
            dp[i+1][j+1] = dp[i][j] + 1
            prev[(i+1, j+1)] = (i,j)
        else:
            #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
            if dp[i+1][j] >= dp[i][j+1]:
                dp[i+1][j+1] = dp[i+1][j]
                prev[(i+1, j+1)] = (i+1,j)
            else:
                dp[i+1][j+1] = dp[i][j+1]
                prev[(i+1, j+1)] = (i,j+1)

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

substr = ""
while i != 0 and j != 0:
    if S[i-1] == T[j-1]:
        substr +=S[i-1] 
    i,j = prev[(i,j)]

print(substr[::-1])

Fixed submission:
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""
def main():
        
    S = input()
    T = input()

    """
    dp[i+1]][j+1]
    Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
    """
    dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

    #prev = {}
    # 部分列の最大長さを求める
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            if s == t:
                #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
                dp[i+1][j+1] = dp[i][j] + 1
                #prev[(i+1, j+1)] = (i,j)
            else:
                #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
                #prev[(i+1, j+1)] = (i+1,j) if dp[i+1][j] >= dp[i][j+1] else (i,j+1)

    i, j = len(S), len(T)
    """
    なんかi+1,j+1がどのDPノードから更新されてできたのかをたどって、S[i],T[j]が同じであればそれを部分列に加えられるから～みたいな感じで部分列の後ろから作って最後にひっくり返すといいらしい
    
    """

    substr = ""
    while i != 0 and j != 0:
        # 同じ文字で＋１になっていた場合、その文字を部分列に加える
        if S[i-1] == T[j-1]:
            substr += S[i-1]
            i,j = i-1, j-1
        else:
            i,j = (i, j-1) if dp[i][j-1] >= dp[i-1][j] else (i-1, j)


    #TLEなのでやめた
    """
    while i != 0 and j != 0:
        if S[i-1] == T[j-1]:
            substr +=S[i-1] 
        i,j = prev[(i,j)]
    """
    print(substr[::-1])

if __name__ == "__main__":
    main()

Buggy python submission (verdict: Time Limit Exceeded):
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""

S = input()
T = input()

"""
dp[i+1]][j+1]
Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
"""
dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

next = {}
prev = {}
# 部分列の最大長さを求める
for i, s in enumerate(S):
    for j, t in enumerate(T):
        if s == t:
            #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
            dp[i+1][j+1] = dp[i][j] + 1
            prev[(i+1, j+1)] = (i,j)
        else:
            #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
            if dp[i+1][j] >= dp[i][j+1]:
                dp[i+1][j+1] = dp[i+1][j]
                prev[(i+1, j+1)] = (i+1,j)
            else:
                dp[i+1][j+1] = dp[i][j+1]
                prev[(i+1, j+1)] = (i,j+1)

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

substr = ""
while i != 0 and j != 0:
    if S[i-1] == T[j-1]:
        substr +=S[i-1] 
    i,j = prev[(i,j)]

print(substr[::-1])

Fixed submission:
"""
https://qiita.com/drken/items/03c7db44ccd27820ea0d


"""
def main():
        
    S = input()
    T = input()

    """
    dp[i+1]][j+1]
    Sのi番目とtのｊ番目まで見たときの共通する部分列の最大長さ
    """
    dp = [[0 for _ in range(len(T)+1)] for _ in range(len(S)+1)]

    #prev = {}
    # 部分列の最大長さを求める
    for i, s in enumerate(S):
        for j, t in enumerate(T):
            if s == t:
                #i番目とｊ番目が同じなら、dp[i+1][j+1]はそれまでの最大長さ＋１
                dp[i+1][j+1] = dp[i][j] + 1
                #prev[(i+1, j+1)] = (i,j)
            else:
                #異なる場合はdp[i][j]かd[i+1][j]かdp[i][j+1]のどれかだけども、後者ふたつがi,jより小さいことはないから後ろ二つの大きいほうを採用
                dp[i+1][j+1] = max(dp[i+1][j], dp[i][j+1])
                #prev[(i+1, j+1)] = (i+1,j) if dp[i+1][j] >= dp[i][j+1] else (i,j+1)

    i, j = len(S), len(T)
    """
    なんかi+1,j+1がどのDPノードから更新されてできたのかをたどって、S[i],T[j]が同じであればそれを部分列に加えられるから～みたいな感じで部分列の後ろから作って最後にひっくり返すといいらしい
    
    """

    substr = ""
    while i != 0 and j != 0:
        # 同じ文字で＋１になっていた場合、その文字を部分列に加える
        if S[i-1] == T[j-1]:
            substr += S[i-1]
            i,j = i-1, j-1
        else:
            i,j = (i, j-1) if dp[i][j-1] >= dp[i-1][j] else (i-1, j)


    #TLEなのでやめた
    """
    while i != 0 and j != 0:
        if S[i-1] == T[j-1]:
            substr +=S[i-1] 
        i,j = prev[(i,j)]
    """
    print(substr[::-1])

if __name__ == "__main__":
    main()