Problem:
Score : 500 points

Problem Statement

Snuke has a string s.
From this string, Anuke, Bnuke, and Cnuke obtained strings a, b, and c, respectively, as follows:

Choose a non-empty (contiguous) substring of s (possibly s itself). Then, replace some characters (possibly all or none) in it with ?s.

For example, if s is mississippi, we can choose the substring ssissip and replace its 1-st and 3-rd characters with ? to obtain ?s?ssip.

You are given the strings a, b, and c.
Find the minimum possible length of s.

Constraints

1 \leq |a|, |b|, |c| \leq 2000

a, b, and c consists of lowercase English letters and ?s.

Input

Input is given from Standard Input in the following format:

a
b
c

Output

Print the minimum possible length of s.

Sample Input 1

a?c
der
cod

Sample Output 1

7

For example, s could be atcoder.

Sample Input 2

atcoder
atcoder
???????

Sample Output 2

7

a, b, and c may not be distinct.

Solution in Python (3.4.3) (judge verdict: Wrong Answer)

def comp(a,b):
  r=""
  for x,y in zip(a,b):
    if x==y:
      r += x
    elif y=="?":
      r += x
    elif x=="?":
      r += y
    else:
      return False
  return r
 
def merge1(a,b):
  la, lb = map(len,[a,b])
  for i in range(la-lb+1):
    m = comp(a[i:],b)
    if m:
      yield i, (a[:i]+m+a[i+lb:], la)
 
def merge2(a,b):
  la, lb = map(len,[a,b])
  for i in range(1,lb):
    m = comp(b, a[-lb+i:])
    if m:
      yield la-lb+i, (a[:-lb+i]+m+b[-i:], la+i)
  yield la, (a+b, la+lb)
 
def merge3(a,b):
  la, lb = map(len,[a,b])
  for i in range(1,lb):
    m = comp(b[i:], a)
    if m:
      yield -i, (b[:i]+m+a[len(b)-i:], la+i)
  yield -lb, (b+a, la+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 = dict(merge1(a,b))
  a_b2 = dict(merge2(a,b))
  a_b3 = dict(merge3(a,b))
  a_c = dict(merge1(a,c))
  a_c2 = dict(merge2(a,c))
  a_c3 = dict(merge3(a,c))
  b_c = dict(merge1(b,c))
  b_c2 = dict(merge2(b,c))
  b_c3 = dict(merge3(b,c))
  
  for i,(d, ld) in a_b.items():
    for j, (e, le) in a_c.items():
      if j+lc<=i or i+lb<=j:
        return la
      if j-i in b_c and comp(d[j:], c):
        return la
      if j-i in b_c2 and comp(d[j:j+lb], c):
        return la
      if j-i in b_c3 and comp(d[i:], c[i-j:]):
        return la
  
  for i,(d, ld) in a_b2.items():
    if abc <= ld:
      break
    for j, (e, le) in a_c.items()|a_c2.items():
      if j+lc<=i:
        abc = min(abc, ld)
        break
      if j-i in b_c and comp(d[j:la], c):
        abc = min(abc, ld)
        break
      if j-i in b_c3 and comp(d[i:la], c[i-j:]):
        abc = min(abc, ld)
        break
    if abc <= ld:
      break
    for j, (e, le) in b_c.items():
      if la<=i+j:
        abc = min(abc, ld)
        break
    if abc <= ld:
      break
    for j, (e, le) in a_c3.items():
      if j+lc<=i:
        abc = min(abc, ld-j)
        break
      if j-i in b_c3 and comp(d[i:], c[i-j:]):
        abc = min(abc, ld-j)
        break
    for j, (e, le) in b_c2.items():
      if la<=i+j:
        abc = min(abc, i+le)
        break
      if i+j in a_c2 and comp(d[i+j:la], c):
        abc = min(abc, i+le)
        break
      
      
  for i,(d, ld) in a_b3.items():
    if abc <= ld:
      break
    for j, (e, le) in a_c.items()|a_c3.items():
      if i+lb <= j:
        abc = min(abc, ld)
        break
      if j-i in b_c and comp(d[j-i+lc-1:-1:-1], c[::-1]):
        abc = min(abc, ld)
        break
      if j-i in b_c2 and comp(d[lb-1:-i-1:-1], c[i-j+lb-1::-1]):
        abc = min(abc, ld)
        break
    if abc <= ld:
      break
    for j, (e, le) in b_c.items():
      if i+j+lc<=0:
        abc = min(abc, ld)
        break
    if abc <= ld:
      break
      
    for j, (e, le) in a_c3.items():
      if i+lb<=j:
        abc = min(abc, le-i)
        break
      if j-i in b_c2 and comp(d[j-i:lb], c):
        abc = min(abc, le-i)
        break
      
    for j, (e, le) in b_c3.items():
      if i+j+lc<=0:
        abc = min(abc, ld-j)
        break
      if i+j in a_c3 and comp(d[-i:], c[-i-j:]):
        abc = min(abc, ld-j)
        break
  
  for i in range(1,lc):
    if abc < la+lb+i:
      break     
    for j, (e, le) in a_c2.items():
      if j-la-i in b_c3:
        return la+lb+i
    for j, (e, le) in b_c2.items():
      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))