#include <stdio.h>
#include <stdlib.h>

#include <iostream>
#include <iomanip>
#include <sstream>
#include <fstream>
#include <stdint.h>
#include <string.h>

//#define _USE_MATH_DEFINES
//#include <math.h>

#include <vector>
#include <list>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <queue>
#include <stack>
#include <deque>
#include <string>

#include <algorithm>
#include <functional>
#include <bitset>
#include <functional>
#include <chrono>
#include <random>
#define sqr(x) (x) * (x)

typedef unsigned int u32;
typedef int i32;
typedef unsigned long long int u64;
//typedef int long long i64;
typedef size_t i64;
typedef uint16_t u16;
typedef int16_t i16;
typedef uint8_t u8;
typedef int8_t i8;

using namespace std;
using namespace std::chrono;

const i64 mod = 1000000007ll;
const i64 smod = 998244353ll;
const i64 inf = 1000000007; // 10000000000000007ll;

const double eps = 1e-8;

const i64 MAXN = 2'000 + 3;

string a[3];
bool b[3][3][MAXN];

void fillb(i64 u, i64 v) {
    for (i64 i = 0; i <= a[u].size(); i++) {
        b[u][v][i] = true;
        for (i64 j = 0; j < a[v].size() && i + j < a[u].size(); j++) {
            if (a[u][i + j] == '?' || a[v][j] == '?' || a[u][i + j] == a[v][j]) {
                continue;
            }
            b[u][v][i] = false;
            break;
        }
    }
}

void merge(i64 u, i64 v, set<i64>& q) {
    for (i64 i = 0; i <= a[u].size(); i++) {
        if (b[u][v][i]) {
            q.insert(i);
        }
    }
}

i64 check(i64 u, i64 v, i64 w) {
    i64 R = inf;

    for (size_t i = 0; i <= a[u].size(); i++) {
        if (!b[u][v][i]) {
            continue;
        }

        i64 r = max(a[u].size(), a[v].size() + i);

        for (i64 j = 0; j <= r; j++) {
            if (j <= a[u].size() && !b[u][w][j]) {
                continue;
            }
            if (j < i && i - j <= a[w].size() && !b[w][v][i - j]) {
                continue;
            }
            if (j >= i && j - i <= a[v].size() && !b[v][w][j - i]) {
                continue;
            }
            i64 t = max(r, a[w].size() + j);
            R = min(R, t);
        }

        for (i64 j = 0; j <= a[w].size(); j++) {
            if (!b[w][u][j]) {
                continue;
            }
            if (i + j <= a[w].size() && !b[w][v][i + j]) {
                continue;
            }
            i64 t = max(a[w].size(), r + j);
            R = min(R, t);
        }
    }

    return R;
}

int main(int argc, char* argv[]) {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); cout.precision(15); cout.setf(ios::fixed);

    for (i64 i = 0; i < 3; i++) {
        cin >> a[i];
    }

    for (i64 i = 0; i < 3; i++) {
        for (i64 j = 0; j < 3; j++) {
            if (i == j) {
                continue;
            }
            fillb(i, j);
        }
    }

    i64 R = 0;
    for (i64 i = 0; i < 3; i++) {
        R += a[i].size();
    }

    for (i64 i = 0; i < 3; i++) {
        for (i64 j = 0; j < 3; j++) {
            for (i64 k = 0; k < 3; k++) {
                if (i == j || i == k || j == k) {
                    continue;
                }
                i64 r = check(i, j, k);
                R = min(R, r);
            }
        }
    }

    cout << R << endl;

    return 0;
}

Measured memory_bytes: 384