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>

#if MYDEBUG
#include "lib/cp_debug.hpp"
#else
#define DBG(...) ;
#endif
#if __cplusplus <= 201402L
template <typename T>
T gcd(T a, T b) { return ((a % b == 0) ? b : gcd(b, a % b)); }
template <typename T>
T lcm(T a, T b) { return a / gcd(a, b) * b; }
#endif
using LL = long long;
constexpr LL LINF = 334ll << 53;
constexpr int INF = 15 << 26;
constexpr LL MOD = 1E9 + 7;

namespace Problem {
using namespace std;

class Solver {
 public:
  void solve() {
    string a, b, c;
    cin >> a >> b >> c;
    int ans = INF;
    ans = min(ans, calc(a, b, c));
    ans = min(ans, calc(a, c, b));
    ans = min(ans, calc(b, a, c));
    ans = min(ans, calc(b, c, a));
    ans = min(ans, calc(c, a, b));
    ans = min(ans, calc(c, b, a));
    cout << ans << endl;
  }
  int calc(string a, string b, string c) {
    int la = a.length();
    int lb = b.length();
    int lc = c.length();
    int ret = INF;
    int d2 = 0;
    for (int d1 = la; d1 >= 0; --d1) {
      string tmp = a;
      bool ok = true;
      for (int i = 0; i < min(lb, la - d1); ++i) {
        if (b[i] == '?') continue;
        if (a[d1 + i] == '?') continue;
        if (b[i] != a[d1 + i]) ok = false;
      }
      if (ok) {
        for (; d2 <= lb; ++d2) {
          bool ok2 = true;
          for (int i = 0; i < min(lc, lb - d2); ++i) {
            if (c[i] == '?') continue;
            if (b[d2 + i] == '?') continue;
            if (c[i] != b[d2 + i]) ok2 = false;
          }
          if (ok2) {
            DBG(d1, d2)
            ret = min(ret, max({la, d1 + lb, d1 + d2 + lc}));
            break;
          }
        }
      }
    }
    DBG(a, b, c, ret)
    return ret;
  }
};

}  // namespace Problem

int main() {
  std::cin.tie(0);
  std::ios_base::sync_with_stdio(false);
  // std::cout << std::fixed << std::setprecision(12);

  Problem::Solver sol;
  sol.solve();
  return 0;
}