import java.lang.Math

fun main(args: Array<String>) {
    val a = readInputLine().toCharArray()
    val b = readInputLine().toCharArray()
    val c = readInputLine().toCharArray()

    val aLen = a.size
    val bLen = b.size
    val cLen = c.size

    fun match(c1: Char, c2: Char) = c1 == '?' || c2 == '?' || c1 == c2

    val ab = BooleanArray(100000)
    val ac = BooleanArray(100000)
    val bc = BooleanArray(100000)

    // ab, ac, bcについて重ねられない位置を確かめる
    // ab -> a左端を0点としたbの相対位置
    // ac -> a左端を0点としたcの相対位置
    // bc -> b左端を0点としたcの相対位置
    // 50000を中心として、+-動いた分のindexの要素がtrue -> その相対位置では配置できない
    for (i in 0 until aLen) {
        for (j in 0 until bLen) {
            if (!match(a[i], b[j])) {
                ab[i - j + 50000] = true
            }
        }
        for (j in 0 until cLen) {
            if (!match(a[i], c[j])) {
                ac[i - j + 50000] = true
            }
        }
    }
    for (i in 0 until bLen) {
        for (j in 0 until cLen) {
            if (!match(b[i], c[j])) {
                bc[i - j + 50000] = true
            }
        }
    }

    // 解答初期値は最大文字数
    var ans = 6000

    for (i in -4000..4000) {
        // i -> a左端を0点としたbの相対位置
        for (j in -4000..4000) {
            // j -> a左端を0点としたcの相対位置
            // このときb左端を0点としたcの相対位置はj - i
            if (!ab[i + 50000] && !ac[j + 50000] && !bc[j - i + 50000]) {
                val l = Math.min(0, Math.min(i, j))
                val r = Math.max(aLen, Math.max(i + bLen, j + cLen))
                ans = Math.min(ans, r - l)
            }
        }
    }

    println(ans)
}

fun readInputLine(): String {
    return readLine()!!
}
