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)

//QWsin
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define rep(i,x,y) for(int i=x;i<=y;++i)
#define out(i,u) for(int i=first[u];i!=-1;i=nxt[i])
#define repvc(i,vc) for(int i=0,Sz=vc.size();i<Sz;++i)
using namespace std;
inline int read()
{
	char ch=getchar();int ret=0,f=1;
	while(ch<'0' || ch>'9') {if(ch=='-')f=-1;ch=getchar();}
	for(;ch>='0' && ch<='9';ch=getchar()) ret=ret*10+ch-'0';
	return ret*f;
}

typedef long long ll;
const int INF=1<<30;

const int maxn=2000+10;

string res;

bool check(int pos,char *s)
{
	vector<int>tmp;
	for(int i=pos;i<(int)res.length();++i)
	{
		if(res[i]=='?') {}
		else if(s[i-pos]!='?' && res[i]!=s[i-pos]) {
			return 0;	
		}
	}
	return 1;
}

void fill(int pos,char *s)
{
	int l=strlen(s);
	int resl=res.length();
	for(int i=pos;i<resl;++i)
		res[i]=s[i-pos];
	for(int i=resl;i<pos+l;++i)
		res+=s[i-pos];
}

int solve(char *a,char *b,char *c)
{
	int la=strlen(a);
	int lc=strlen(c);
	res.clear();
	res=string(a);
//	cout<<res<<endl;
	int pos1;
	rep(i,0,la){
		if(check(i,b)) {
			pos1=i;fill(i,b);break;
		}
	}
//	cout<<res<<endl;
	rep(i,pos1,(int)res.length()){
		if(check(i,c)) {
//			fill(i,c);
//			cout<<res<<endl;
//			puts("");
			return i+lc;
		}
	}
	
	return INF;
}

char s[3][maxn];
int id[5];


int main()
{
	rep(i,0,2) scanf("%s",s[i]);
	int ans=INF;
	rep(i,1,3) id[i]=i;
	do{
		char *t[5];
		rep(i,1,3) t[i]=s[id[i]-1];
		ans=min(ans,solve(t[1],t[2],t[3]));
	}while(next_permutation(id+1,id+3+1));
	cout<<ans<<endl;
	return 0;
}