Buggy python submission (verdict: Time Limit Exceeded):
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))

#################

a = list(input())
b = list(input())
c = list(input())

def concat1(x,y,len_only=False):
    n = len(x)
    m = len(y)
    ret = [x+y]
    for i in range(n):
        con_flag = False
        d = {}
        for j in range(i,min(i+m,n)):
            if x[j] == '?' and y[j-i] != '?':
                d[j] = y[j-i]
            elif x[j] != y[j-i] and x[j] != '?' and y[j-i] != '?':
                con_flag = True
                break
            else:
                continue
        if con_flag:
            continue
        else:
            if len_only:
                if n-i <= m-1:
                    return m+i
                else:
                    return n
            else:
                if n-i <= m-1:
                    now = x+y[n-i:]
                    for k,v in d.items():
                        now[k] = v
                else:
                    now = x[:]
                    for k,v in d.items():
                        now[k] = v
                ret.append(now)

    if len_only:
        return n+m
    else:
        return ret

def concat2(xlist,y):
    ans = float('inf')
    for x in xlist:
        now = concat1(x,y,len_only=True)
        min_ = now
        if min_ < ans:
            ans = min_
    return ans


ret1 = concat2(concat1(a,b),c)
ret2 = concat2(concat1(a,c),b)
ret3 = concat2(concat1(b,a),c)
ret4 = concat2(concat1(b,c),a)
ret5 = concat2(concat1(c,a),b)
ret6 = concat2(concat1(c,b),a)

print(min(ret1,ret2,ret3,ret4,ret5,ret6))

Fixed submission:
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))

#################

a = list(input())
b = list(input())
c = list(input())

def is_match(c1,c2):
    if c1 == '?' or c2 == '?' or c1 == c2:
        return True
    else:
        return False

def prefix_match_len(x,y):
    len_list = []
    n = len(x)
    m = len(y)
    for i in range(n):
        match = 0
        for j in range(i,min(i+m,n)):
            if is_match(x[j],y[j-i]):
                match += 1
            else:
                break
        len_list.append(match)
    return len_list

def concat(x,y,xy):
    index_list = []
    n = len(x)
    m = len(y)
    for i in range(n):
        if xy[i] == min(n-i,m):
            index_list.append(i)
    index_list.append(n)
    return index_list

def concat2(x,y,z,xz,yz,zy,index_list):
    n1 = len(x)
    n2 = len(y)
    m = len(z)
    candidate = []
    for i in index_list:
        flag = False
        for j in range(max(n1,n2+i)):
            if j <= n1-1:
                if xz[j] != min(n1-j,m):
                    continue
            if j >= i:
                if n2-j+i >= 1 and yz[j-i] != min(n2-j+i,m):
                    continue
            else:
                if m-i+j >= 1 and zy[i-j] != min(m-i+j,n2):
                    continue
            flag = True
            candidate.append(max(n1,n2+i,j+m))
            break
        if not flag:
            candidate.append(max(n1,n2+i)+m)
    return min(candidate)

ab = prefix_match_len(a,b)
ac = prefix_match_len(a,c)
ba = prefix_match_len(b,a)
bc = prefix_match_len(b,c)
ca = prefix_match_len(c,a)
cb = prefix_match_len(c,b)

index_list = concat(a,b,ab)
ret1 = concat2(a,b,c,ac,bc,cb,index_list)
index_list = concat(a,c,ac)
ret2 = concat2(a,c,b,ab,cb,bc,index_list)
index_list = concat(b,a,ba)
ret3 = concat2(b,a,c,bc,ac,ca,index_list)
index_list = concat(b,c,bc)
ret4 = concat2(b,c,a,ba,ca,ac,index_list)
index_list = concat(c,a,ca)
ret5 = concat2(c,a,b,cb,ab,ba,index_list)
index_list = concat(c,b,cb)
ret6 = concat2(c,b,a,ca,ba,ab,index_list)

print(min(ret1,ret2,ret3,ret4,ret5,ret6))

Buggy python submission (verdict: Time Limit Exceeded):
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))

#################

a = list(input())
b = list(input())
c = list(input())

