Buggy python submission (verdict: Time Limit Exceeded):
# https://atcoder.jp/contests/panasonic2020/submissions/10891808
# generatorを使うところ

def solve_panasonic2020_e():
    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    def matching_list(P: str, Q: str, MX: int = MX) -> list:
        """相対位置ごとの文字列マッチングの可否を調べる
        ret[index差]:=その相対位置でマッチしないときTrue
        [-MX,MX]
        + : 左文字より右文字が右にある, P->Q
        - : 右文字より左文字が右にある, Q->P"""

        def unmatched(c1: str, c2: str) -> bool:
            """c1,c2がマッチしない"""
            return not (c1 == '?' or c2 == '?' or c1 == c2)

        ret = [False] * (MX * 4 + 1)
        for i, p in enumerate(P):
            for j, q in enumerate(Q):
                ret[i - j] |= unmatched(p, q)
        return ret

    ab = matching_list(A, B)
    ac = matching_list(A, C)
    bc = matching_list(B, C)

    def candidates(MX: int = MX) -> int:
        """Aに対するB,Cの相対位置MX**2で全探索し
        文字列長の候補を返すgenerator"""
        for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
            if ab[i]: continue
            for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
                if ac[j]: continue
                if bc[j - i]: continue
                # 添え字で混乱するが
                # ab[i-j]で
                # 添え字i-jは(bの開始)-(aの開始)を意味したことから
                # (i-j>0でa->bの配置から)
                # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
                # bcの添え字は(cの開始)-(bの開始)なのでj-i

                # [L,R)
                L = min(0, i, j)
                R = max(len(A), i + len(B), j + len(C))
                yield R - L

    ans = min(candidates())
    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査


Fixed submission:
# 解説の写経

def solve_panasonic2020_e():
    def unmatched(c1: str, c2: str) -> bool:
        """c1,c2がマッチしない"""
        return not (c1 == '?' or c2 == '?' or c1 == c2)

    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    # 相対位置ごとの文字列マッチングの可否を調べる
    # ab/ac/bc[index差]:=その相対位置でマッチしないときTrue
    # [-MX,MX]
    # + : 左文字より右文字が右にある, a->b
    # - : 右文字より左文字が右にある, b->a
    ab = [False] * (MX * 4 + 1)
    ac = [False] * (MX * 4 + 1)
    bc = [False] * (MX * 4 + 1)

    for i, a in enumerate(A):
        for j, b in enumerate(B):
            ab[i - j] |= unmatched(a, b)

    for i, a in enumerate(A):
        for j, c in enumerate(C):
            ac[i - j] |= unmatched(a, c)

    for i, b in enumerate(B):
        for j, c in enumerate(C):
            bc[i - j] |= unmatched(b, c)

    # Aに対するB,Cの相対位置MX**2で全探索
    ans = sum(map(len, [A, B, C]))
    for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
        if ab[i]: continue
        for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
            if ac[j]: continue
            if bc[j - i]: continue
            # 添え字で混乱するが
            # ab[i-j]で
            # 添え字i-jは(bの開始)-(aの開始)を意味したことから
            # (i-j>0でa->bの配置から)
            # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
            # bcの添え字は(cの開始)-(bの開始)なのでj-i

            # [L,R)
            L = min(0, i, j)
            R = max(len(A), i + len(B), j + len(C))
            ans = min(ans, R - L)

    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査

Buggy python submission (verdict: Time Limit Exceeded):
# https://atcoder.jp/contests/panasonic2020/submissions/10891808
# generatorを使うところ

