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_b = list(merge1(a,b))
  a_b2 = list(merge2(a,b))
  a_b3 = list(merge3(a,b))
  a_c = list(merge1(a,c))
  a_c2 = list(merge2(a,c))
  a_c3 = list(merge3(a,c))
  b_c = list(merge1(b,c))
  b_c2 = list(merge2(b,c))
  b_c3 = list(merge3(b,c))
  
  for i in a_b:
    for j in a_c:
      if j+lc <= i or i+lb <= j:
        return la
      if j-i in (b_c+b_c2+b_c3) and comp_dup(0,i,j,a,b,c):
        return la
        
  for i in a_b:
    for j in a_c2:
      if i+lb <= j:
        abc = min(abc, j+lc)
        break
      if j-i in (b_c2) and comp_dup(0,i,j,a,b,c):
        abc = min(abc, j+lc)
        break
    for j in a_c3:
      if j+lc <= i:
        abc = min(abc, la-j)
        break
      if j-i in (b_c3) and comp_dup(0,i,j,a,b,c):
        abc = min(abc, la-j)
        break
  
  for i in a_b2:
    if abc <= i+lb:
      break
    for j in a_c+a_c2:
      if j+lc  <= i:
        abc = min(abc, i+lb)
        break
      if j-i in (b_c+b_c3) and comp_dup(0,i,j,a,b,c):
        abc = min(abc, i+lb)
        break
    if abc <= i+lb:
      break
    if b_c and la <= i+b_c[-1]:
      abc = min(abc, i+lb)
      break
    
    for j in a_c3:
      if abc <= i-j+lb:
        break
      if j+lc <= i:
        abc = min(abc, i-j+lb)
        break
      if j-i in b_c3 and comp_dup(0,i,j,a,b,c):
        abc = min(abc, i-j+lb)
        break
        
    for j in b_c2:
      if abc <= i+j+lc:
        break
      if la <= i+j:
        abc = min(abc, i+j+lc)
        break
      if i+j in a_c2 and comp_dup(0,i,i+j,a,b,c):
        abc = min(abc, i+j+lc)
        break
      
      
  for i in a_b3:
    if abc <= la-i:
      break
    for j in a_c+a_c3:
      if i+lb <= j:
        abc = min(abc, la-i)
        break
      if j-i in (b_c+b_c2) and comp_dup(0,i,j,a,b,c):
        abc = min(abc, la-i)
        break
    if abc <= la-i:
      break
    if b_c and i+b_c[0]+lc <= 0:
      abc = min(abc, la-i)
      break
      
    for j in a_c2:
      if abc <= j-i+lc:
        break
      if i+lb <= j:
        abc = min(abc, j-i+lc)
        break
      if j-i in b_c2 and comp_dup(0,i,j,a,b,c):
        abc = min(abc, j-i+lc)
        break
        
    for j in b_c3:
      if abc <= la-i-j:
        break
      if i+j+lc <= 0:
        abc = min(abc, la-i-j)
        break
      if i+j in a_c3 and comp_dup(0,i,i+j,a,b,c):
        abc = min(abc, la-i-j)
        break
      
  
  for i in range(1,lc):
    if abc <= la+lb+i:
      break     
    for j in a_c2:
      if j-la-i in b_c3:
        return la+lb+i
    for j in b_c2:
      if j-la-i in a_c3:
        return la+lb+i
    
  return abc

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))