def concat1(x,y,len_only=False):
    n = len(x)
    m = len(y)
    if len_only:
        ret = [n+m]
    else:
        ret = [x+y]
    for i in range(n):
        con_flag = False
        d = {}
        for j in range(i,min(i+m,n)):
            if x[j] == '?' and y[j-i] != '?':
                d[j] = y[j-i]
            elif x[j] != y[j-i] and x[j] != '?' and y[j-i] != '?':
                con_flag = True
                break
            else:
                continue
        if con_flag:
            continue
        else:
            if len_only:
                if n-i <= m-1:
                    ret.append(m+i)
                else:
                    ret.append(n)
            else:
                if n-i <= m-1:
                    now = x+y[n-i:]
                    for k,v in d.items():
                        now[k] = v
                else:
                    now = x
                    for k,v in d.items():
                        now[k] = v
                ret.append(now)

    return ret

def concat2(xlist,y):
    ans = float('inf')
    for x in xlist:
        now = concat1(x,y,len_only=True)
        min_ = min(now)
        if min_ < ans:
            ans = min_
    return ans


ret1 = concat2(concat1(a,b),c)
ret2 = concat2(concat1(a,c),b)
ret3 = concat2(concat1(b,a),c)
ret4 = concat2(concat1(b,c),a)
ret5 = concat2(concat1(c,a),b)
ret6 = concat2(concat1(c,b),a)

print(min(ret1,ret2,ret3,ret4,ret5,ret6))

Fixed submission:
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))

#################

a = list(input())
b = list(input())
c = list(input())

def is_match(c1,c2):
    if c1 == '?' or c2 == '?' or c1 == c2:
        return True
    else:
        return False

def prefix_match_len(x,y):
    len_list = []
    n = len(x)
    m = len(y)
    for i in range(n):
        match = 0
        for j in range(i,min(i+m,n)):
            if is_match(x[j],y[j-i]):
                match += 1
            else:
                break
        len_list.append(match)
    return len_list

def concat(x,y,xy):
    index_list = []
    n = len(x)
    m = len(y)
    for i in range(n):
        if xy[i] == min(n-i,m):
            index_list.append(i)
    index_list.append(n)
    return index_list

def concat2(x,y,z,xz,yz,zy,index_list):
    n1 = len(x)
    n2 = len(y)
    m = len(z)
    candidate = []
    for i in index_list:
        flag = False
        for j in range(max(n1,n2+i)):
            if j <= n1-1:
                if xz[j] != min(n1-j,m):
                    continue
            if j >= i:
                if n2-j+i >= 1 and yz[j-i] != min(n2-j+i,m):
                    continue
            else:
                if m-i+j >= 1 and zy[i-j] != min(m-i+j,n2):
                    continue
            flag = True
            candidate.append(max(n1,n2+i,j+m))
            break
        if not flag:
            candidate.append(max(n1,n2+i)+m)
    return min(candidate)

ab = prefix_match_len(a,b)
ac = prefix_match_len(a,c)
ba = prefix_match_len(b,a)
bc = prefix_match_len(b,c)
ca = prefix_match_len(c,a)
cb = prefix_match_len(c,b)

index_list = concat(a,b,ab)
ret1 = concat2(a,b,c,ac,bc,cb,index_list)
index_list = concat(a,c,ac)
ret2 = concat2(a,c,b,ab,cb,bc,index_list)
index_list = concat(b,a,ba)
ret3 = concat2(b,a,c,bc,ac,ca,index_list)
index_list = concat(b,c,bc)
ret4 = concat2(b,c,a,ba,ca,ac,index_list)
index_list = concat(c,a,ca)
ret5 = concat2(c,a,b,cb,ab,ba,index_list)
index_list = concat(c,b,cb)
ret6 = concat2(c,b,a,ca,ba,ab,index_list)

print(min(ret1,ret2,ret3,ret4,ret5,ret6))

Buggy python submission (verdict: Time Limit Exceeded):
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))

#################

a = list(input())
b = list(input())
c = list(input())

