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

#![allow(unused_imports)]
#![allow(non_snake_case)]
use std::cmp::*;
use std::collections::*;
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($e:expr),*) => {
        #[cfg(debug_assertions)]
        $({
            let (e, mut err) = (stringify!($e), std::io::stderr());
            writeln!(err, "{} = {:?}", e, $e).unwrap()
        })*
    };
}

fn get_possible_matches(a: &Vec<char>, b: &Vec<char>, first_only: bool) -> Vec<Vec<char>> {
    let mut ans = vec![];
    for i in 0..a.len() + 1 {
        if (0..b.len())
            .any(|j| i + j < a.len() && a[i + j] != b[j] && a[i + j] != '?' && b[j] != '?')
        {
            continue;
        }
        let mut temp = vec![];
        for j in 0..i {
            temp.push(a[j]);
        }
        for j in i..a.len() {
            if a[j] != '?' {
                temp.push(a[j]);
            } else if j - i < b.len() && b[j - i] != '?' {
                temp.push(b[j - i]);
            } else {
                temp.push('?');
            }
        }
        if b.len() + i > a.len() {
            for j in 0..b.len() + i - a.len() {
                temp.push(b[j + a.len() - i]);
            }
        }
        ans.push(temp);
        if first_only {
            break;
        }
        if ans.len() > 50 {
            break;
        }
    }
    ans
}

fn main() {
    let a = read::<String>().chars().collect::<Vec<_>>();
    let b = read::<String>().chars().collect::<Vec<_>>();
    let c = read::<String>().chars().collect::<Vec<_>>();

    // try a->b  b->a
    let mut ans = a.len() + b.len() + c.len();

    for &(ref a, ref b, ref c) in &[
        (&a, &b, &c),
        (&b, &a, &c),
        (&a, &c, &b),
        (&c, &a, &b),
        (&b, &c, &a),
        (&c, &b, &a),
    ] {
        for matched in get_possible_matches(&a, &b, false) {
            ans = min(get_possible_matches(&matched, &c, true)[0].len(), ans);
        }
    }
    println!("{}", ans);
}

fn read<T: std::str::FromStr>() -> T {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).ok();
    s.trim().parse().ok().unwrap()
}

fn read_vec<T: std::str::FromStr>() -> Vec<T> {
    read::<String>()
        .split_whitespace()
        .map(|e| e.parse().ok().unwrap())
        .collect()
}