def solve_panasonic2020_e():
    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    def matching_list(P: str, Q: str) -> list:
        """相対位置ごとの文字列マッチングの可否を調べる
        ret[index差]:=その相対位置でマッチしないときTrue
        [-MX,MX]
        + : 左文字より右文字が右にある, P->Q
        - : 右文字より左文字が右にある, Q->P"""

        def unmatched(c1: str, c2: str) -> bool:
            """c1,c2がマッチしない"""
            return not (c1 == '?' or c2 == '?' or c1 == c2)

        ret = [False] * (MX * 4 + 1)
        for i, p in enumerate(P):
            for j, q in enumerate(Q):
                ret[i - j] |= unmatched(p, q)
        return ret

    ab = matching_list(A, B)
    ac = matching_list(A, C)
    bc = matching_list(B, C)

    def candidates() -> int:
        """Aに対するB,Cの相対位置MX**2で全探索し
        文字列長の候補を返すgenerator"""
        for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
            if ab[i]: continue
            for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
                if ac[j]: continue
                if bc[j - i]: continue
                # 添え字で混乱するが
                # ab[i-j]で
                # 添え字i-jは(bの開始)-(aの開始)を意味したことから
                # (i-j>0でa->bの配置から)
                # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
                # bcの添え字は(cの開始)-(bの開始)なのでj-i

                # [L,R)
                L = min(0, i, j)
                R = max(len(A), i + len(B), j + len(C))
                yield R - L

    ans = min(candidates())
    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査


Fixed submission:
# 解説の写経

def solve_panasonic2020_e():
    def unmatched(c1: str, c2: str) -> bool:
        """c1,c2がマッチしない"""
        return not (c1 == '?' or c2 == '?' or c1 == c2)

    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    # 相対位置ごとの文字列マッチングの可否を調べる
    # ab/ac/bc[index差]:=その相対位置でマッチしないときTrue
    # [-MX,MX]
    # + : 左文字より右文字が右にある, a->b
    # - : 右文字より左文字が右にある, b->a
    ab = [False] * (MX * 4 + 1)
    ac = [False] * (MX * 4 + 1)
    bc = [False] * (MX * 4 + 1)

    for i, a in enumerate(A):
        for j, b in enumerate(B):
            ab[i - j] |= unmatched(a, b)

    for i, a in enumerate(A):
        for j, c in enumerate(C):
            ac[i - j] |= unmatched(a, c)

    for i, b in enumerate(B):
        for j, c in enumerate(C):
            bc[i - j] |= unmatched(b, c)

    # Aに対するB,Cの相対位置MX**2で全探索
    ans = sum(map(len, [A, B, C]))
    for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
        if ab[i]: continue
        for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
            if ac[j]: continue
            if bc[j - i]: continue
            # 添え字で混乱するが
            # ab[i-j]で
            # 添え字i-jは(bの開始)-(aの開始)を意味したことから
            # (i-j>0でa->bの配置から)
            # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
            # bcの添え字は(cの開始)-(bの開始)なのでj-i

            # [L,R)
            L = min(0, i, j)
            R = max(len(A), i + len(B), j + len(C))
            ans = min(ans, R - L)

    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査

Buggy python submission (verdict: Time Limit Exceeded):
# 解説の写経

def solve_panasonic2020_e():
    def unmatched(c1: str, c2: str) -> bool:
        """c1,c2がマッチしない"""
        return not (c1 == '?' or c2 == '?' or c1 == c2)

    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    # 相対位置ごとの文字列マッチングの可否を調べる
    # ab/ac/bc[index差]:=その相対位置でマッチしないときTrue
    # [-MX,MX]
    # + : 左文字より右文字が右にある, a->b
    # - : 右文字より左文字が右にある, b->a
    ab = [False] * (MX * 4 + 1)
    ac = [False] * (MX * 4 + 1)
    bc = [False] * (MX * 4 + 1)

    for i, a in enumerate(A):
        for j, b in enumerate(B):
            ab[i - j] |= unmatched(a, b)

    for i, a in enumerate(A):
        for j, c in enumerate(C):
            ac[i - j] |= unmatched(a, c)

    for i, b in enumerate(B):
        for j, c in enumerate(C):
            bc[i - j] |= unmatched(b, c)

    # Aに対するB,Cの相対位置MX**2で全探索
    ans = sum(map(len, [A, B, C]))
    for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
        if ab[i]: continue
        for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
            if ac[j]: continue
            if bc[j - i]: continue
            # 添え字で混乱するが
            # ab[i-j]で
            # 添え字i-jは(bの開始)-(aの開始)を意味したことから
            # (i-j>0でa->bの配置から)
            # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
            # bcの添え字は(cの開始)-(bの開始)なのでj-i

            # [L,R)
            L = min(0, i, j)
            R = max(len(A), i + len(B), j + len(C))
            ans = min(ans, R - L)

    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査