def concat1(x,y,len_only=False):
    ret = []
    n = len(x)
    m = len(y)
    for i in range(n):
        con_flag = False
        d = {}
        for j in range(i,min(i+m,n)):
            if x[j] == '?' and y[j-i] != '?':
                d[j] = y[j-i]
            elif x[j] != y[j-i] and x[j] != '?' and y[j-i] != '?':
                con_flag = True
                break
            else:
                continue
        if con_flag:
            continue
        else:
            if n-i <= m-1:
                now = x+y[n-i:]
                for k,v in d.items():
                    now[k] = v
            else:
                now = x
                for k,v in d.items():
                    now[k] = v
            if len_only:
                ret.append(len(now))
            else:
                ret.append(now)
    if len_only:
        ret.append(n+m)
    else:
        ret.append(x+y)               
    return ret

def concat2(xlist,y):
    ans = float('inf')
    for x in xlist:
        now = concat1(x,y,len_only=True)
        min_ = min(now)
        if min_ < ans:
            ans = min_
    return ans


ret1 = concat2(concat1(a,b),c)
ret2 = concat2(concat1(a,c),b)
ret3 = concat2(concat1(b,a),c)
ret4 = concat2(concat1(b,c),a)
ret5 = concat2(concat1(c,a),b)
ret6 = concat2(concat1(c,b),a)

print(min(ret1,ret2,ret3,ret4,ret5,ret6))

Fixed submission:
import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right

sys.setrecursionlimit(10**7)
def input():
    return sys.stdin.readline()[:-1]

mod = 10**9 + 7

def I(): return int(input())
def LI(): return list(map(int, input().split()))
def LIR(row,col):
    if row <= 0:
        return [[] for _ in range(col)]
    elif col == 1:
        return [I() for _ in range(row)]
    else:
        read_all = [LI() for _ in range(row)]
        return map(list, zip(*read_all))

#################

a = list(input())
b = list(input())
c = list(input())

def is_match(c1,c2):
    if c1 == '?' or c2 == '?' or c1 == c2:
        return True
    else:
        return False

def prefix_match_len(x,y):
    len_list = []
    n = len(x)
    m = len(y)
    for i in range(n):
        match = 0
        for j in range(i,min(i+m,n)):
            if is_match(x[j],y[j-i]):
                match += 1
            else:
                break
        len_list.append(match)
    return len_list

def concat(x,y,xy):
    index_list = []
    n = len(x)
    m = len(y)
    for i in range(n):
        if xy[i] == min(n-i,m):
            index_list.append(i)
    index_list.append(n)
    return index_list

def concat2(x,y,z,xz,yz,zy,index_list):
    n1 = len(x)
    n2 = len(y)
    m = len(z)
    candidate = []
    for i in index_list:
        flag = False
        for j in range(max(n1,n2+i)):
            if j <= n1-1:
                if xz[j] != min(n1-j,m):
                    continue
            if j >= i:
                if n2-j+i >= 1 and yz[j-i] != min(n2-j+i,m):
                    continue
            else:
                if m-i+j >= 1 and zy[i-j] != min(m-i+j,n2):
                    continue
            flag = True
            candidate.append(max(n1,n2+i,j+m))
            break
        if not flag:
            candidate.append(max(n1,n2+i)+m)
    return min(candidate)

ab = prefix_match_len(a,b)
ac = prefix_match_len(a,c)
ba = prefix_match_len(b,a)
bc = prefix_match_len(b,c)
ca = prefix_match_len(c,a)
cb = prefix_match_len(c,b)

index_list = concat(a,b,ab)
ret1 = concat2(a,b,c,ac,bc,cb,index_list)
index_list = concat(a,c,ac)
ret2 = concat2(a,c,b,ab,cb,bc,index_list)
index_list = concat(b,a,ba)
ret3 = concat2(b,a,c,bc,ac,ca,index_list)
index_list = concat(b,c,bc)
ret4 = concat2(b,c,a,ba,ca,ac,index_list)
index_list = concat(c,a,ca)
ret5 = concat2(c,a,b,cb,ab,ba,index_list)
index_list = concat(c,b,cb)
ret6 = concat2(c,b,a,ca,ba,ab,index_list)

print(min(ret1,ret2,ret3,ret4,ret5,ret6))