Problem:
 Score : 500 points    Problem Statement Snuke has a string s .
From this string, Anuke, Bnuke, and Cnuke obtained strings a , b , and c , respectively, as follows:   Choose a non-empty (contiguous) substring of s (possibly s itself). Then, replace some characters (possibly all or none) in it with ? s.   For example, if s is mississippi , we can choose the substring ssissip and replace its 1 -st and 3 -rd characters with ? to obtain ?s?ssip .  You are given the strings a , b , and c .
Find the minimum possible length of s .      Constraints  1 \leq |a|, |b|, |c| \leq 2000  a , b , and c consists of lowercase English letters and ? s.         Input Input is given from Standard Input in the following format:  a  b  c       Output Print the minimum possible length of s .        Sample Input 1 a?c
der
cod      Sample Output 1 7  For example, s could be atcoder .       Sample Input 2 atcoder
atcoder
???????      Sample Output 2 7  a , b , and c may not be distinct.

Solution (Python):
def I(): return int(input())
def MI(): return map(int, input().split())
def LI(): return list(map(int, input().split()))


"""
aを固定して，b，cの位置を全探索
"""
def main():
    mod=10**9+7
    a=input()
    b=input()
    c=input()
    M=2100

    
    def ch(c1,c2):
        return c1==c2 or c1=="?" or c2=="?"
    
    
    
    def calc(s1,s2,s3):
        
        
        ab=[1]*(2*M)
        ac=[1]*(2*M)
        bc=[1]*(2*M)
        
        Na=len(s1)
        Nb=len(s2)
        Nc=len(s3)
        
        
        for bi in range(Na+5):
            for j in range(Nb):
                if bi+j>=Na:
                    break
                if not ch(s1[bi+j], s2[j]):
                    ab[bi]=0
                    break
                
        for ci in range(Na+5):
            for j in range(Nc):
                if ci+j>=Na:
                    break
                if not ch(s1[ci+j], s3[j]):
                    ac[ci]=0
                    break
                
        for ci in range(Nb+5):
            for j in range(Nc):
                if ci+j>=Nb:
                    break
                if not ch(s2[ci+j], s3[j]):
                    bc[ci]=0
                    break
                
        ans=10**5
        for i in range(Na+5):
            for j in range(i,Na+Nb+5):
                if ab[i] and ac[j] and bc[j-i]:
                    temp=max(Na,i+Nb,j+Nc)
                    ans=min(ans,temp)
                    
        
        
        
                    
        return ans
    
    ans=len(a)+len(b)+len(c)
    
    ans=min(ans,calc(a,b,c))
    ans=min(ans,calc(a,c,b))
    ans=min(ans,calc(b,a,c))
    ans=min(ans,calc(b,c,a))
    ans=min(ans,calc(c,a,b))
    ans=min(ans,calc(c,b,a))
    
    print(ans)
                
            

main()

Solution (Python):
"""
a = 'a'*2000
b = 'b'*2000
c = 'c'*2000
"""
a = input()
b = input()
c = input()


len_a = len(a)
len_b = len(b)
len_c = len(c)

def match(a, b):
    return a=='?' or b=='?' or a==b

dp_len=50000
ab = [True] * dp_len
ac = [True] * dp_len
bc = [True] * dp_len

