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: Accepted)

/*
 * じょえチャンネル
 * 高評価・チャンネル登録よろしくおねがいします！
 * https://www.youtube.com/channel/UCRXsI3FL_kvaVL9zoolBfbQ
 */
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define rep(i,n) for(int i=0;i<n;i++)
#define REP(i,n) for(int i=1;i<n;i++)
#define all(v) v.begin(),v.end()
#define inf (int)(3e18)
#define P pair<int,int>
#define mod (int)(1e9+7)
template<class T> inline void chmin(T &a, T b) {
	a = min(a, b);
}
template<class T> inline void chmax(T &a, T b) {
	a = max(a, b);
}

string a,b,c;
bool ab[20005],ac[20005],bc[20005];
signed main() {
	cin>>a>>b>>c;
	rep(i,a.size()+b.size()+1){
		rep(j,b.size()){
			int k=-b.size()+i+j;
			if(0<=k&&k<a.size()&&b[j]!='?'&&a[k]!='?'&&b[j]!=a[k]){
				ab[i]=true;
			}
		}
	}
	rep(i,a.size()+c.size()+1){
		rep(j,c.size()){
			int k=-c.size()+i+j;
			if(0<=k&&k<a.size()&&c[j]!='?'&&a[k]!='?'&&c[j]!=a[k]){
				ac[i]=true;
			}
		}
	}
	rep(i,b.size()+c.size()+1){
		rep(j,c.size()){
			int k=-c.size()+i+j;
			if(0<=k&&k<b.size()&&c[j]!='?'&&b[k]!='?'&&c[j]!=b[k]){
				bc[i]=true;
			}
		}
	}
	int ans=inf;
	int aindex=b.size()+c.size();
	rep(i,a.size()+b.size()+c.size()*2+1){
		for(int j=max(0ll,min(aindex,j)-(int)c.size());j<=min((int)b.size()*2+(int)a.size()+(int)c.size()+1,max(j+(int)b.size(),aindex+(int)a.size()));j++){
			int dab=max(0ll,i-aindex+(int)b.size());
			int lab=max(aindex,i)-i,rab=min(aindex+(int)a.size(),i+(int)b.size())-i;
			if(ab[dab]){
				continue;
			}
			int dac=max(0ll,j-aindex+(int)c.size());
			lab=max(aindex,j)-j,rab=min(aindex+(int)a.size(),j+(int)c.size())-j;
			if(ac[dac]){
				continue;
			}
			dac=max(0ll,j-i+(int)c.size());
			lab=max(i,j)-j,rab=min(i+(int)b.size(),j+(int)c.size())-j;
			if(bc[dac]){
				continue;
			}
			chmin(ans,max({i+(int)b.size(),j+(int)c.size(),aindex+(int)a.size()})-min({i,j,aindex}));
		}
	}
	cout<<ans<<endl;
}