

let rec seq a b () = if a > b then Seq.Nil else Seq.Cons (a, seq (a+1) b)
let (>>=) = Fun.flip Seq.flat_map

let eqs a b o =
  let a, b, o = if o < 0 then b, a, -o else a, b, o in
  let rec f i =
    if i+o >= String.length a || i >= String.length b then true
    else (a.[i+o] = '?' || b.[i] = '?' || a.[i+o] = b.[i]) && f (i+1)
  in f 0

let max3 a b = max (max a b)
let min3 a b = min (min a b)

module S = Set.Make(struct type t = int let compare = (-) end)


let () =
  Scanf.scanf "%s %s %s" @@ fun a b c ->
  let la, lb, lc = String.(length a, length b, length c) in
  let ab = Array.init 4001 (fun i -> eqs a b (i-2000)) in
  let bc = Array.init 4001 (fun i -> eqs b c (i-2000)) in
  let ac = Array.init 4001 (fun i -> eqs a c (i-2000)) in

  begin
    seq (-4000) 4000 >>= fun i ->
      if abs i <= 2000 && not ab.(i+2000) then Seq.empty else 
        seq (-4000) 4000 >>= fun j ->
          if (abs j > 2000 || ac.(j+2000)) &&
             (abs (j-i) > 2000 || bc.(j-i+2000))
          then
            Seq.return (max3 la (i+lb) (j+lc) - min3 0 i j)
          else
            Seq.empty
  end
  |> Seq.fold_left min 6000
  |> Printf.printf "%d\n"