def check(a, b, ab):
    for i in range(len(a)):
        for j in range(len(b)):
            if not match(a[i], b[j]):
                ab[i-j+dp_len//2] = False

check(a, b, ab)
check(a, c, ac)
check(b, c, bc)

len_max = 2000

ans = len_a+len_b+len_c
for i in range(-2*len_max, 2*len_max+1):
    for j in range(-2*len_max, 2*len_max+1):
        if ab[i+dp_len//2] and ac[j+dp_len//2] and bc[j-i+dp_len//2]:
            ans = min(ans, max(len_a, len_b+i, len_c+j) - min(0, i, j))
print(ans)

Solution (Python):
from itertools import permutations
ans = 6000
for a, b, c in permutations(input() for _ in range(3)):
    ab, bc, ac = [], [], []
    for s, t, st in [(a, b, ab), (b, c, bc), (a, c, ac)]:
        for i in range(len(s) + 1):
            for si, ti in zip(s[i:], t):
                if si != '?' and ti != '?' and si != ti:
                    st.append(False)
                    break
            else:
                st.append(True)
    for i in range(len(a) + 1):
        for j in range(max(len(b), len(a) - i) + 1):
            if ab[i] and (j > len(b) or bc[j]) and (i+j > len(a) or ac[i+j]):
                ans = min(ans, max(len(a), i+len(b), i+j+len(c)))
print(ans)

Solution (Python):
"""
検証: https://twitter.com/neterukun_cd/status/1283020759942619139
"""
MAX_N = 2000
a = [ord(char) for char in input()]
b = [ord(char) for char in input()]
c = [ord(char) for char in input()]

len_a = len(a)
len_b = len(b)
len_c = len(c)

a += [63] * (MAX_N - len_a + 10)
b += [63] * (MAX_N - len_b + 10)
c += [63] * (MAX_N - len_c + 10)

ab = [True] * (2 * MAX_N + 10)
ba = [True] * (2 * MAX_N + 10)
bc = [True] * (2 * MAX_N + 10)
cb = [True] * (2 * MAX_N + 10)
ca = [True] * (2 * MAX_N + 10)
ac = [True] * (2 * MAX_N + 10)

for length in range(MAX_N + 1):
    for i in range(MAX_N + 1):
        if i + length > MAX_N:
            break

        if a[i + length] != b[i] and a[i + length] != 63 and b[i] != 63:
            ab[length] = False
        if b[i + length] != a[i] and b[i + length] != 63 and a[i] != 63:
            ba[length] = False

        if b[i + length] != c[i] and b[i + length] != 63 and c[i] != 63:
            bc[length] = False
        if c[i + length] != b[i] and c[i + length] != 63 and b[i] != 63:
            cb[length] = False

        if c[i + length] != a[i] and c[i + length] != 63 and a[i] != 63:
            ca[length] = False
        if a[i + length] != c[i] and a[i + length] != 63 and c[i] != 63:
            ac[length] = False

ans = MAX_N * 6
"""

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
"""

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)

print(ans)

Solution (Python):
"""
検証: https://twitter.com/neterukun_cd/status/1283020759942619139
"""
MAX_N = 2000
a = [ord(char) for char in input()]
b = [ord(char) for char in input()]
c = [ord(char) for char in input()]

len_a = len(a)
len_b = len(b)
len_c = len(c)

a += [63] * (MAX_N - len_a + 10)
b += [63] * (MAX_N - len_b + 10)
c += [63] * (MAX_N - len_c + 10)

ab = [True] * (2 * MAX_N + 10)
ba = [True] * (2 * MAX_N + 10)
bc = [True] * (2 * MAX_N + 10)
cb = [True] * (2 * MAX_N + 10)
ca = [True] * (2 * MAX_N + 10)
ac = [True] * (2 * MAX_N + 10)

for length in range(MAX_N + 1):
    for i in range(MAX_N + 1):
        if i + length > MAX_N:
            break

        if a[i + length] != b[i] and a[i + length] != 63 and b[i] != 63:
            ab[length] = False
        if b[i + length] != a[i] and b[i + length] != 63 and a[i] != 63:
            ba[length] = False

        if b[i + length] != c[i] and b[i + length] != 63 and c[i] != 63:
            bc[length] = False
        if c[i + length] != b[i] and c[i + length] != 63 and b[i] != 63:
            cb[length] = False

        if c[i + length] != a[i] and c[i + length] != 63 and a[i] != 63:
            ca[length] = False
        if a[i + length] != c[i] and a[i + length] != 63 and c[i] != 63:
            ac[length] = False

ans = MAX_N * 6
"""

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
"""

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)

print(ans)

Solution (Python):
"""
検証: https://twitter.com/neterukun_cd/status/1283020759942619139
"""
MAX_N = 2000
a = [ord(char) for char in input()]
b = [ord(char) for char in input()]
c = [ord(char) for char in input()]

