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++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

    //For higher stack size use g++ -O2 -std=c++11 -Wall -Wl,--stack=268435456 a.cpp -o a.exe in cmd
    #include <bits/stdc++.h>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstring>
    #include <chrono>
    #include <complex>
    #define ll long long
    #define ld long double
    #define vi vector<int>
    #define vll vector<ll>
    #define vvi vector < vi >
    #define pii pair<int,int>
    #define pll pair<long long, long long>
    #define mod 1000000007
    #define inf 1000000000000000001;
    #define all(c) c.begin(),c.end()
    #define mp(x,y) make_pair(x,y)
    #define mem(a,val) memset(a,val,sizeof(a))
    #define eb emplace_back
    #define pb push_back
    #define f first
    #define s second
    
    using namespace std;

    vector<int> GetMatch(const string& a, const string& b)
    {
        int i,j,k,flag=0,x=a.length();
        vector<int> ans;
        for(i=0;i<b.length();++i)
        {
            flag=1;
            for(k=0;k<a.length() && k<=i;++k)
            {
                if(b[i-k]=='?' || a[x-1-k]=='?')
                    continue;
                if(b[i-k]!=a[x-1-k])
                {
                    flag=0;
                    break;
                }
            }
            if(flag)
                ans.pb(i);
        }
        return ans;
    }

    int ab[2001],ac[2001],bc[2001];

    int process(const string& a, const string& b, const string&c)
    {
        int i,j,k;
        for(i=0;i<=2000;++i)
            ab[i]=0,ac[i]=0,bc[i]=0;
        vector<int> x,y,z;
        x=GetMatch(a,b);
        y=GetMatch(a,c);
        z=GetMatch(b,c);

        for(auto it:x)
        {
            ab[it]=1;
        }
        for(auto it:y)
        {
            ac[it]=1;
        }
        for(auto it:z)
        {
            bc[it]=1;
        }

        int ans=1e9,stb,stc,ans2;
        int alen=a.length(),blen=b.length(),clen=c.length();
        for (auto it : z)
        {
            if(it<b.length())
            {
                int pos=lower_bound(x.begin(),x.end(),(int)(b.length())-(int)it-1) - x.begin();
                if(pos>0)
                {
                    ans2=alen+blen+clen;
                    ans2=ans2-min(alen,x[pos]+1);
                    ans2=ans2-min(it+1,blen);

                    ans=min(ans,ans2);
                }
            }
            if(it>=b.length())
            {
                stb=0;
                stc=it-b.length()+1;
            }
            else
            {
                stb=b.length()-it-1;
                stc=0;
            }
            while(stb<b.length())
            {
                if(ab[stb]==1 && ac[stc]==1)
                {
                    ans2=alen+blen+clen;
                    ans2=ans2-min(alen,stb+1);
                    ans2=ans2-min(clen,it+1);
                    ans=min(ans,ans2);
                }
                ++stb;
                ++stc;
            }
        }
        return ans;
    }


    int main()
    {
        std::ios::sync_with_stdio(false);
        int T;
        T=1;
        // cin.ignore(); must be there when using getline(cin, s)
        while(T--)
        {
            string a,b,c;
            cin>>a>>b>>c;
            int ans=1e9;
            ans=min(ans,process(a,b,c));
            ans=min(ans,process(a,c,b));
            ans=min(ans,process(b,a,c));
            ans=min(ans,process(b,c,a));
            ans=min(ans,process(c,a,b));
            ans=min(ans,process(c,b,a));
            cout<<ans<<endl;
        }
        return 0;
    }