Fixed submission:
# 解説の写経

def solve_panasonic2020_e():
    def unmatched(c1: str, c2: str) -> bool:
        """c1,c2がマッチしない"""
        return not (c1 == '?' or c2 == '?' or c1 == c2)

    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    # 相対位置ごとの文字列マッチングの可否を調べる
    # ab/ac/bc[index差]:=その相対位置でマッチしないときTrue
    # [-MX,MX]
    # + : 左文字より右文字が右にある, a->b
    # - : 右文字より左文字が右にある, b->a
    ab = [False] * (MX * 4 + 1)
    ac = [False] * (MX * 4 + 1)
    bc = [False] * (MX * 4 + 1)

    for i, a in enumerate(A):
        for j, b in enumerate(B):
            ab[i - j] |= unmatched(a, b)

    for i, a in enumerate(A):
        for j, c in enumerate(C):
            ac[i - j] |= unmatched(a, c)

    for i, b in enumerate(B):
        for j, c in enumerate(C):
            bc[i - j] |= unmatched(b, c)

    # Aに対するB,Cの相対位置MX**2で全探索
    ans = sum(map(len, [A, B, C]))
    for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
        if ab[i]: continue
        for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
            if ac[j]: continue
            if bc[j - i]: continue
            # 添え字で混乱するが
            # ab[i-j]で
            # 添え字i-jは(bの開始)-(aの開始)を意味したことから
            # (i-j>0でa->bの配置から)
            # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
            # bcの添え字は(cの開始)-(bの開始)なのでj-i

            # [L,R)
            L = min(0, i, j)
            R = max(len(A), i + len(B), j + len(C))
            ans = min(ans, R - L)

    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査

Buggy python submission (verdict: Time Limit Exceeded):
def solve_panasonic2020_e():
    from itertools import islice, permutations, zip_longest

    def cv2num(c):
        return -1 if c == '?' else ord(c)

    *a, = map(cv2num, input())
    *b, = map(cv2num, input())
    *c, = map(cv2num, input())

    abc = a, b, c

    ret = sum(map(len, abc))
    for perm in permutations(abc):
        first, second, third = perm

        cands = [first + second]
        for i in range(len(first)):
            # first[i:]とsecondが一致するか見る
            # 一致なら候補に残す
            # すべてダメならfirst+secondだけ候補になる(重なりなし)
            cand = []
            for fc, sc in zip_longest(islice(first, i, len(first)), second, fillvalue=0):
                if not (fc and sc):
                    cand.append(fc + sc)
                elif fc == sc or sc == -1:
                    cand.append(fc)
                elif fc == -1:
                    cand.append(sc)
                else:
                    break
            else:
                cand = first[:i] + cand
                cands.append(cand)

        for cand in cands:
            for i in range(len(cand)):
                t = i
                for cc, tc in zip_longest(islice(cand, i, len(cand)), third, fillvalue=0):
                    t += 1
                    if not (cc and tc):
                        continue
                    if not (cc == tc or cc == -1 or tc == -1):
                        break

                else:
                    ret = min(ret, t)

    print(ret)


if __name__ == '__main__':
    solve_panasonic2020_e()


Fixed submission:
# 解説の写経