len_a = len(a)
len_b = len(b)
len_c = len(c)

a += [63] * (MAX_N - len_a + 10)
b += [63] * (MAX_N - len_b + 10)
c += [63] * (MAX_N - len_c + 10)

ab = [True] * (2 * MAX_N + 10)
ba = [True] * (2 * MAX_N + 10)
bc = [True] * (2 * MAX_N + 10)
cb = [True] * (2 * MAX_N + 10)
ca = [True] * (2 * MAX_N + 10)
ac = [True] * (2 * MAX_N + 10)

for length in range(MAX_N + 1):
    for i in range(MAX_N + 1):
        if i + length > MAX_N:
            break

        if a[i + length] != b[i] and a[i + length] != 63 and b[i] != 63:
            ab[length] = False
        if b[i + length] != a[i] and b[i + length] != 63 and a[i] != 63:
            ba[length] = False

        if b[i + length] != c[i] and b[i + length] != 63 and c[i] != 63:
            bc[length] = False
        if c[i + length] != b[i] and c[i + length] != 63 and b[i] != 63:
            cb[length] = False

        if c[i + length] != a[i] and c[i + length] != 63 and a[i] != 63:
            ca[length] = False
        if a[i + length] != c[i] and a[i + length] != 63 and c[i] != 63:
            ac[length] = False

ans = MAX_N * 6
"""

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
"""

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)

print(ans)

Solution (Python):
"""
検証: https://twitter.com/neterukun_cd/status/1283020759942619139
"""
MAX_N = 2000
a = [ord(char) for char in input()]
b = [ord(char) for char in input()]
c = [ord(char) for char in input()]

len_a = len(a)
len_b = len(b)
len_c = len(c)

a += [63] * (MAX_N - len_a + 10)
b += [63] * (MAX_N - len_b + 10)
c += [63] * (MAX_N - len_c + 10)

ab = [True] * (2 * MAX_N + 10)
ba = [True] * (2 * MAX_N + 10)
bc = [True] * (2 * MAX_N + 10)
cb = [True] * (2 * MAX_N + 10)
ca = [True] * (2 * MAX_N + 10)
ac = [True] * (2 * MAX_N + 10)

for length in range(MAX_N + 1):
    for i in range(MAX_N + 1):
        if i + length > MAX_N:
            break

        if a[i + length] != b[i] and a[i + length] != 63 and b[i] != 63:
            ab[length] = False
        if b[i + length] != a[i] and b[i + length] != 63 and a[i] != 63:
            ba[length] = False

        if b[i + length] != c[i] and b[i + length] != 63 and c[i] != 63:
            bc[length] = False
        if c[i + length] != b[i] and c[i + length] != 63 and b[i] != 63:
            cb[length] = False

        if c[i + length] != a[i] and c[i + length] != 63 and a[i] != 63:
            ca[length] = False
        if a[i + length] != c[i] and a[i + length] != 63 and c[i] != 63:
            ac[length] = False

ans = MAX_N * 6
"""

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
"""

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)

        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)

print(ans)

Solution (Python):
MAX_N = 2000
a = [ord(char) for char in input()]
b = [ord(char) for char in input()]
c = [ord(char) for char in input()]


len_a = len(a)
len_b = len(b)
len_c = len(c)

a = a + [63] * (MAX_N - len_a + 10)
b = b + [63] * (MAX_N - len_b + 10)
c = c + [63] * (MAX_N - len_c + 10)

ab = [True] * (2 * MAX_N + 10)
ba = [True] * (2 * MAX_N + 10)
bc = [True] * (2 * MAX_N + 10)
cb = [True] * (2 * MAX_N + 10)
ca = [True] * (2 * MAX_N + 10)
ac = [True] * (2 * MAX_N + 10)


