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 is_ok(a: &Vec<char>, b: &Vec<char>) -> Vec<bool> {
    let mut ret = vec![true; a.len()];
    for i in 0..a.len() {
        if (0..b.len())
            .any(|j| i + j < a.len() && b[j] != '?' && a[i + j] != '?' && b[j] != a[i + j])
        {
            ret[i] = false;
        }
    }
    ret
}

fn main() {
    let a = read::<String>().chars().collect::<Vec<_>>();
    let b = read::<String>().chars().collect::<Vec<_>>();
    let c = read::<String>().chars().collect::<Vec<_>>();
    // [0]a->b, [1]b->a, [2]b->c, [3]c->b, [4]a->c, [5]c->a
    let mut ok = vec![vec![]; 6];
    for (i, &(ref a, ref b)) in [(&a, &b), (&b, &a), (&b, &c), (&c, &b), (&a, &c), (&c, &a)]
        .iter()
        .enumerate()
    {
        ok[i] = is_ok(&a, &b);
    }

    let mut ans = a.len() + b.len() + c.len();
    let criterion = |ok: &Vec<bool>, i| i >= ok.len() || ok[i];
    for &(ref ok0, ref ok1, ref ok2, l1, l2, l3) in &[
        (&ok[0], &ok[2], &ok[4], a.len(), b.len(), c.len()), // a -> b -> c
        (&ok[4], &ok[3], &ok[0], a.len(), c.len(), b.len()), // a -> c -> b
        (&ok[1], &ok[4], &ok[2], b.len(), a.len(), c.len()), // b -> a -> c
        (&ok[2], &ok[5], &ok[1], b.len(), c.len(), a.len()), // b -> c -> a
        (&ok[5], &ok[0], &ok[3], c.len(), a.len(), b.len()), // c -> a -> b
        (&ok[3], &ok[1], &ok[5], c.len(), b.len(), a.len()), // c -> b -> a
    ] {
        for i in 0..ok0.len() {
            if !criterion(ok0, i) {
                continue;
            }
            for j in i..ok0.len() + ok1.len() {
                if criterion(ok1, j - i) && criterion(ok2, j) {
                    let cur_length = *[l1, i + l2, j + l3].iter().max().unwrap();
                    ans = min(ans, cur_length);
                    break;
                }
            }
        }
    }
    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()
}