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)

# -*- coding: utf-8 -*-
a = list(input())
b = list(input())
c = list(input())

def equal(s,t):
  # sとtが等しいかどうか
  if len(s)!=len(t):
    return False
  for i in range(len(s)):
    if s[i]!='?' and t[i]!='?' and s[i]!=t[i]:
      return False
  return True

def compare(s,t):
  # sの先頭n文字 と tの末尾n文字が一致している ようなnの最大値
  length = min(len(s), len(t))
  n = 0
  for i in range(1,length+1):
    if equal(s[:i], t[-i:]):
      n = i
  return n

def subset(s,t):
  # sの部分文字列の中にtがあるかどうか
  if len(t)>len(s):
    return False
  for i in range(len(s)-len(t)+1):
    if equal(s[i:i+len(t)], t):
      return True
  return False

def concat(s,t):
  # s->tでくっつける
  c = compare(t,s)
  st = s + t[c:]
  for i in range(c):
    if t[i]=='?':
      st[i+len(s)-c] = '?'
  return st

def calculator():
  if substring[0] and substring[1]:
    return length[0]
  if substring[2] and substring[3]:
    return length[1]
  if substring[4] and substring[5]:
    return length[2]
  
  result = sum(length)
  
  # a->b
  tmp_str = concat(a,b)
  if subset(tmp_str, c):
    result = min(result, len(tmp_str))
  else:
    result = min(result, len(concat(c,tmp_str)), len(concat(tmp_str,c)))
  
  # a->c
  tmp_str = concat(a,c)
  if subset(tmp_str, b):
    result = min(result, len(tmp_str))
  else:
    result = min(result, len(concat(b,tmp_str)), len(concat(tmp_str,b)))
  
  # b->a
  tmp_str = concat(b,a)
  if subset(tmp_str, c):
    result = min(result, len(tmp_str))
  else:
    result = min(result, len(concat(c,tmp_str)), len(concat(tmp_str,c)))
  
  # b->c
  tmp_str = concat(b,c)
  if subset(tmp_str, a):
    result = min(result, len(tmp_str))
  else:
    result = min(result, len(concat(a,tmp_str)), len(concat(tmp_str,a)))
  
  # c->a
  tmp_str = concat(c,a)
  if subset(tmp_str, b):
    result = min(result, len(tmp_str))
  else:
    result = min(result, len(concat(b,tmp_str)), len(concat(tmp_str,b)))
  
  # c->b
  tmp_str = concat(c,b)
  if subset(tmp_str, a):
    result = min(result, len(tmp_str))
  else:
    result = min(result, len(concat(a,tmp_str)), len(concat(tmp_str,a)))
  
  return result

length = [len(a), len(b), len(c)]
substring = [subset(a,b), subset(a,c), subset(b,a),
             subset(b,c), subset(c,a), subset(c,b)]

print(calculator())