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.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace AtCoder
{
    class Program
    {
        private static string Read() { return Console.ReadLine(); }
        private static int ReadInt() { return int.Parse(Read()); }
        private static long ReadLong() { return long.Parse(Read()); }
        private static double ReadDouble() { return double.Parse(Read()); }
        private static int[] ReadInts() { return Array.ConvertAll(Read().Split(), int.Parse); }
        private static long[] ReadLongs() { return Array.ConvertAll(Read().Split(), long.Parse); }
        private static double[] ReadDoubles() { return Array.ConvertAll(Read().Split(), double.Parse); }

        private static CompareInfo ci = new System.Globalization.CultureInfo("ja-JP").CompareInfo;
        private static int Compare(string a, string b) { return ci.Compare(a, b, System.Globalization.CompareOptions.Ordinal); }

        static string Overlap(string a, string b, int n)
        {
            for (int i = 0; i < b.Length; ++i)
            {
                if (i + n < a.Length && a[i + n] != '?' && b[i] != '?' && a[i + n] != b[i])
                {
                    return null;
                }
            }
            var c = new char[Math.Max(a.Length, b.Length + n)];
            for (int i = 0; i < a.Length; ++i) { c[i] = a[i]; }
            for (int i = 0; i < b.Length; ++i) { if (c[i + n] != '?' || b[i] != '?') { c[i + n] = b[i]; } }
            return new string(c);
        }

        static int Solve(string a, string b, string c)
        {
            int min = int.MaxValue;
            {
                for (int i = 0; i < a.Length; ++i)
                {
                    string s = Overlap(a, b, i);
                    if (s != null)
                    {
                        for (int j = 0; j < s.Length; ++j)
                        {
                            string t = Overlap(s, c, j);
                            if (t != null) { min = Math.Min(t.Length, min); }
                        }
                    }
                }
            }
            return min;
        }

        static void Main(string[] args)
        {
            string a = Read();
            string b = Read();
            string c = Read();
            int min = int.MaxValue;
            min = Math.Min(Solve(a, b, c), min);
            min = Math.Min(Solve(a, c, b), min);
            min = Math.Min(Solve(b, a, c), min);
            min = Math.Min(Solve(b, c, a), min);
            min = Math.Min(Solve(c, a, b), min);
            min = Math.Min(Solve(c, b, a), min);
            Console.WriteLine(min);
        }
    }
}