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)

// This code is generated by [cargo-atcoder](https://github.com/tanakh/cargo-atcoder)
// Original source code:
/*
use interpol::println;
use proconio::input;
use proconio::marker::*;

fn main() {
    input! {
        mut ss: [Chars; 3],
    }
    ss.sort_by(|l, r| r.len().cmp(&l.len()));
    fn add01(ss: &[Vec<char>]) -> usize {
        fn add012(s01: &Vec<char>, s2: &Vec<char>) -> usize {
            for subs01 in s01.windows(s2.len()) {
                if subs01
                    .iter()
                    .enumerate()
                    .all(|(i, c)| *c == s2[i] || *c == '?' || s2[i] == '?')
                {
                    return s01.len();
                }
            }
            let s201_len = (0..s2.len())
                .map(|i| {
                    if s2
                        .iter()
                        .skip(s2.len() - i)
                        .enumerate()
                        .all(|(i, c)| *c == s01[i] || *c == '?' || s01[i] == '?')
                    {
                        s2.len() + s01.len() - i
                    } else {
                        s2.len() + s01.len()
                    }
                })
                .min()
                .unwrap();
            let s012_len = (0..=s2.len())
                .map(|i| {
                    if s2.iter().take(i).enumerate().all(|(j, c)| {
                        *c == s01[s01.len() - i + j] || *c == '?' || s01[s01.len() - i + j] == '?'
                    }) {
                        s01.len() + s2.len() - i
                    } else {
                        s01.len() + s2.len()
                    }
                })
                .min()
                .unwrap();
            std::cmp::min(s201_len, s012_len)
        }
        let mut min = ss.iter().map(|s| s.len()).sum();
        for i in 0..ss[1].len() {
            if ss[1]
                .iter()
                .skip(i)
                .enumerate()
                .all(|(j, c)| *c == ss[0][j] || *c == '?' || ss[0][j] == '?')
            {
                let mut s10 = ss[1][0..i].iter().cloned().collect::<Vec<char>>();
                for j in 0..ss[1].len() - i {
                    s10.push(match (ss[0][j], ss[1][i + j]) {
                        ('?', '?') => '?',
                        (c, '?') => c,
                        ('?', c) => c,
                        (c, d) if c == d => c,
                        _ => unreachable!(),
                    });
                }
                let mut tmp = ss[0][i..].iter().cloned().collect::<Vec<char>>();
                s10.append(&mut tmp);
                min = std::cmp::min(add012(&s10, &ss[2]), min);
            }
        }
        for (i, subs0) in ss[0].windows(ss[1].len()).enumerate() {
            if subs0
                .iter()
                .enumerate()
                .all(|(j, c)| *c == ss[1][j] || *c == '?' || ss[1][j] == '?')
            {
                let mut s010 = ss[0][0..i].iter().cloned().collect::<Vec<char>>();
                for j in 0..ss[1].len() {
                    let c = match (subs0[j], ss[1][j]) {
                        ('?', '?') => '?',
                        (c, '?') => c,
                        ('?', c) => c,
                        (c, d) if c == d => c,
                        _ => {
                            dbg!(&subs0, &ss[1], i, j);
                            unreachable!();
                        }
                    };
                    s010.push(c);
                }
                let mut tmp = ss[0][i + ss[1].len()..]
                    .iter()
                    .cloned()
                    .collect::<Vec<char>>();
                s010.append(&mut tmp);
                min = std::cmp::min(add012(&s010, &ss[2]), min);
            }
        }
        for i in 0..ss[1].len() {
            if ss[0]
                .iter()
                .skip(ss[0].len() - i)
                .enumerate()
                .all(|(j, c)| *c == ss[1][j] || *c == '?' || ss[1][j] == '?')
            {
                let mut s01 = ss[0]
                    .iter()
                    .take(ss[0].len() - i)
                    .cloned()
                    .collect::<Vec<char>>();
                for (j, c) in ss[0].iter().skip(ss[0].len() - i).enumerate() {
                    s01.push(match (ss[1][j], c) {
                        ('?', '?') => '?',
                        (c, '?') => c,
                        ('?', c) => *c,
                        (c, d) if c == *d => c,
                        _ => unreachable!(),
                    });
                }
                let mut tmp = ss[1][i..].iter().cloned().collect::<Vec<char>>();
                s01.append(&mut tmp);
                min = std::cmp::min(add012(&s01, &ss[2]), min);
            }
        }
        min
    }
    let ans = add01(ss.as_slice());
    let ans = std::cmp::min(
        ans,
        add01(vec![ss[0].clone(), ss[2].clone(), ss[1].clone()].as_slice()),
    );
    println!("{ans}");
}
*/

fn main() {
    let exe = "/tmp/bin12C5091F";
    std::io::Write::write_all(&mut std::fs::File::create(exe).unwrap(), &decode(BIN)).unwrap();
    std::fs::set_permissions(exe, std::os::unix::fs::PermissionsExt::from_mode(0o755)).unwrap();
    std::process::exit(std::process::Command::new(exe).status().unwrap().code().unwrap())
}

fn decode(v: &str) -> Vec<u8> {
    let mut ret = vec![];
    let mut buf = 0;
    let mut tbl = vec![64; 256];
    for i in 0..64 { tbl[TBL[i] as usize] = i as u8; }
    for (i, c) in v.bytes().filter_map(|c| { let c = tbl[c as usize]; if c < 64 { Some(c) } else { None } }).enumerate() {
        match i % 4 {
            0 => buf = c << 2,
            1 => { ret.push(buf | c >> 4); buf = c << 4; }
            2 => { ret.push(buf | c >> 2); buf = c << 6; }
            3 => ret.push(buf | c),
            _ => unreachable!(),
        }
    }
    ret
}

const TBL: &'static [u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const BIN: &'static str = "<base64-encoded ELF executable removed>";