for length in range(MAX_N + 1):
    for i in range(MAX_N + 1):
        if i + length > MAX_N:
            break

        if a[i + length] != b[i] and a[i + length] != 63 and b[i] != 63:
            ab[length] = False
        if b[i + length] != a[i] and b[i + length] != 63 and a[i] != 63:
            ba[length] = False

        if b[i + length] != c[i] and b[i + length] != 63 and c[i] != 63:
            bc[length] = False
        if c[i + length] != b[i] and c[i + length] != 63 and b[i] != 63:
            cb[length] = False

        if c[i + length] != a[i] and c[i + length] != 63 and a[i] != 63:
            ca[length] = False
        if a[i + length] != c[i] and a[i + length] != 63 and c[i] != 63:
            ac[length] = False


ans = MAX_N * 6
for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)

"""
for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)

        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
"""
print(ans)

Solution (Python):
MAX_N = 2000
a = [ord(char) for char in input()]
b = [ord(char) for char in input()]
c = [ord(char) for char in input()]


len_a = len(a)
len_b = len(b)
len_c = len(c)

a = a + [63] * (MAX_N - len_a + 10)
b = b + [63] * (MAX_N - len_b + 10)
c = c + [63] * (MAX_N - len_c + 10)

ab = [True] * (2 * MAX_N + 10)
ba = [True] * (2 * MAX_N + 10)
bc = [True] * (2 * MAX_N + 10)
cb = [True] * (2 * MAX_N + 10)
ca = [True] * (2 * MAX_N + 10)
ac = [True] * (2 * MAX_N + 10)


for length in range(MAX_N + 1):
    for i in range(MAX_N + 1):
        if i + length > MAX_N:
            break

        if a[i + length] != b[i] and a[i + length] != 63 and b[i] != 63:
            ab[length] = False
        if b[i + length] != a[i] and b[i + length] != 63 and a[i] != 63:
            ba[length] = False

        if b[i + length] != c[i] and b[i + length] != 63 and c[i] != 63:
            bc[length] = False
        if c[i + length] != b[i] and c[i + length] != 63 and b[i] != 63:
            cb[length] = False

        if c[i + length] != a[i] and c[i + length] != 63 and a[i] != 63:
            ca[length] = False
        if a[i + length] != c[i] and a[i + length] != 63 and c[i] != 63:
            ac[length] = False


