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)

#include "bits/stdc++.h"
using namespace std;
#define Rep(i,n) for(int i=0;i<(int)(n);i++)
#define For(i,n1,n2) for(int i=(int)(n1);i<(int)(n2);i++)
#define REP(i,n) for(ll i=0;i<(ll)(n);i++)
#define RREP(i,n) for(ll i=((ll)(n)-1);i>=0;i--)
#define FOR(i,n1,n2) for(ll i=(ll)(n1);i<(ll)(n2);i++)
#define RFOR(i,n1,n2) for(ll i=((ll)(n1)-1);i>=(ll)(n2);i--)
#define all(a)  (a).begin(),(a).end()
#define SORT(a) sort((a).begin(),(a).end())
#define oorret 0
#define oor(x) [&](){try{x;} catch(const out_of_range& oor){return oorret;} return x;}()
#define IOS cin.tie(0),ios::sync_with_stdio(false)
typedef long long ll;
typedef unsigned long long ull;
typedef std::pair<ll, ll> P;
template<typename T1, typename T2> inline bool chmin(T1& a, T2 b) { if (a > b) { a = b; return 1; }return 0; }
template<typename T1, typename T2> inline bool chmax(T1& a, T2 b) { if (a < b) { a = b; return 1; }return 0; }
template<class Type>struct is_vector : std::false_type {};
template<class ValueType, class Alloc>struct is_vector<std::vector<ValueType, Alloc>> : std::true_type {};
template <typename T> inline std::ostream& operator << (std::ostream& out, const std::vector<T>& v) {
	if (v.empty())return out;
	constexpr bool is_vector_v = is_vector<T>::value;
	if (is_vector_v)for (auto itr = v.begin(); itr != v.end();)out << (*itr), out << ((++itr != v.end()) ? "\n" : "");
	else for (auto itr = v.begin(); itr != v.end();)out << (*itr), out << ((++itr != v.end()) ? " " : "");
	return out;
}
inline void put() {}
template<class T> inline void put(const T& first) { std::cout << first << "\n"; }
template<class T, class... N> inline void put(const T& first, const N& ... rest) { std::cout << first << " "; put(rest...); }
inline void putn() {}
template<class T, class... N> inline void putn(const T& first, const N& ... rest) { std::cout << first << "\n"; putn(rest...); }

bool equal(char c1, char c2) {
	if (c1 == '?' || c2 == '?') {
		return true;
	} else if (c1 == c2) {
		return true;
	}
	return false;
}

vector<int> makeTable(vector<char>& s,int n) {
	//int n = s.size();
	vector<int> ret(n + 1);
	ret[0] = -1;
	int j = -1;
	for (int i = 0; i < n; i++) {
		while (j >= 0 && /*s[i] != s[j]*/ !equal(s[i],s[j])) j = ret[j];
		ret[i + 1] = ++j;
	}
	return ret;
}

vector<int> kmp(vector<char>& str,int n,vector<int>& table, const string& word) {
	vector<int> /*table = makeTable(word),*/ ret;
	int m = 0, i = 0/*, n = str.size()*/;
	while (m + i < n) {
		if (/*word[i] == str[m + i]*/equal(word[i],str[m+i])) {
			if (++i == (int)(word.size())) {
				ret.push_back(m);
				m = m + i - table[i];
				i = table[i];
			}
		} else {
			m = m + i - table[i];
			if (i > 0) i = table[i];
		}
	}
	return ret;
}

int proc(string& d, string& e, string& f) {
	int ld = d.size(), le = e.size(), lf = f.size();
	vector<char> s(ld + le + lf);
	//string t = d;
	int res = INT_MAX;
	REP(i, ld + le) {
		REP(j, ld) {
			s[j] = d[j];
		}
		FOR(j, ld, ld + le + lf) {
			s[j] = '?';
		}
		REP(j, lf) {
			int k = i + j;
			if (!equal(s[k], f[j])) {
				continue;
			} else if (f[j] != '?') {
				s[k] = f[j];
			}
		}
		int n = i + lf;
		vector<int> table = makeTable(s, n);
		auto t = kmp(s, n, table, e);
		if (t.size() > 0) {
			chmin(res, n);
		}
	}
	return res;
}

int main() {
	IOS;
	string a, b, c, s;
	cin >> a >> b >> c;
	int res = a.size() + b.size() + c.size();
	chmin(res, proc(a, b, c));
	chmin(res, proc(a, c, b));
	chmin(res, proc(b, a, c));
	chmin(res, proc(b, c, a));
	chmin(res, proc(c, a, b));
	chmin(res, proc(c, a, b));
	chmin(res, proc(c, b, a));
	put(res);
	return 0;
}