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 Rust (1.15.1) (judge verdict: Wrong Answer)

#![allow(unused_imports)]
#![allow(non_snake_case, unused)]

use std::cmp::*;
use std::collections::*;
use std::ops::*;

macro_rules! eprint {
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = write!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! eprintln {
	() => { eprintln!(""); };
	($($t:tt)*) => {{
		use ::std::io::Write;
		let _ = writeln!(::std::io::stderr(), $($t)*);
	}};
}
macro_rules! dbg {
	($v:expr) => {{
		let val = $v;
		eprintln!("[{}:{}] {} = {:?}", file!(), line!(), stringify!($v), val);
		val
	}}
}

macro_rules! mat {
	($($e:expr),*) => { Vec::from(vec![$($e),*]) };
	($($e:expr,)*) => { Vec::from(vec![$($e),*]) };
	($e:expr; $d:expr) => { Vec::from(vec![$e; $d]) };
	($e:expr; $d:expr $(; $ds:expr)+) => { Vec::from(vec![mat![$e $(; $ds)*]; $d]) };
}

macro_rules! ok {
	($a:ident$([$i:expr])*.$f:ident()$(@$t:ident)*) => {
		$a$([$i])*.$f($($t),*)
	};
	($a:ident$([$i:expr])*.$f:ident($e:expr$(,$es:expr)*)$(@$t:ident)*) => { {
		let t = $e;
		ok!($a$([$i])*.$f($($es),*)$(@$t)*@t)
	} };
}

pub fn readln() -> String {
	let mut line = String::new();
	::std::io::stdin().read_line(&mut line).unwrap_or_else(|e| panic!("{}", e));
	line
}

macro_rules! read {
	($($t:tt),*; $n:expr) => {{
		let stdin = ::std::io::stdin();
		let ret = ::std::io::BufRead::lines(stdin.lock()).take($n).map(|line| {
			let line = line.unwrap();
			let mut it = line.split_whitespace();
			_read!(it; $($t),*)
		}).collect::<Vec<_>>();
		ret
	}};
	($($t:tt),*) => {{
		let line = readln();
		let mut it = line.split_whitespace();
		_read!(it; $($t),*)
	}};
}

macro_rules! _read {
	($it:ident; [char]) => {
		_read!($it; String).chars().collect::<Vec<_>>()
	};
	($it:ident; [u8]) => {
		Vec::from(_read!($it; String).into_bytes())
	};
	($it:ident; usize1) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1
	};
	($it:ident; [usize1]) => {
		$it.map(|s| s.parse::<usize>().unwrap_or_else(|e| panic!("{}", e)) - 1).collect::<Vec<_>>()
	};
	($it:ident; [$t:ty]) => {
		$it.map(|s| s.parse::<$t>().unwrap_or_else(|e| panic!("{}", e))).collect::<Vec<_>>()
	};
	($it:ident; $t:ty) => {
		$it.next().unwrap_or_else(|| panic!("input mismatch")).parse::<$t>().unwrap_or_else(|e| panic!("{}", e))
	};
	($it:ident; $($t:tt),+) => {
		($(_read!($it; $t)),*)
	};
}

pub fn main() {
	let _ = ::std::thread::Builder::new().name("run".to_string()).stack_size(32 * 1024 * 1024).spawn(run).unwrap().join();
}

const MOD: usize = 1_000_000_007;
const INF: i64 = std::i64::MAX/2;

pub trait SetMinMax {
	fn setmin(&mut self, v: Self) -> bool;
	fn setmax(&mut self, v: Self) -> bool;
}
impl<T> SetMinMax for T where T: PartialOrd {
	fn setmin(&mut self, v: T) -> bool {
		*self > v && { *self = v; true }
	}
	fn setmax(&mut self, v: T) -> bool {
		*self < v && { *self = v; true }
	}
}

fn solve() {
	let a = read!(String);
	let b = read!(String);
	let c = read!(String);
	let mut ans = 10000000;
	ans.setmin(create(a.clone(),b.clone(),c.clone()));
	ans.setmin(create(a.clone(),c.clone(),b.clone()));
	ans.setmin(create(b.clone(),a.clone(),c.clone()));
	ans.setmin(create(b.clone(),c.clone(),a.clone()));
	ans.setmin(create(c.clone(),a.clone(),b.clone()));
	ans.setmin(create(c.clone(),b.clone(),a.clone()));
	println!("{}", ans);
}

fn create(a: String, b: String, c:String) -> usize {
	let ac = a.chars().collect::<Vec<char>>();
	let bc = b.chars().collect::<Vec<char>>();
	let cc = c.chars().collect::<Vec<char>>();
	let mut nc = vec![];
	for i in 0..ac.len(){
		let mut flag = true;
		let mut ty = vec![];
		for j in 0..bc.len() {
			let idx = i + j;
			if idx>=ac.len() {
				ty.push(0);
				continue;
			}
			let x = ac[idx];
			let y = bc[j];
			if x=='?' || y=='?'{
				if x=='?' && y=='?' {
					ty.push(3);
				}
				else if x=='?' {
					ty.push(2);
				}
				else {
					ty.push(1);
				}
				continue;
			}
			if x!=y {
				flag = false;
				break;
			}
			ty.push(0);
		}
		if !flag {
			continue;
		}
		let mut s = "".to_string();
		for j in 0..i {
			s.push(ac[j]);
		}
		for j in 0..bc.len() {
			if ty[j]==3 {
				s.push('?');
			}
			else if ty[j]==2 {
				s.push(bc[j]);
			}
			else if ty[j]==1 {
				s.push(ac[i+j]);
			}
			else{
				s.push(bc[j]);
			}
		}
		// println!("{}", s);
		nc.push(s);
	}
	let mut s = "".to_string();
	for j in 0..ac.len() {
		s.push(ac[j]);
	}
	for j in 0..bc.len() {
		s.push(bc[j]);
	}
	nc.push(s);
	let mut ans = 100000000;
	for y in nc {
		let yy = y.chars().collect::<Vec<char>>();
		let mut zz = "".to_string();
		for i in 0..cc.len() {
			zz.push(cc[i]);
		}
		for i in 0..y.len() {
			zz.push(yy[i]);
		}
		let z = zz.chars().collect::<Vec<char>>();
		let mut A = vec![0;z.len()];
		A[0] = A.len();
		let mut i = 1;
		let mut j = 0;
		while (i < A.len()) {
		  while (i+j < z.len() && (z[j] == z[i+j] || z[j]=='?' || z[i+j]=='?')){
			  j+=1; // 右向きにjを伸ばしていく
		  }
		  A[i] = j;
		  if (j == 0) { i+=1; continue;}
		  let mut k = 1;
		  while (i+k < z.len() && k+A[k] < j){
			  A[i+k] = A[k];
			  k+=1; // i~j間にkを走らせる
		  }
		  i += k;
		  j -= k;
		}
		for i in c.len()..zz.len() {
			let num = A[i];
			if num>=c.len() || num>=(zz.len()-i){
				// println!("{}", y);
				// println!("{} {}", i, num);
				let val = max(yy.len(), i + c.len());
				// println!("{}", val);
				ans.setmin(val);
			}
		}
		ans.setmin(zz.len());
	}
	ans
}


fn run() {
    solve();
}