def solve_panasonic2020_e():
    def unmatched(c1: str, c2: str) -> bool:
        """c1,c2がマッチしない"""
        return not (c1 == '?' or c2 == '?' or c1 == c2)

    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    # 相対位置ごとの文字列マッチングの可否を調べる
    # ab/ac/bc[index差]:=その相対位置でマッチしないときTrue
    # [-MX,MX]
    # + : 左文字より右文字が右にある, a->b
    # - : 右文字より左文字が右にある, b->a
    ab = [False] * (MX * 4 + 1)
    ac = [False] * (MX * 4 + 1)
    bc = [False] * (MX * 4 + 1)

    for i, a in enumerate(A):
        for j, b in enumerate(B):
            ab[i - j] |= unmatched(a, b)

    for i, a in enumerate(A):
        for j, c in enumerate(C):
            ac[i - j] |= unmatched(a, c)

    for i, b in enumerate(B):
        for j, c in enumerate(C):
            bc[i - j] |= unmatched(b, c)

    # Aに対するB,Cの相対位置MX**2で全探索
    ans = sum(map(len, [A, B, C]))
    for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
        if ab[i]: continue
        for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
            if ac[j]: continue
            if bc[j - i]: continue
            # 添え字で混乱するが
            # ab[i-j]で
            # 添え字i-jは(bの開始)-(aの開始)を意味したことから
            # (i-j>0でa->bの配置から)
            # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
            # bcの添え字は(cの開始)-(bの開始)なのでj-i

            # [L,R)
            L = min(0, i, j)
            R = max(len(A), i + len(B), j + len(C))
            ans = min(ans, R - L)

    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査

Buggy python submission (verdict: Time Limit Exceeded):
def solve_panasonic2020_e():
    from itertools import islice, permutations, zip_longest

    abc = tuple(input() for _ in range(3))

    ret = sum(map(len, abc))
    for perm in permutations(abc):
        first, second, third = perm

        cands = [first + second]
        for i in range(len(first)):
            # first[i:]とsecondが一致するか見る
            # 一致なら候補に残す
            # すべてダメならfirst+secondだけ候補になる(重なりなし)
            cand = ''
            for fc, sc in zip_longest(islice(first, i, len(first)), second, fillvalue=''):
                if not fc or not sc:
                    cand += fc + sc
                elif fc == sc or sc == '?':
                    cand += fc
                elif fc == '?':
                    cand += sc
                else:
                    break
            else:
                cand = first[:i] + cand
                cands.append(cand)

        for cand in cands:
            for i in range(len(cand)):
                t = i
                for cc, tc in zip_longest(islice(cand, i, len(cand)), third, fillvalue=''):
                    t += 1
                    if not cc or not tc:
                        continue
                    if not (cc == tc or cc == '?' or tc == '?'):
                        break

                else:
                    ret = min(ret, t)

    print(ret)


if __name__ == '__main__':
    solve_panasonic2020_e()


Fixed submission:
# 解説の写経

def solve_panasonic2020_e():
    def unmatched(c1: str, c2: str) -> bool:
        """c1,c2がマッチしない"""
        return not (c1 == '?' or c2 == '?' or c1 == c2)

    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    # 相対位置ごとの文字列マッチングの可否を調べる
    # ab/ac/bc[index差]:=その相対位置でマッチしないときTrue
    # [-MX,MX]
    # + : 左文字より右文字が右にある, a->b
    # - : 右文字より左文字が右にある, b->a
    ab = [False] * (MX * 4 + 1)
    ac = [False] * (MX * 4 + 1)
    bc = [False] * (MX * 4 + 1)

    for i, a in enumerate(A):
        for j, b in enumerate(B):
            ab[i - j] |= unmatched(a, b)

    for i, a in enumerate(A):
        for j, c in enumerate(C):
            ac[i - j] |= unmatched(a, c)

    for i, b in enumerate(B):
        for j, c in enumerate(C):
            bc[i - j] |= unmatched(b, c)

    # Aに対するB,Cの相対位置MX**2で全探索
    ans = sum(map(len, [A, B, C]))
    for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
        if ab[i]: continue
        for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
            if ac[j]: continue
            if bc[j - i]: continue
            # 添え字で混乱するが
            # ab[i-j]で
            # 添え字i-jは(bの開始)-(aの開始)を意味したことから
            # (i-j>0でa->bの配置から)
            # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
            # bcの添え字は(cの開始)-(bの開始)なのでj-i

            # [L,R)
            L = min(0, i, j)
            R = max(len(A), i + len(B), j + len(C))
            ans = min(ans, R - L)

    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査

