#include <bits/stdc++.h>
#include <boost/range/algorithm.hpp>
#include <boost/range/numeric.hpp>
#include <boost/integer/common_factor.hpp>
#include <boost/integer/common_factor_rt.hpp>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>

using std::string;
using std::vector;
using std::set;
using std::multiset;
using std::unordered_set;
using std::map;
using std::multimap;
using std::unordered_map;
using std::pair;
using std::cin;
using std::cout;

using boost::multiprecision::cpp_int;
using cpp_dec_float_1000 = boost::multiprecision::number<boost::multiprecision::cpp_dec_float<1000, boost::int128_type>>;

typedef uintmax_t    ull;
typedef intmax_t     ll;
typedef uint64_t     ul;
typedef uint32_t     ui;
typedef uint8_t      uc;

constexpr char CRLF  = '\n';
constexpr char SPACE = ' ';
constexpr char VECTOR_COUT_SEPARATOR = SPACE;
constexpr ll INF = 1000'000'007;
constexpr int MOD = 1000'000'007;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return true; } return false; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return true; } return false; }
template<class T> std::ostream& operator<< (std::ostream& os, const std::vector<T>& vc) { for(auto it = vc.begin(); it != vc.end(); ++it) { if (std::next(it) == vc.end()) os << *it; else os << *it << VECTOR_COUT_SEPARATOR; } return os; }
template<class T1, class T2> inline std::ostream & operator<< (std::ostream & os, const std::pair<T1, T2> & p) { return os << p.first << ' ' << p.second; }
template<class T> T modinv(T a, T m) { T b = m, u = 1, v = 0; while (b) { T t = a / b; a -= t * b; boost::swap(a, b); u -= t * v; boost::swap(u, v); } u %= m; if (u < 0) u += m; return u; }
template<class T> inline bool isSosuu(const T& n) { if (n == T(1)) { return false; } for (T i = 2; i*i <= n; ++i) { if (n % i == 0) { return false; } } return true; }
template<class T> vector<vector<T>> split (const vector<T>& S, T delim) { vector<vector<T>> ret{}; vector<T> buff{}; for (auto c : S) { if (c == delim) { if (!buff.empty()) ret.push_back(buff); buff.clear(); } else { buff.push_back(c); } } if (!buff.empty()) ret.push_back(buff); return ret; }

struct Tmp
{
public:
  Tmp(int N);
};

Tmp::Tmp(int N){}

bool comp(const string& s, const string& t, int offset)
{
  int i = 0;
  while (i + offset < s.size() && i < t.size()) {
    if (s[i+offset] == '?'
    || t[i] == '?'
    || s[i+offset] == t[i]) {
      // OK
      ;
    } else {
      return false;
    }

    ++i;
  }
  return true;
}

string concat(const string& s, const string& t, int offset)
{
  string buff = s.substr(0, offset);
  int i = 0;
  while (i + offset < s.size() || i < t.size()) {
    auto p = i + offset < s.size();
    auto q = i < t.size();
    if (p && q) {
      auto pp = s[i+offset] == '?';
      auto qq = t[i] == '?';
      if (pp && qq) {
        buff.push_back('?');
      } else if (pp) {
        buff.push_back(t[i]);
      } else if (qq) {
        buff.push_back(s[i+offset]);
      } else {
        buff.push_back(t[i]);
      }
    } else if (p) {
      buff.push_back(s[i+offset]);
    } else if (q) {
      buff.push_back(t[i]);
    } else {
      abort();
    }
    ++i;
  }
  return buff;
}

int query(string a, string b, string c)
{
  int res = INF;
  for (int i = 0; i <= a.size(); ++i) {
    auto jInf = i + b.size();
    for (int j = 0; j <= jInf; ++j) {
      if (comp(a, b, i)) {
        string d = concat(a, b, i);
        if (comp(d, c, j)) {
          string e = concat(d, c, j);
          chmin(res, (int)e.size());
        }
      }
    }
  }
  return res;
}

void solve(void)
{
  string a, b, c; cin >> a >> b >> c;

  vector<int> ab(8002);
  vector<int> ac(8002);
  vector<int> bc(16004);
  for (int i = -4000; i < 4001; ++i) {
    if (i < 0) {
      ab[i+4000] = comp(b, a, -i);
      ac[i+4000] = comp(c, a, -i);
    } else {
      ab[i+4000] = comp(a, b, i);
      ac[i+4000] = comp(a, c, i);
    }
  }
  for (int i = -8000; i < 8002; ++i) {
    if (i < 0) {
      bc[i+8000] = comp(c, b, -i);
    } else {
      bc[i+8000] = comp(b, c, i);
    }
  }

  int res = INF;
  int az = a.size(), bz = b.size(), cz = c.size();
  for (int i = -4000; i < 4001; ++i) {
    for (int j = -4000; j < 4001; ++j) {
      if (ab[i+4000] && ac[j+4000] && bc[j-i+8000]) {
        int l = std::min(0, std::min(i, j));
        int r = std::max(az, std::max(bz+i, cz+j));
        chmin(res, r-l);
      }
    }
  }

  cout << res << CRLF;
  return;
}

int main(void)
{
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);

  solve();

  return 0;
}


Measured memory_bytes: 384