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 <algorithm>
#include <array>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
using namespace std;
#define int long long
constexpr int INF = 1000000000 + 8;

int wraplen(string s, string t) {
    const int n = s.size(), m = t.size();
    vector<int> dp(n, 0);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i; j++) {
            if (j >= m) {
                dp[i] = 0;
                continue;
            }
            if (s[i + j] == '?' || t[j] == '?' || s[i + j] == t[j]) {
                dp[i]++;
            } else {
                dp[i] = 0;
                continue;
            }
        }
    }

    int ans = 0;
    for (int i = 0; i < n; i++) {
        ans = max(dp[i], ans);
    }

    return ans;
}

bool including(string s, string t) {
    const int n = s.size(), m = t.size();

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n - i; j++) {
            if (j >= m) {
                return true;
            }
            if (s[i + j] == '?' || t[j] == '?' || s[i + j] == t[j]) {
            } else {
                continue;
            }
        }
    }

    return false;
}

int shortlen(string s1, string s2, string s3) {
    int len = s1.size();
    len += s2.size() - wraplen(s1, s2);
    len += s3.size() - wraplen(s2, s3);

    int len2 = INF;
    if (including(s1, s2)) {
        len2 = s1.size();
        len2 += s3.size() - wraplen(s1, s3);

        if (including(s1, s3)) {
            len2 = s1.size();
        }
    }

    return min(len, len2);
}

signed main() {
    cin.tie(0);
    ios::sync_with_stdio(0);

    string a, b, c;
    cin >> a >> b >> c;

    int ans = INF;

    ans = min(shortlen(a, b, c), ans);
    ans = min(shortlen(a, c, b), ans);
    ans = min(shortlen(b, a, c), ans);
    ans = min(shortlen(b, c, a), ans);
    ans = min(shortlen(c, a, b), ans);
    ans = min(shortlen(c, b, a), ans);

    cout << ans << endl;
}