from itertools import *

def comp(a,b,c=repeat("?")):
  return all(len({x,y,z}-{"?"}) <= 1 for x,y,z in zip(a, b, c))

def comp_dup(i,j,k,a,b,c):
  m = max(i,j,k)
  n = min(i+len(a),j+len(b),k+len(c))
  return comp(a[m-i:n-i],b[m-j:n-j],c[m-k:n-k])

def merge1(a,b):
  la, lb = map(len,[a,b])
  for i in range(la-lb+1):
    if comp(a[i:],b):
      yield i

def merge2(a,b):
  la, lb = map(len,[a,b])
  for i in range(1,lb):
    if comp(b, a[-lb+i:]):
      yield la-lb+i
  yield la

def merge3(a,b):
  la, lb = map(len,[a,b])
  for i in range(1,lb):
    if comp(b[i:], a):
      yield -i
  yield -lb

def min_merge(a,b,c):
  a,b,c=sorted([a,b,c],key=len,reverse=True)
  la, lb, lc = map(len,[a,b,c])
  abc = float("inf")
  a_b1, a_b2, a_b3  = map(list, [merge1(a,b), merge2(a,b), merge3(a,b)])
  a_b = {*a_b1, *a_b2, *a_b3}
  a_c1, a_c2, a_c3  = map(list, [merge1(a,c), merge2(a,c), merge3(a,c)])
  a_c = {*a_c1, *a_c2, *a_c3}
  b_c1, b_c2, b_c3  = map(list, [merge1(b,c), merge2(b,c), merge3(b,c)])
  b_c = {*b_c1, *b_c2, *b_c3}
  
  for i in a_b1:
    for j in a_c1:
      if j+lc <= i or i+lb <= j or j-i in b_c and comp_dup(0,i,j,a,b,c):
        return la
  
  can = (  
    chain(
      (lb+i for i in a_b2 if (a_c1 and a_c1[0]+lc <= i) or (b_c1 and la <= i+b_c1[-1]) or any(j-i in b_c and comp_dup(0,i,j,a,b,c) for j in takewhile((lambda j:j+lc<=i+lb), a_c1+a_c2))),
      (lb+i for i in count(a_b2[-1]+1) if any(j-i in b_c and comp_dup(0,i,j,a,b,c) for j in dropwhile((lambda j:j+lc<i), a_c2))),
    ),
    
    chain(
      (la-i for i in a_b3 if (b_c1 and i+b_c1[0]+lc <= 0) or (a_c1 and i+lb <= a_c1[-1]) or any(j-i in b_c and comp_dup(0,i,j,a,b,c) for j in takewhile((lambda j:i<=j), a_c1+a_c3))),
      (la-i for i in count(a_b3[-1]-1, -1) if any(j-i in b_c and comp_dup(0,i,j,a,b,c) for j in dropwhile((lambda j:i+lb<j), a_c3))),
    ),
    
    chain(
      (lc+i for i in a_c2 if (a_b1 and a_b1[0]+lb <= i) or any(i-j in b_c and comp_dup(0,j,i,a,b,c) for j in takewhile((lambda j:j+lb<=i+lc), a_b1+a_b2))),
      (lc+i for i in count(a_c2[-1]+1) if any(i-j in b_c and comp_dup(0,i,j,a,b,c) for j in dropwhile((lambda j:j+lb<i), a_b2))),
    ),
    
    chain(
      (la-i for i in a_c3 if (a_b1 and i+lc <= a_b1[-1]) or any(i-j in b_c and comp_dup(0,j,i,a,b,c) for j in takewhile((lambda j:i<=j), a_b1+a_b3))),
      (la-i for i in count(a_c3[-1]-1, -1) if any(i-j in b_c and comp_dup(0,j,i,a,b,c) for j in dropwhile((lambda j:i+lc<j), a_b3))),
    ),
  )
  
  return min(map(next, can))

a=input()
b=input()
c=input()

print(min_merge(a,b,c))



### FIXED CODE ###

from itertools import *
from heapq import *

def comp(a,b):
  return all(x==y or "?" in (x,y) for x,y in zip(a, b))

def comp3(a,b,c):
  return 

def comp3(i,j,k,a,b,c):
  m = max(i,j,k)
  n = min(i+len(a),j+len(b),k+len(c))
  return all(len({x,y,z}-{"?"}) <= 1 for x,y,z in zip(a[m-i:n-i],b[m-j:n-j],c[m-k:n-k]))

def _merge_mid(a,b):
  la, lb = map(len,[a,b])
  for i in range(la-lb+1):
    if comp(a[i:],b):
      yield i

def merge_mid(a,b):
  return list(_merge_mid(a,b))

def _merge_right(a,b):
  la, lb = map(len,[a,b])
  for i in range(max(la-lb+1, 1),la):
    if comp(b, a[i-la:]):
      yield i
  yield la

def merge_right(a,b):
  return list(_merge_right(a,b))

class K(int):
  def __new__(cls, *args, **kwargs):
    cb = kwargs.pop("cb")
    i = int.__new__(cls, *args, **kwargs)
    i.cb = cb
    return i

def min_merge(a,b,c):
  keys = sorted([a,b,c],key=len,reverse=True)
  len_keys = list(map(len, keys))
  mid = {(i,j):merge_mid(keys[i],keys[j]) for i,j in permutations(range(3), 2)}
  right = {(i,j):merge_right(keys[i],keys[j]) for i,j in permutations(range(3), 2)}
  
  for i in mid[0,1]:
    for j in mid[0,2]:
      if j+len_keys[2] <= i or i+len_keys[2] <= j or (j-i in mid[1,2] or j-i in right[1,2] or i-j in right[2,1]):
        return len_keys[0]
  
  def candicates(a,b,c):
    return chain(
      (K(i+len_keys[b], cb=lambda:(
       (mid[a,c] and mid[a,c][0]+len_keys[c] <= i) or (mid[b,c] and len_keys[a] <= i+mid[b,c][-1]) or 
       any((i-j in right[c,b] if i>j else j-i in mid[b,c]) and comp3(0,i,j,keys[a],keys[b],keys[c]) for j in dropwhile((i-len_keys[c]).__gt__, mid[a,c]+right[a,c]))
      )) for i in dropwhile((len_keys[c]-len_keys[b]+1).__gt__, right[a,b])),
      (K(min(i+next(dropwhile((len_keys[a]-i+1).__gt__, y))+len_keys[b] for i in x), cb=lambda:True) for (x, y) in [sorted((right[a,c], right[c,b]), key=len)]),
    )
  
  can = merge(*(candicates(x,y,z) for x,y,z in permutations(range(3),3)))
  
  for k in can:
    if k.cb():
      return k
  
  return sum(len_keys)

a=input()
b=input()
c=input()

print(min_merge(a,b,c))