#include <bits/stdc++.h>
using namespace std;
using ll=long long;
bool match(char c1, char c2){
  return (c1=='?' ||c2=='?' ||c1==c2);
};
int main(){
  string a,b,c;
  cin>>a>>b>>c;
  int as=a.size(), bs=b.size(), cs=c.size();
  //a+bとを用意してcをくっつけていくか
  //bのスタート地点が-2000から+2000まで
  vector<bool> ab(16010,true), bc(16010,true), ac(16010,true); 
  for(int i=0; i<as; i++){
    for(int j=0; j<bs; j++){
      if(match(a[i], b[j])==false)
        ab[8000+i-j]=false;
    }
  }
  for(int i=0; i<bs; i++){
    for(int j=0; j<cs; j++){
      if(match(b[i], c[j])==false)
        bc[8000+i-j]=false;
    }
  }
  for(int i=0; i<as; i++){
    for(int j=0; j<cs; j++){
      if(match(a[i], c[j])==false)
        ac[8000+i-j]=false;
    }
  }
  //ab[i]=trueとなるiはabが連結可能
  //i<2000の場合はb先頭でスタートしてる
  //bc[j]とca[k]についてはどう絡むか
  //i<2000の場合、bc[j]はj<2000でないといけない？
  //それかbcのうしろにbcつく、はありえない。bはbにつく
  //ab[i]>2000のばあいはabがついてる
  //iはbの先頭を意味してる。
  //bcは同じくcの先頭か。2000がbの頭なのは固定か
  ll ans=10000;
  for(int i=4000; i<=12000; i++){
    for(int j=4000; j<=12000; j++){
      if(ab[i]&&ac[j]&&bc[8000-i+j]){
        ll L=min(8000,min(i,j));
        ll R=max(8000+as,max(i+bs,j+cs));
        ans=min(ans,R-L);
      }
    }
  }
  cout<<ans<<endl;
}
