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;

typedef long long ll;
typedef double lf;
typedef long double Lf;
typedef pair <int,int> pii;
typedef pair <ll, ll> pll;

#define TRACE(x) cerr << #x << "  " << x << endl
#define FOR(i, a, b) for (int i = (a); i < int(b); i++)
#define REP(i, n) FOR(i, 0, n)
#define all(x) (x).begin(), (x).end()
#define _ << " " <<

#define fi first
#define sec second
#define mp make_pair
#define pb push_back

const int MAXN = 2020;

int ans;
int moze[6][MAXN];
int cnt[3][3];

void solve(vector <string> &v) {
  memset(moze, 0, sizeof moze);
  REP(i, 3) {
    REP(j, 3) {
      if (i == j) continue;
      int t = cnt[i][j];
      string &a = v[i];
      string &b = v[j];
      REP(start, (int)a.size()) {
        moze[t][start] = 1;
        REP(k, (int)b.size()) {
          if (start + k >= (int)a.size()) break;
          if (b[k] != a[start + k] && b[k] != '?' && a[start + k] != '?') {
            moze[t][start] = 0;
            break;
          }
        }
      }
    }
  }

  string &a = v[0];
  string &b = v[1];
  string &c = v[2];
  REP(i, (int)a.size()) {
    if (!moze[cnt[0][1]][i]) continue;
    int pre = i + b.size();
    if (pre < a.size()) pre = a.size();
    REP(j, pre) {
      bool ok = 1;
      if (j < a.size() && !moze[cnt[0][2]][j]) ok = 0;
      if (j >= i && !moze[cnt[1][2]][j - i]) ok = 0;
      if (j < i && j + c.size() > i && !moze[cnt[2][1]][i - j]) ok = 0;
      if (ok) {
        int tmp = j + c.size();
        if (tmp < pre) tmp = pre;
        ans = min(ans, tmp);
      }
    }
  }
}

int main() {
  cnt[0][1] = 0;
  cnt[0][2] = 1;
  cnt[1][0] = 2;
  cnt[1][2] = 3;
  cnt[2][0] = 4;
  cnt[2][1] = 5;
  vector <string> v;
  REP(i, 3) {
    string s;
    cin >> s;
    v.pb(s);
  }

  sort(all(v));

  ans = (1 << 30);
  do {
    solve(v);
  } while (next_permutation(all(v)));

  cout << ans << endl;
  return 0;
}