ans = MAX_N * 6
for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ab[len1] and bc[len2] and ac[len1 + len2]:
            tmp = max(len_a, len_b + len1, len_c + len1 + len2)
            ans = min(ans, tmp)
        if ba[len1] and ac[len2] and bc[len1 + len2]:
            tmp = max(len_b, len_a + len1, len_c + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if bc[len1] and ca[len2] and ba[len1 + len2]:
            tmp = max(len_b, len_c + len1, len_a + len1 + len2)
            ans = min(ans, tmp)
        if cb[len1] and ba[len2] and ca[len1 + len2]:
            tmp = max(len_c, len_b + len1, len_a + len1 + len2)
            ans = min(ans, tmp)

for len1 in range(MAX_N + 1):
    for len2 in range(MAX_N + 1):
        if ca[len1] and ab[len2] and cb[len1 + len2]:
            tmp = max(len_c, len_a + len1, len_b + len1 + len2)
            ans = min(ans, tmp)
        if ac[len1] and cb[len2] and ab[len1 + len2]:
            tmp = max(len_a, len_c + len1, len_b + len1 + len2)
            ans = min(ans, tmp)

print(ans)

Solution (Python):
import sys
input = sys.stdin.readline

def calc(s1, s2, s3):
    f12 = [True]*2001
    f23 = [True]*2001
    f13 = [True]*4001
    
    for i in range(2001):
        for j in range(len(s2)):
            if i+j>=len(s1):
                break
            
            if s1[i+j]!='?' and s2[j]!='?' and s1[i+j]!=s2[j]:
                f12[i] = False
                break
    
    for i in range(2001):
        for j in range(len(s3)):
            if i+j>=len(s2):
                break
            
            if s2[i+j]!='?' and s3[j]!='?' and s2[i+j]!=s3[j]:
                f23[i] = False
                break
    
    for i in range(4001):
        for j in range(len(s3)):
            if i+j>=len(s1):
                break
            
            if s1[i+j]!='?' and s3[j]!='?' and s1[i+j]!=s3[j]:
                f13[i] = False
                break
    
    res = 1000000
    
    for i in range(2001):
        for j in range(2001):
            if f12[i] and f23[j] and f13[i+j]:
                res = min(res, max(len(s1), i+len(s2), i+j+len(s3)))
    
    return res

a = input()[:-1]
b = input()[:-1]
c = input()[:-1]
ans = 1000000
ans = min(ans, calc(a, b, c))
ans = min(ans, calc(a, c, b))
ans = min(ans, calc(b, a, c))
ans = min(ans, calc(b, c, a))
ans = min(ans, calc(c, a, b))
ans = min(ans, calc(c, b, a))
print(ans)

Solution (Python):
a = input()
b = input()
c = input()

aa = len(a)
bb = len(b)
cc = len(c)

lensum = aa + bb + cc 
ab = [0]*(lensum+cc+1) 
ac = [0]*(lensum+bb+1)
bc = [0]*(lensum+aa+1)

def match(v,w): 
    if(v != '?' and w != '?' and v != w):
        return 0
    else:
        return 1

def match2(A,B,k): 
    AA = len(A)
    BB = len(B)
    if(k>=AA):
        return 1
    elif(k<-BB):
        return 1
    else:
        flg = 1
        st = max(0,k)
        la = min(AA,BB+k)
        for i in range(st,la):
            if(match(A[i],B[i-k])==0):
                flg = 0
                break
        return flg


for i in range(lensum+cc+1):
    ab[i] = match2(a,b,i-bb-cc)
for i in range(lensum+bb+1):
    ac[i] = match2(a,c,i-bb-cc)
for i in range(lensum+aa+1):
    bc[i] = match2(b,c,i-aa-cc)

def milen(a,b,c):
    minlen = lensum 
    for i in range(-bb-cc,aa+cc+1): 
        for j in range(-bb-cc,aa+bb+1): 
            if(ab[i+bb+cc] == 0): 
                continue
            elif(ac[j+bb+cc] == 0):
                continue
            elif(j-i+aa+cc < 0 or j-i+aa+cc >= lensum+aa+1): 
                continue  
            elif(bc[j-i+aa+cc] == 0):
                continue   
            else:
                sta = min(0,i,j) 
                en = max(aa,i+bb,j+cc) 
                minlen = min(minlen,en-sta) 
    return minlen

print(milen(a,b,c))

Solution (Python):
def main():
  ab=[1]*100000
  bc=[1]*100000
  ac=[1]*100000
  a=input()
  b=input()
  c=input()
  A,B,C=len(a),len(b),len(c)
  match=lambda x,y:x=="?" or y=="?" or x==y
  for i in range(A):
    for j in range(B):
      if not match(a[i],b[j]):ab[i-j+50000]=0
  for i in range(A):
    for j in range(C):
      if not match(a[i],c[j]):ac[i-j+50000]=0
  for i in range(B):
    for j in range(C):
      if not match(b[i],c[j]):bc[i-j+50000]=0
  ans=10**20
  for i in range(-4000,4001):
    for j in range(-4000,4001):
      if ab[i+50000]+ac[j+50000]+bc[j-i+50000]==3:
        ans=min(ans,max(A,B+i,C+j)-min(0,i,j))
  print(ans)
if __name__ == "__main__":
  main()

Solution (Python):
ab=[1]*100000
bc=[1]*100000
ac=[1]*100000
a=input()
b=input()
c=input()
A,B,C=len(a),len(b),len(c)
match=lambda x,y:x=="?" or y=="?" or x==y
for i in range(A):
  for j in range(B):
    if not match(a[i],b[j]):ab[i-j+50000]=0
for i in range(A):
  for j in range(C):
    if not match(a[i],c[j]):ac[i-j+50000]=0
for i in range(B):
  for j in range(C):
    if not match(b[i],c[j]):bc[i-j+50000]=0
ans=10**20
for i in range(-4000,4001):
  for j in range(-4000,4001):
    if ab[i+50000]+ac[j+50000]+bc[j-i+50000]==3:
      ans=min(ans,max(A,B+i,C+j)-min(0,i,j))
print(ans)

Solution (Python):


import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10**9))