Buggy python submission (verdict: Time Limit Exceeded):
def solve_panasonic2020_e():
    from itertools import islice, permutations, zip_longest

    abc = tuple(input() for _ in range(3))

    ret = sum(map(len, abc))
    for perm in permutations(abc):
        first, second, third = perm

        cands = [first + second]
        for i in range(len(first)):
            # first[i:]とsecondが一致するか見る
            # 一致なら候補に残す
            # すべてダメならfirst+secondだけ候補になる(重なりなし)
            cand = ''
            for fc, sc in zip_longest(islice(first, i, len(first)), second, fillvalue=''):
                if not fc or not sc:
                    cand += fc + sc
                elif fc == sc or sc == '?':
                    cand += fc
                elif fc == '?':
                    cand += sc
                else:
                    break
            else:
                cand = first[:i] + cand
                cands.append(cand)

        for cand in cands:
            for i in range(len(cand)):
                t = i
                for cc, tc in zip_longest(islice(cand, i, len(cand)), third, fillvalue=''):
                    t += 1
                    if not cc or not tc:
                        continue
                    if not (cc == tc or cc == '?' or tc == '?'):
                        break

                else:
                    ret = min(ret, t)

    print(ret)


if __name__ == '__main__':
    solve_panasonic2020_e()


Fixed submission:
# 解説の写経

def solve_panasonic2020_e():
    def unmatched(c1: str, c2: str) -> bool:
        """c1,c2がマッチしない"""
        return not (c1 == '?' or c2 == '?' or c1 == c2)

    A = input()
    B = input()
    C = input()

    MX = max(map(len, [A, B, C]))

    # 相対位置ごとの文字列マッチングの可否を調べる
    # ab/ac/bc[index差]:=その相対位置でマッチしないときTrue
    # [-MX,MX]
    # + : 左文字より右文字が右にある, a->b
    # - : 右文字より左文字が右にある, b->a
    ab = [False] * (MX * 4 + 1)
    ac = [False] * (MX * 4 + 1)
    bc = [False] * (MX * 4 + 1)

    for i, a in enumerate(A):
        for j, b in enumerate(B):
            ab[i - j] |= unmatched(a, b)

    for i, a in enumerate(A):
        for j, c in enumerate(C):
            ac[i - j] |= unmatched(a, c)

    for i, b in enumerate(B):
        for j, c in enumerate(C):
            bc[i - j] |= unmatched(b, c)

    # Aに対するB,Cの相対位置MX**2で全探索
    ans = sum(map(len, [A, B, C]))
    for i in range(-MX * 2, MX * 2 + 1):  # ACBのようにAB間にMX分空くこともあって、幅2MX
        if ab[i]: continue
        for j in range(-MX * 2, MX * 2 + 1):  # ABCのようにAC間にMX分空くこともあって、幅2MX
            if ac[j]: continue
            if bc[j - i]: continue
            # 添え字で混乱するが
            # ab[i-j]で
            # 添え字i-jは(bの開始)-(aの開始)を意味したことから
            # (i-j>0でa->bの配置から)
            # 今回i,jは(aの開始)を基準にした(b,cの開始位置)で
            # bcの添え字は(cの開始)-(bの開始)なのでj-i

            # [L,R)
            L = min(0, i, j)
            R = max(len(A), i + len(B), j + len(C))
            ans = min(ans, R - L)

    print(ans)
    return


if __name__ == '__main__':
    solve_panasonic2020_e()

# N**3は通らない
# N**2の方針=2本の文字列の捜査