#pragma GCC optimize ("O3")

#include <bits/stdc++.h>

using namespace std;

#ifdef LOCAL
#include <prettyprint.hpp>
#define debug(...)  cerr << "[" << #__VA_ARGS__ << "]: ", d_err(__VA_ARGS__);
#else
#define debug(...) 83;
#endif

void d_err() {
    cerr << endl;
}

template <typename H, typename... T>
void d_err(H h, T... t) {
    cerr << h << " ";
    d_err(t...);
}

#define FOR(i, m, n) for (int i = (m); i < (n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define bcnt __builtin_popcountll

typedef long long ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<ll,ll> Pll;
typedef pair<int,int> Pin;

ll INF = 1e16;
int inf = 1e9;
ll MOD = 1e9+7;

bool ab[10000], bc[10000], ac[10000];

void greedy_wrong() {
    cin.tie(0);
    ios_base::sync_with_stdio(false);
    cout << fixed << setprecision(20);

    vector<string> S(3);
    cin >> S[0] >> S[1] >> S[2];

    int len = 0;
    REP(i, 3) len += S[i].size();

    int ans = len;
    REP(i, 3) REP(j, 3) REP(k, 3) REP(z, 2) {
                    if (i == j || j == k || k == i) continue;

                    string a = S[i], b = S[j], c = S[k];

                    if (z & 1) {
                        swap(a, b); swap(b, c);
                    }

                    int c1 = 0;
                    string t1;
                    reverse(a.begin(), a.end());

                    REP(m, b.size()) {
                        if (a[0] != b[m] && a[0] != '?' && b[m] != '?') continue;

                        string tmp = "";
                        int l = 0;
                        while(l <= m && l < a.size()) {
                            if (a[l] != b[m-l] && a[l] != '?' && b[m-l] != '?') break;

                            if (a[l] != '?') tmp += a[l];
                            else tmp += b[m-l];

                            ++l;
                        }

                        if (m - l != -1 && a.size() - l != -1) continue;

                        if (c1 < m + 1)  {
                            c1 = m + 1;
                            t1 = tmp;
                        }
                    }

                    a = a.substr(0, a.size() - c1);
                    a += t1;

                    reverse(a.begin(), a.end());

                    if (z & 1) {
                        swap(b, c); swap(a, c);
                    }

                    int c2 = 0;
                    reverse(b.begin(), b.end());
                    REP(m, c.size()) {
                        if (b[0] != c[m] && b[0] != '?' && c[m] != '?') continue;

                        int l = 1;
                        while(l <= m && l < b.size()) {
                            if (b[l] != c[m-l] && b[l] != '?' && c[m-l] != '?') break;
                            ++l;
                        }

                        if (l == m + 1) c2 = max(c2, m + 1);
                    }

                    ans = min(len - c1 - c2, ans);
                }

    cout << ans << endl;

}


bool match(char c1, char c2) {
    return c1 == '?' || c2 == '?' || c1 == c2;
}

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

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


    int A = a.size();
    int B = b.size();
    int C = c.size();

    REP(i, A) REP(j, B) if (!match(a[i], b[j])) ab[i - j + 5000] = true;
    REP(i, B) REP(j, C) if (!match(b[i], c[j])) bc[i - j + 5000] = true;
    REP(i, A) REP(j, C) if (!match(a[i], c[j])) ac[i - j + 5000] = true;

    int m = B + C;

    int ans = inf;
    FOR(i, -m, m) FOR(j, -m, m) {
        if (!ab[i + 5000] && !ac[j + 5000] && !bc[j-i+5000]) {
            int l = min(0, min(i, j));
            int r = max(A, max(i + B, j + C));

            ans = min(ans, r - l);
        }
    }

    cout << ans << endl;
}


Measured memory_bytes: 256