a,b,c = [input() for _ in range(3)]
la, lb, lc = len(a), len(b), len(c)

def ok(c1,c2):
    return True if c1==c2 or c1=="?" or c2=="?" else False
def sub(s,t,gap=0):
    
    
    S = set(list(range(-len(s)-gap, -len(s)+1)) + list(range(len(t), len(t)+gap+1)))
    i1 = min(len(s), len(t))
    i2 = max(len(s), len(t))
    i3 = len(s)+len(t)
    for i in range(1,i1+1):
        if all((ok(s[-i+ii], t[ii])) for ii in range(i)):
            S.add(i-len(s))
    for i in range(i1, i2):
        if len(s)<len(t) and all((ok(s[ii], t[ii+i-i1]) for ii in range(i1))):
            S.add(i-len(s))
        elif len(t)<len(s) and all(ok(s[i2-i+ii], t[ii]) for ii in range(i1)):
            S.add(i-len(s))
    for i in range(i2, i3):
        if all((ok(s[ii], t[i-i3+ii]) for ii in range(i3-i))):
            S.add(i-len(s))
    return S

ab = sub(a,b, lc)
bc = sub(c,b, la)
ac = sub(a,c, lb)
ans = 10**9
import itertools
for ii, jj in itertools.product(ab, bc):
    if ii - jj in ac:
        val = max(lb, ii+la, jj+lc) - min(0, ii, jj)
        ans = min(ans, val)
print(ans)

Solution (Python):
a = input()
b = input()
c = input()
 

def match(a, b):
    return a=="?" or b=="?" or a==b
 
ab = [True] * 100000 
ac = [True] * 100000 
bc = [True] * 100000 
 
def check(a, b, ab):
    for i in range(len(a)):
        for j in range(len(b)):
            if not match(a[i], b[j]):
                ab[i-j+50000] = False
 
check(a, b, ab)
check(a, c, ac)
check(b, c, bc)
 
len_max = 2000
len_a = len(a)
len_b = len(b)
len_c = len(c)
 
ans = len_a + len_b + len_c
 

for i in range(-2 * len_max, 2 * len_max + 1):
    
    for j in range(-2 * len_max, 2 * len_max + 1):
        if ab[i+50000] and ac[j+50000] and bc[j-i+50000]:
            ans = min(ans, max(len_a, len_b+i, len_c+j) - min(0, i, j))
 
print(ans)

Solution (Python):
import sys
readline = sys.stdin.readline

A = list(map(lambda x:ord(x)-63, readline().strip()))
B = list(map(lambda x:ord(x)-63, readline().strip()))
C = list(map(lambda x:ord(x)-63, readline().strip()))

LA = len(A)
LB = len(B)
LC = len(C)
geta = 4002

tAB = [True]*(2*geta + 4)
for i in range(-geta//2, geta//2+1):
    for j in range(LB):
        if 0 <= j+i < LA and A[i+j] and B[j] and A[i+j] != B[j]:
            tAB[i] = False
            break

tAC = [True]*(2*geta + 4)
for i in range(-geta//2, geta//2+1):
    for j in range(LC):
        if 0 <= j+i < LA and A[i+j] and C[j] and A[i+j] != C[j]:
            tAC[i] = False
            break


tBC = [True]*(2*geta + 4)
for i in range(-geta, geta+1):
    for j in range(LC):
        if 0 <= j+i < LB and B[i+j] and C[j] and B[i+j] != C[j]:
            tBC[i] = False
            break

ans = 3*geta
for ib in range(-geta, geta+1):
    if tAB[ib]:
        for ic in range(min(0, ib)-LC, 1+max(LA-1, ib+LB-1)):
            if tAC[ic]:
                if -geta <= ic-ib <= geta and not tBC[ic-ib]:
                    continue
                l = min(0, ib, ic)
                r = max(LA-1, ib+LB-1, ic+LC-1)
                ans = min(ans, r-l+1)
print(ans)