← Home
```go
package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	scanner.Scan()
	s1 := scanner.Text()
	scanner.Scan()
	s2 := scanner.Text()
	scanner.Scan()
	virus := scanner.Text()

	n, m, v := len(s1), len(s2), len(virus)

	lps := make([]int, v)
	for i := 1; i < v; i++ {
		j := lps[i-1]
		for j > 0 && virus[i] != virus[j] {
			j = lps[j-1]
		}
		if virus[i] == virus[j] {
			j++
		}
		lps[i] = j
	}

	aut := make([][]int, v+1)
	for i := range aut {
		aut[i] = make([]int, 26)
	}
	for state := 0; state <= v; state++ {
		for c := 0; c < 26; c++ {
			ch := byte('A' + c)
			if state < v && ch == virus[state] {
				aut[state][c] = state + 1
			} else {
				if state == 0 {
					aut[state][c] = 0
				} else {
					aut[state][c] = aut[lps[state-1]][c]
				}
			}
		}
	}

	const NEG = -1 << 29
	dp := make([][][]int, n+1)
	from := make([][][][3]int, n+1)
	for i := 0; i <= n; i++ {
		dp[i] = make([][]int, m+1)
		from[i] = make([][][3]int, m+1)
		for j := 0; j <= m; j++ {
			dp[i][j] = make([]int, v)
			from[i][j] = make([][3]int, v)
			for k := 0; k < v; k++ {
				dp[i][j][k] = NEG
			}
		}
	}

	dp[0][0][0] = 0

	for i := 0; i <= n; i++ {
		for j := 0; j <= m; j++ {
			for k := 0; k < v; k++ {
				if dp[i][j][k] < 0 {
					continue
				}
				if i < n {
					if dp[i+1][j][k] < dp[i][j][k] {
						dp[i+1][j][k] = dp[i][j][k]
						from[i+1][j][k] = [3]int{i, j, k}
					}
				}
				if j < m {
					if dp[i][j+1][k] < dp[i][j][k] {
						dp[i][j+1][k] = dp[i][j][k]
						from[i][j+1][k] = [3]int{i, j, k}
					}
				}
				if i < n && j < m && s1[i] == s2[j] {
					ch := s1[i]
					nk := aut[k][ch-'A']
					if nk < v {
						if dp[i+1][j+1][nk] < dp[i][j][k]+1 {
							dp[i+1][j+1][nk] = dp[i][j][k] + 1
							from[i+1][j+1][nk] = [3]int{i, j, k}
						}
					}
				}
			}
		}
	}

	bestLen := 0
	bestK := 0
	for k := 0; k < v; k++ {
		if dp[n][m][k] > bestLen {
			bestLen = dp[n][m][k]
			bestK = k
		}
	}

	if bestLen == 0 {
		fmt.Println(0)
		return
	}

	res := make([]byte, 0, bestLen)
	ci, cj, ck := n, m, bestK
	for ci > 0 || cj > 0 {
		pi, pj, pk := from[ci][cj][ck][0], from[ci][cj][ck][1], from[ci][cj][ck][2]
		if pi == ci-1 && pj == cj-1 {
			res = append(res, s1[ci-1])
		}
		ci, cj, ck = pi, pj, pk
	}

	for i, j := 0, len(res)-1; i < j; i, j = i+1, j-1 {
		res[i], res[j] = res[j], res[i]
	}
	fmt.Println(string(res))
}
```