#include <iostream>
#include <string>
#include <algorithm>

const int upper_bound_length = 2000;
std::string a, b, c;
int length_a, length_b, length_c;
int min_length_s = 3*upper_bound_length;

// i-j+50000 element(0-based) means that assignment where a[i] and b[j] are match is contradict.
bool ab[100000], bc[100000], ac[100000];

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

int main() {
  std::cin >> a >> b >> c;
  length_a = a.length();
  length_b = b.length();
  length_c = c.length();
  for (int i = 0; i < length_a; ++i) {
    for (int j = 0; j < length_b; ++j) {
      if (!match(a[i], b[j])) ab[i-j+50000] = true;
    }
  }
  for (int i = 0; i < length_b; ++i) {
    for (int j = 0; j < length_c; ++j) {
      if (!match(b[i], c[j])) bc[i-j+50000] = true;
    }
  }
  for (int i = 0; i < length_a; ++i) {
    for (int j = 0; j < length_c; ++j) {
      if (!match(a[i], c[j])) ac[i-j+50000] = true;
    }
  }
  for (int i = -2*upper_bound_length; i <= 2*upper_bound_length; ++i) {
    for (int j = -2*upper_bound_length; j <= 2*upper_bound_length; ++j) {
      if (!ab[i+50000] && !bc[j-i+50000] && !ac[j+50000]) {
        int L = std::min(0, std::min(i, j));
        int R = std::max(length_a, std::max(length_b + i, length_c + j));
        min_length_s = std::min(min_length_s, R - L);
      }
    }
  }

  std::cout << min_length_s << std::endl;
}
