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 in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Linq;
using System.Collections.Generic;

using E = System.Linq.Enumerable;

public class Program
{
    public static void Main()
    {
        var a = Console.ReadLine().Trim();
        var b = Console.ReadLine().Trim();
        var c = Console.ReadLine().Trim();

        // ab, ac, bc, ba, ca, cb
        // abc, acb, bac, bca, cab, cba
        var ts = new []
        {
            ConcatUnion(a, b),
            ConcatUnion(b, a),
            ConcatUnion(b, c),
            ConcatUnion(c, b),
            ConcatUnion(a, c),
            ConcatUnion(c, a),
        };
        var ss = new []
        {
            ConcatUnion(ts[0], ts[2]),
            ConcatUnion(ts[1], ts[4]),
            ConcatUnion(ts[2], ts[5]),
            ConcatUnion(ts[3], ts[1]),
            ConcatUnion(ts[4], ts[3]),
            ConcatUnion(ts[5], ts[0]),
        };
        
        var l = ss.Min(x => x.Length);
        Console.WriteLine(l);
    }

    static bool Match(string a, int i, string b, int j) => a[i] == '?' || b[j] == '?' || a[i] == b[j];

    static string ConcatUnion(string a, string b)
    {
        int i = Math.Max(0, a.Length - b.Length);
        while (true)
        {
            while (i < a.Length && !Match(a, i, b, 0))
            {
                ++i;
            }
            int j = 0;
            int l = 0;
            while (i < a.Length && j < b.Length && Match(a, i, b, j))
            {
                ++i;
                ++j;
                ++l;
            }
            if (i >= a.Length || j >= b.Length)
            {
                return a + b.Substring(l);
            }
        }
    }
}