#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <list>
#include <set>
#include <numeric>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <climits>
#include <cfloat>
#include <ctime>
#include <complex>
#include <cassert>
#include <array>
#include <bitset>
#include <unordered_map>
#include <random>

using namespace std;
typedef long long LL;
typedef pair<int,int> P;

void calcZ(char in[], int z[]){
	int l=-1,r=-1;
	for(int i=1;in[i];i++){
		int j=i;
		if(i<=r){
			if(z[i-l]<r-i+1){
				z[i]=z[i-l];
				continue;
			}
			j=r+1;
		}
		while(in[j]==in[j-i]){
			j++;
		}
		z[i]=j-i;
		if(z[i]){
			r=j-1;
			l=i;
		}
	}
}
const int L=1e5+10;
char a[L];
int z[L];
int pos[3][3];
char in[3][L];
int sz[3];
int main() {
	for(int i=0;i<3;i++){
		scanf("%s",in[i]);
		sz[i]=strlen(in[i]);
	}
	for(int i=0;i<3;i++){
		strcpy(a,in[i]);
		a[sz[i]]='$';
		for(int j=0;j<3;j++){
			if(i==j)continue;
			strcpy(a+1+sz[i],in[j]);
			a[sz[i]+1+sz[j]]=0;
			calcZ(a,z);
			pos[j][i]=sz[j];
			for(int k=0;k<sz[j];k++){
				if(z[k+sz[i]+1]==sz[i]||
					z[k+sz[i]+1]==sz[j]-k){
					pos[j][i]=k;
					break;
				}
			}
			//cerr << j << ", " << i << ": " << pos[j][i] << endl;
		}
	}
	int per[]={0,1,2};
	int ret=sz[0]+sz[1]+sz[2];
	do{
		int a=per[0];
		int b=per[1];
		int c=per[2];
		if(pos[a][b]+sz[b]<=sz[a]){
			ret=min(ret,max(pos[a][c]+sz[c],sz[a]));
		}
		else{
			ret=min(ret,max(pos[a][b]+pos[b][c]+sz[c],pos[a][b]+sz[b]));
		}
	}while(next_permutation(per,per+3));
	printf("%d\n",ret);

	return 0;
}


#include <string>
#include <vector>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <map>
#include <list>
#include <set>
#include <numeric>
#include <queue>
#include <stack>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <climits>
#include <cfloat>
#include <ctime>
#include <complex>
#include <cassert>
#include <array>
#include <bitset>
#include <unordered_map>
#include <random>

using namespace std;
typedef long long LL;
typedef pair<int,int> P;

void calcZ(char in[], int z[]){
	int l=-1,r=-1;
	for(int i=1;in[i];i++){
		int j=i;
		if(i<=r){
			if(z[i-l]<r-i+1){
				z[i]=z[i-l];
				continue;
			}
			j=r+1;
		}
		while(in[j]==in[j-i]){
			j++;
		}
		z[i]=j-i;
		if(z[i]){
			r=j-1;
			l=i;
		}
	}
}
const int L=1e5+10;
char a[2*L];
int z[2*L];
int pos[3][3];
char in[3][L];
int sz[3];
int main() {
	for(int i=0;i<3;i++){
		scanf("%s",in[i]);
		sz[i]=strlen(in[i]);
	}
	for(int i=0;i<3;i++){
		strcpy(a,in[i]);
		a[sz[i]]='$';
		for(int j=0;j<3;j++){
			if(i==j)continue;
			strcpy(a+1+sz[i],in[j]);
			a[sz[i]+1+sz[j]]=0;
			calcZ(a,z);
			pos[j][i]=sz[j];
			for(int k=0;k<sz[j];k++){
				if(z[k+sz[i]+1]==sz[i]||
					z[k+sz[i]+1]==sz[j]-k){
					pos[j][i]=k;
					break;
				}
			}
			//cerr << j << ", " << i << ": " << pos[j][i] << endl;
		}
	}
	int per[]={0,1,2};
	int ret=sz[0]+sz[1]+sz[2];
	do{
		int a=per[0];
		int b=per[1];
		int c=per[2];
		if(pos[a][b]+sz[b]<=sz[a]){
			ret=min(ret,max(pos[a][c]+sz[c],sz[a]));
		}
		else{
			ret=min(ret,max(pos[a][b]+pos[b][c]+sz[c],pos[a][b]+sz[b]));
		}
	}while(next_permutation(per,per+3));
	printf("%d\n",ret);

	return 0;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (int)(x - 'a' + 1)

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int mod = 1e9 + 7;
const int pri = 31;
const int N = 1e5 + 1;
int pw[N];
int ans;

string t[3];

void input() {
    cin >> t[0];
    cin >> t[1];
    cin >> t[2];
    ans = len(t[0]) + len(t[1]) + len(t[2]);
    sort(t, t + 3);
}

void calc_pow() {
    pw[0] = 1;
    for(int i = 1; i < N; ++i) {
        pw[i] = 1ll * pw[i - 1] * pri % mod;
    }
}

vec <int> calc_hash(string &s) {
    vec <int> res;
    res.resize(len(s));
    for(int i = 0; i < len(s); ++i) {
        res[i] = (1ll * (i? res[i - 1]: 0) * pri + v(s[i])) % mod;
    }
    return res;
}

int hash_query(vec <int> &v, int l, int r) {
    return (v[r] - 1ll * (l? v[l - 1]: 0) * pw[r - l + 1] % mod + mod) % mod;
}

int hash_query(vec <int> &v, int d) {
    int l = len(v) - d;
    int r = len(v) - 1;
    return hash_query(v, l, r);
}

int calc() {
    string s = t[0];
    vec <int> cur = calc_hash(s);
    for(int i = 1; i < 3; ++i) {
        vec <int> add = calc_hash(t[i]);
        bool skip = 0;
        if(len(add) <= len(cur)) {
            for(int j = 0; j <= len(cur) - len(add); ++j) {
                if(hash_query(cur, j, j + len(add) - 1) == add.back()) {
                    skip = 1;
                    break;
                }
            }
        }
        if(skip) {
            continue;
        }
        for(int j = min(len(cur), len(add)); j >= 0; --j) {
            if(hash_query(cur, j) == (j? add[j - 1]: 0)) {
                s += t[i].substr(j);
                cur = calc_hash(s);
                break;
            }
        }
    }
    return len(s);
}

void solve() {
    calc_pow();
    do {
        ans = min(ans, calc());
    } while(next_permutation(t, t + 3));
    cout << ans << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (int)(x - 'a' + 1)

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
template <class T1, class T2 = null_type, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int mod = 1e9 + 7;
const int pri = 31;
const int N = 1e5 + 1;
int pw[N];
int ans;

string t[3];

void input() {
    cin >> t[0];
    cin >> t[1];
    cin >> t[2];
    ans = len(t[0]) + len(t[1]) + len(t[2]);
    sort(t, t + 3);
}

void calc_pow() {
    pw[0] = 1;
    for(int i = 1; i < N; ++i) {
        pw[i] = 1ll * pw[i - 1] * pri % mod;
    }
}

vec <int> calc_hash(string &s) {
    vec <int> res;
    res.resize(len(s));
    for(int i = 0; i < len(s); ++i) {
        res[i] = (1ll * (i? res[i - 1]: 0) * pri + v(s[i])) % mod;
    }
    return res;
}

int hash_query(vec <int> &v, int l, int r) {
    return (v[r] - 1ll * (l? v[l - 1]: 0) * pw[r - l + 1] % mod + mod) % mod;
}

int hash_query(vec <int> &v, int d) {
    int l = len(v) - d;
    int r = len(v) - 1;
    return hash_query(v, l, r);
}

int calc() {
    string s = t[0];
    vec <int> cur = calc_hash(s);
    for(int i = 1; i < 3; ++i) {
        vec <int> add = calc_hash(t[i]);
        bool skip = 0;
        if(len(add) <= len(cur)) {
            for(int j = 0; j <= len(cur) - len(add); ++j) {
                if(hash_query(cur, j, j + len(add) - 1) == add.back()) {
                    skip = 1;
                    break;
                }
            }
        }
        if(skip) {
            continue;
        }
        for(int j = min(len(cur), len(add)); j >= 0; --j) {
            if(hash_query(cur, j) == (j? add[j - 1]: 0)) {
                s += t[i].substr(j);
                cur = calc_hash(s);
                break;
            }
        }
    }
    return len(s);
}

void solve() {
    calc_pow();

    vec <int> a = calc_hash(t[1]);
    vec <int> b = calc_hash(t[0]);
    do {
        ans = min(ans, calc());
    } while(next_permutation(t, t + 3));
    cout << ans << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;

#define int long long

#ifdef lioraju
	#define ndbg(x)
#else
	#define ndbg(x) x
#endif

struct KMP
{
	vector<int> faf;
	string pat;

	void build(string s)
	{
		pat = s, faf.resize(s.size());

		faf[0] = -1;
		for (int i=1, n=s.size();i<n;i++)
		{
			int j = faf[i-1];
			while (j>=0 && s[j+1]!=s[i]) j = faf[j];

			if (s[j+1]==s[i]) j++;
			faf[i] = j;
		}
	}

	int modSearch(string s)
	{
		int i=0, j=-1, sL = s.size(), pL = pat.size();
		while (i<sL)
		{
			if (s[i]==pat[j+1]) i++, j++;
			else if (j>=0) j = faf[j];
			else i++;

			if (j==pL-1) j = faf[j];
		}
		return j;
	}

};

string minMix(string va, string vb)
{
	KMP sm; sm.build(vb);
	return va + vb.substr(sm.modSearch(va)+1);
}

int32_t main()
{
	ndbg( ios::sync_with_stdio(0); cin.tie(0); );
	string v[3]; cin>>v[0]>>v[1]>>v[2];

	int mnn = 1e9;
	vector<int> id = {0, 1, 2};
	do mnn = min(mnn, (int)minMix(minMix(v[id[0]], v[id[1]]), v[id[2]]).size());
	while (next_permutation(id.begin(), id.end()));

	cout<<mnn<<'\n';
}


#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;

#define int long long

#ifdef lioraju
	#define ndbg(x)
#else
	#define ndbg(x) x
#endif

struct KMP
{
	vector<int> faf;
	string pat;

	void build(string s)
	{
		pat = s, faf.resize(s.size());

		faf[0] = -1;
		for (int i=1, n=s.size();i<n;i++)
		{
			int j = faf[i-1];
			while (j>=0 && s[j+1]!=s[i]) j = faf[j];

			if (s[j+1]==s[i]) j++;
			faf[i] = j;
		}
	}

	int modSearch(string s)
	{
		int i=0, j=-1, sL = s.size(), pL = pat.size();
		while (i<sL)
		{
			if (s[i]==pat[j+1]) i++, j++;
			else if (j>=0) j = faf[j];
			else i++;

			if (j==pL-1 && i<sL) j = faf[j];
		}
		return j;
	}

};

string minMix(string va, string vb)
{
	KMP sm; sm.build(vb);
	return va + vb.substr(sm.modSearch(va)+1);
}

int32_t main()
{
	ndbg( ios::sync_with_stdio(0); cin.tie(0); );
	string v[3]; cin>>v[0]>>v[1]>>v[2];

	int mnn = 1e9;
	vector<int> id = {0, 1, 2};
	do mnn = min(mnn, (int)minMix(minMix(v[id[0]], v[id[1]]), v[id[2]]).size());
	while (next_permutation(id.begin(), id.end()));

	cout<<mnn<<'\n';
}


#include<iostream>
#include<algorithm>
#include<numeric>
#include<cstring>
#include<vector>
using namespace std;

#define int long long

#ifdef lioraju
	#define ndbg(x)
#else
	#define ndbg(x) x
#endif

struct KMP
{
	vector<int> faf;
	string pat;

	void build(string s)
	{
		pat = s, faf.resize(s.size());

		faf[0] = -1;
		for (int i=1, n=s.size();i<n;i++)
		{
			int j = faf[i-1];
			while (j>=0 && s[j+1]!=s[i]) j = faf[j];

			if (s[j+1]==s[i]) j++;
			faf[i] = j;
		}
	}

	int modSearch(string s)
	{
		int i=0, j=-1, sL = s.size(), pL = pat.size();
		while (i<sL)
		{
			if (s[i]==pat[j+1]) i++, j++;
			else if (j>=0) j = faf[j];
			else i++;

			if (j==pL-1 && i<sL) j = faf[j];
		}
		return j;
	}

	bool modSearch2(string s)
	{
		int i=0, j=-1, sL = s.size(), pL = pat.size();
		while (i<sL)
		{
			if (s[i]==pat[j+1]) i++, j++;
			else if (j>=0) j = faf[j];
			else i++;

			if (j==pL-1) return 1;
		}
		return 0;
	}

};

string minMix(string va, string vb)
{
	KMP sm; sm.build(vb);
	return va + vb.substr(sm.modSearch(va)+1);
}

int minSupStr(vector<string> v)
{
	int n = v.size(), mnn = 1e9;
	vector<int> id(n); iota(id.begin(), id.end(), 0);
	do
	{
		string s = v[id[0]];
		for (int i=1;i<n;i++) s = minMix(s, v[id[i]]);
		mnn = min(mnn, (int)s.size());
	}
	while (next_permutation(id.begin(), id.end()));

	return mnn;
}

inline bool contain(string a, string b)
{
	KMP sm; sm.build(b);
	return sm.modSearch2(a);
}

int32_t main()
{
	ndbg( ios::sync_with_stdio(0); cin.tie(0); );
	vector<string> v(3); cin>>v[0]>>v[1]>>v[2];

	int mnn = minSupStr(v);
	for (int i=0;i<3;i++)
	{
		int i2 = (i+1)%3, i3 = (i+2)%3;
		bool b2 = contain(v[i], v[i2]), b3 = contain(v[i], v[i3]);

		if (b2 && b3) mnn = min(mnn, (int)v[i].size());
		if (b2) mnn = min(mnn, minSupStr({v[i], v[i3]}));
		if (b3) mnn = min(mnn, minSupStr({v[i], v[i2]}));
	}

	cout<<mnn<<'\n';
}


#include<bits/stdc++.h>
#define speedio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;

typedef long long       ll;
typedef long double     ld;

typedef vector<int>     vi;
typedef vector<bool>    vb;
typedef vector<ll>      vll;
typedef vector<vi>      vvi;
typedef vector<vll>     vvll;
typedef vector<string>  vs;

typedef pair<int, int>  pii;
typedef pair<ll, int>   pli;
typedef pair<ll, ll>    pll;
typedef vector< pii >   vpi;
typedef vector< pll >   vpll;

// typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> oset;

#define pb           push_back
#define mod          1000000007
#define INF          1e17
#define mini         INT_MIN
#define maxo         INT_MAX
#define eb           emplace_back
#define ff           first
#define ss           second
#define re           return
#define endl         "\n"

#define all(c)       c.begin(),c.end()
#define be           begin()
#define en           end()
#define sz(x)        (ll)x.size()
#define mem(a,val)   memset(a,val,sizeof(a))
#define mk(x,y)      make_pair(x,y)
#define mid(s,e)     ((s)+((e)-(s))/2)

#define fo(i,a,b)     for(ll i = (ll)(a); i <= (ll)(b); i++)
#define rf(i,a,b)    for(ll i = (ll)(a); i >= (ll)(b); i--)
#define read(a,n)    for(int i=0;i<n;i++)cin>>a[i];
#define show(a,n)    for(int i=0;i<n;i++)cout<<a[i]<<' ';cout<<endl;
#define p2(n)        (1LL << (n))
#define deb(x) cout <<#x << " = " << x << " | " << "LINE: "<<__LINE__<< endl;
template<typename... T> void rd(T&... args) { ((cin >> args), ...); }
template<typename... T> void pp(T... args) { ((cout << args << " "), ...); cout<<"\n"; }

void add(ll &x, ll y){ x += y; if(x>=mod) x %= mod; if(x<0) x = x%mod + mod; }

//============== *** START OF CODE ***

string pat;
const int maxn = 1e6 + 5;
int lps[maxn+5];

void computeLPSArray(){
    int m = pat.size();
    lps[0] = 0; // lps[0] is always 0
    int i = 1;
    int j = 0; // lps of previous

    while(i<m){
        if(pat[i]==pat[j]){
            lps[i]=j+1;
            j++; i++;
        }
        else{
            if(j==0){
                lps[i]=0;i++;
            }
            else{
                j = lps[j-1];
            }
        }
    }
}

void kmpSearch(string str){
    int i=0,j=0;
    int n = sz(str), m = sz(pat);
    while(i<n){
        if(str[i]==pat[j]){
            i++; j++;
            if(j==m){
                cout<<"Found pattern at index "<<i-m<<endl;
            }
        }
        else{
            if(j==0){
                i++;
            }
            else{
                j = lps[j-1];
            }
        }
    }

}
void solve()
{
    string s[3];
    read(s,3);
    int a[3] = {0,1,2};
    ll ans = sz(s[0]) + sz(s[1]) + sz(s[2]);
    do{
        string s1 = s[a[0]],s2=s[a[1]],s3=s[a[2]];
        pat = s2 + "#" + s1;
        computeLPSArray();
        s1 = s1 + s2.substr(lps[sz(pat)-1]);
        pat = s3 + "#" + s1;
        computeLPSArray();
        string temp = s1 + s3.substr(lps[sz(pat)-1]);
        ans = min(ans,sz(temp));
    }
    while(next_permutation(a,a+3));
    cout<<ans<<endl;
}

void prep(){}

//=============== *** END OF CODE ***

int main(){
    speedio; cout<<fixed<<setprecision(12);

// #ifndef ONLINE_JUDGE
//     freopen("input.txt", "r", stdin);
//     freopen("output.txt", "w", stdout);
// #endif

    prep();
    int t = 1;
    // cin >> t;
    while(t--)
        solve();

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i : x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
#define fast ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define ll long long
#define int long long
#define vll vector<long long>
#define pii pair<long long ,long long >
#define vvi vector< vector<long long > >
#define vpii vector<pair<int,int>>
#define pll  pair<long long ,long long >
#define pb  push_back
#define ff  first
#define sec second
#define SORT(a) sort(a.begin(),a.end())
#define SORTR(a) sort(a.rbegin(),a.rend())
#define m_p make_pair
#define all(x) (x.begin(),x.end())
#define sz(v) ((int)(v.size()))
#define endl '\n'
typedef vector< long long > vi ;
const int MOD = 1e9 + 7 ;
int size = 10000000;

int  prefix_function(string s) {

	int n = (int)s.length(); int mx = INT_MIN;
	vector<int> pi(n);
	for (int i = 1; i < n; i++) {
		int j = pi[i - 1];
		while (j > 0 && s[i] != s[j])
			j = pi[j - 1];
		if (s[i] == s[j])
			j++;
		pi[i] = j;

	}

	return pi[n - 1];
}

int func( string s1 , string s2 , string s3 ) {

	int n1 = s1.length();
	int n2 = s2.length();
	int n3 = s3.length();
	int l = prefix_function(s2 + '#' + s1 );
	s1 = s1 + s2.substr(l);
	int r = prefix_function(s3 + '#' + s1); string temp1 = s1 + s3.substr(r);
	int r1 = prefix_function(s1 + '#' + s3); string temp2 = s1 + s3.substr(r1);

	return min(sz(temp1) , sz(temp2));

}

void solve() {

	string s1 , s2, s3; cin >> s1 >> s2 >> s3 ;

	int mn = INT_MAX ;

	mn = min(mn, func( s1 , s2 , s3 ));
	mn = min(mn, func( s2 , s1 , s3 ));
	mn = min(mn, func( s1 , s3 , s2 ));
	mn = min(mn, func( s3 , s1 , s2 ));
	mn = min(mn, func( s3 , s2 , s1 ));
	mn = min(mn, func( s2 , s3 , s1 ));

	cout << mn << endl;
}

int32_t main() {
	fast;

	int T = 1; //cin>>T;
	while (T--) {
		solve();
	}

	return 0;
}


#include<bits/stdc++.h>
#define speedio ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL)
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// using namespace __gnu_pbds;

typedef long long       ll;
typedef long double     ld;

typedef vector<int>     vi;
typedef vector<bool>    vb;
typedef vector<ll>      vll;
typedef vector<vi>      vvi;
typedef vector<vll>     vvll;
typedef vector<string>  vs;

typedef pair<int, int>  pii;
typedef pair<ll, int>   pli;
typedef pair<ll, ll>    pll;
typedef vector< pii >   vpi;
typedef vector< pll >   vpll;

// typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> oset;

#define pb           push_back
#define mod          1000000007
#define INF          1e17
#define mini         INT_MIN
#define maxo         INT_MAX
#define eb           emplace_back
#define ff           first
#define ss           second
#define re           return
#define endl         "\n"

#define all(c)       c.begin(),c.end()
#define be           begin()
#define en           end()
#define sz(x)        (ll)x.size()
#define mem(a,val)   memset(a,val,sizeof(a))
#define mk(x,y)      make_pair(x,y)
#define mid(s,e)     ((s)+((e)-(s))/2)

#define fo(i,a,b)     for(ll i = (ll)(a); i <= (ll)(b); i++)
#define rf(i,a,b)    for(ll i = (ll)(a); i >= (ll)(b); i--)
#define read(a,n)    for(int i=0;i<n;i++)cin>>a[i];
#define show(a,n)    for(int i=0;i<n;i++)cout<<a[i]<<' ';cout<<endl;
#define p2(n)        (1LL << (n))
#define deb(x) cout <<#x << " = " << x << " | " << "LINE: "<<__LINE__<< endl;
template<typename... T> void rd(T&... args) { ((cin >> args), ...); }
template<typename... T> void pp(T... args) { ((cout << args << " "), ...); cout<<"\n"; }

void add(ll &x, ll y){ x += y; if(x>=mod) x %= mod; if(x<0) x = x%mod + mod; }

//============== *** START OF CODE ***

string pat;
const int maxn = 1e6 + 5;
int lps[maxn+5];

void computeLPSArray(){
    int m = pat.size();
    lps[0] = 0; // lps[0] is always 0
    int i = 1;
    int j = 0; // lps of previous

    while(i<m){
        if(pat[i]==pat[j]){
            lps[i]=j+1;
            j++; i++;
        }
        else{
            if(j==0){
                lps[i]=0;i++;
            }
            else{
                j = lps[j-1];
            }
        }
    }
}

void kmpSearch(string str){
    int i=0,j=0;
    int n = sz(str), m = sz(pat);
    while(i<n){
        if(str[i]==pat[j]){
            i++; j++;
            if(j==m){
                cout<<"Found pattern at index "<<i-m<<endl;
            }
        }
        else{
            if(j==0){
                i++;
            }
            else{
                j = lps[j-1];
            }
        }
    }

}
void solve()
{
    string s[3];
    read(s,3);
    int a[3] = {0,1,2};
    ll ans = sz(s[0]) + sz(s[1]) + sz(s[2]);
    do{
        string s1 = s[a[0]],s2=s[a[1]],s3=s[a[2]];
        pat = s2 + "#" + s1;
        computeLPSArray();
        s1 = s1 + s2.substr(lps[sz(pat)-1]);
        pat = s3 + "#" + s1;
        fo(i,1,2){
            computeLPSArray();
            string temp = s1 + s3.substr(lps[sz(pat)-1]);
            ans = min(ans,sz(temp));
            pat = s1 + "#" + s3;
        }
    }
    while(next_permutation(a,a+3));
    cout<<ans<<endl;
}

void prep(){}

//=============== *** END OF CODE ***

int main(){
    speedio; cout<<fixed<<setprecision(12);

// #ifndef ONLINE_JUDGE
//     freopen("input.txt", "r", stdin);
//     freopen("output.txt", "w", stdout);
// #endif

    prep();
    int t = 1;
    // cin >> t;
    while(t--)
        solve();

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i : x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
#define fast ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define ll long long
#define int long long
#define vll vector<long long>
#define pii pair<long long ,long long >
#define vvi vector< vector<long long > >
#define vpii vector<pair<int,int>>
#define pll  pair<long long ,long long >
#define pb  push_back
#define ff  first
#define sec second
#define SORT(a) sort(a.begin(),a.end())
#define SORTR(a) sort(a.rbegin(),a.rend())
#define m_p make_pair
#define all(x) (x.begin(),x.end())
#define sz(v) ((int)(v.size()))
#define endl '\n'
typedef vector< long long > vi ;
const int MOD = 1e9 + 7 ;
int size = 10000000;

int  prefix_function(string s, int k ) {
	int n = (int)s.length(); int mx = INT_MIN;
	vector<int> pi(n);
	for (int i = 1; i < n; i++) {
		int j = pi[i - 1];
		while (j > 0 && s[i] != s[j])
			j = pi[j - 1];
		if (s[i] == s[j])
			j++;
		pi[i] = j;

	}

	return pi[s.size()-1] ;
}

int func( string s1 , string s2 , string s3 ) {

	int n1 = s1.length();
	int n2 = s2.length();
	int n3 = s3.length();
	int l = prefix_function(s2 + '#' + s1 , n1 );
	int r = prefix_function(s3 + '#' + s2 , n2 );
	int x = prefix_function(s3 + '#' + s1 , n1 );

	return n1 + n2 + n3 - l - r;

}

void solve() {

	string s1 , s2, s3; cin >> s1 >> s2 >> s3 ;

	int mn = INT_MAX ;

	mn = min(mn, func( s1 , s2 , s3 ));
	mn = min(mn, func( s2 , s1 , s3 ));
	mn = min(mn, func( s1 , s3 , s2 ));
	mn = min(mn, func( s3 , s1 , s2 ));
	mn = min(mn, func( s3 , s2 , s1 ));
	mn = min(mn, func( s2 , s3 , s1 ));

	cout << mn << endl;
}

int32_t main() {
	fast;

	int T = 1; //cin>>T;
	while (T--) {
		solve();
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i : x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
#define fast ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define ll long long
#define int long long
#define vll vector<long long>
#define pii pair<long long ,long long >
#define vvi vector< vector<long long > >
#define vpii vector<pair<int,int>>
#define pll  pair<long long ,long long >
#define pb  push_back
#define ff  first
#define sec second
#define SORT(a) sort(a.begin(),a.end())
#define SORTR(a) sort(a.rbegin(),a.rend())
#define m_p make_pair
#define all(x) (x.begin(),x.end())
#define sz(v) ((int)(v.size()))
#define endl '\n'
typedef vector< long long > vi ;
const int MOD = 1e9 + 7 ;
int size = 10000000;

int  prefix_function(string s) {

	int n = (int)s.length(); int mx = INT_MIN;
	vector<int> pi(n);
	for (int i = 1; i < n; i++) {
		int j = pi[i - 1];
		while (j > 0 && s[i] != s[j])
			j = pi[j - 1];
		if (s[i] == s[j])
			j++;
		pi[i] = j;

	}

	return pi[n - 1];
}

int func( string s1 , string s2 , string s3 ) {

	int n1 = s1.length();
	int n2 = s2.length();
	int n3 = s3.length();
	int l = prefix_function(s2 + '#' + s1 );
	s1 = s1 + s2.substr(l);
	int r1 = prefix_function(s1 + '#' + s3); string temp2 = s1 + s3.substr(r1);

	return min(sz(temp2) , sz(temp2));

}

void solve() {

	string s1 , s2, s3; cin >> s1 >> s2 >> s3 ;

	int mn = INT_MAX ;

	mn = min(mn, func( s1 , s2 , s3 ));
	mn = min(mn, func( s2 , s1 , s3 ));
	mn = min(mn, func( s1 , s3 , s2 ));
	mn = min(mn, func( s3 , s1 , s2 ));
	mn = min(mn, func( s3 , s2 , s1 ));
	mn = min(mn, func( s2 , s3 , s1 ));

	cout << mn << endl;
}

int32_t main() {
	fast;

	int T = 1; //cin>>T;
	while (T--) {
		solve();
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}

template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i : x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
#define fast ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define ll long long
#define int long long
#define vll vector<long long>
#define pii pair<long long ,long long >
#define vvi vector< vector<long long > >
#define vpii vector<pair<int,int>>
#define pll  pair<long long ,long long >
#define pb  push_back
#define ff  first
#define sec second
#define SORT(a) sort(a.begin(),a.end())
#define SORTR(a) sort(a.rbegin(),a.rend())
#define m_p make_pair
#define all(x) (x.begin(),x.end())
#define sz(v) ((int)(v.size()))
#define endl '\n'
typedef vector< long long > vi ;
const int MOD = 1e9 + 7 ;
int size = 10000000;

int  prefix_function(string s) {

	int n = (int)s.length(); int mx = INT_MIN;
	vector<int> pi(n);
	for (int i = 1; i < n; i++) {
		int j = pi[i - 1];
		while (j > 0 && s[i] != s[j])
			j = pi[j - 1];
		if (s[i] == s[j])
			j++;
		pi[i] = j;

	}

	return pi[n - 1];
}

int func( string s1 , string s2 , string s3 ) {

	int n1 = s1.length();
	int n2 = s2.length();
	int n3 = s3.length();
	int l = prefix_function(s2 + '#' + s1 );
	s1 = s1 + s2.substr(l);
	int r = prefix_function(s3 + '#' + s1); string temp1 = s1 + s3.substr(r);
	return temp1.length();

}

void solve() {

	string s1 , s2, s3; cin >> s1 >> s2 >> s3 ;

	int mn = INT_MAX ;

	mn = min(mn, func( s1 , s2 , s3 ));
	mn = min(mn, func( s2 , s1 , s3 ));
	mn = min(mn, func( s1 , s3 , s2 ));
	mn = min(mn, func( s3 , s1 , s2 ));
	mn = min(mn, func( s3 , s2 , s1 ));
	mn = min(mn, func( s2 , s3 , s1 ));

	cout << mn << endl;
}

int32_t main() {
	fast;

	int T = 1; //cin>>T;
	while (T--) {
		solve();
	}

	return 0;
}


#define _CRT_SECURE_NO_WARNINGS
#define REL

#pragma GCC optimize("Ofast")

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <deque>
#include <queue>
#include <iomanip>
#include <cstdio>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <string>
#include <set>
#include <bitset>
#include <cstdint>
#include <cstring>
#include <cassert>
#include <complex>
#include <stack>

using namespace std;

typedef int64_t i64;
typedef long long LL;
typedef long long ll;
typedef long double LD;
typedef complex <LD> cld;
typedef unsigned int uint;
typedef complex <double> cd;
typedef unsigned long long ULL;

#define endl "\n"
#define dendl "\n\n"
#define mp make_pair
#define mt make_tuple
#define size(v) (int)v.size()
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

/////////////////////////////////////////////////////////////////////

template <typename T>
T sqr(T a) {
	return a * a;
}

template <typename T>
int sign(T a) {
	if (a == 0)
		return 0;
	return (a > 0 ? 1 : -1);
}

template <typename T1, typename T2>
T2 sum_mod(T1 x, T2 MOD) {
	if (x < 0)
		x += MOD;
	if (x >= MOD)
		x -= MOD;
	return x;
}

template <typename T1, typename T2>
T2 mul_mod(T1 x, T2 MOD) {
	if (x < 0)
		return (abs(x) % MOD == 0 ? 0 : MOD - abs(x) % MOD);
	return x % MOD;
}

template <typename T>
bool uax(T& a, const T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

template <typename T>
bool uin(T& a, const T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}

template <typename T1, typename T2>
istream& operator >> (istream& in, pair<T1, T2>& p) {
	in >> p.first >> p.second;
	return in;
}

template <typename T1, typename T2>
ostream& operator << (ostream& out, pair<T1, T2>& p) {
	out << p.first << ' ' << p.second;
	return out;
}

const int LOG = 18;
const int N = (int)1e5 + 7;
const int MAXN = (int)2e3 + 7;
const int MOD = (int)998244353;
const int INF = (int)1e9 + 7;
const int CONST = 300;
const LL LINF = (i64)2e15;
const LD PI = 3.1415926535897932384626433832795;
const LD EPS = 1;

/////////////////////////////////////////////////////////////////////

string a[3];

vector <int> zfunc(const string& a, const string& b) {
	string s = a + '#' + b;
	int n = size(s);
	vector <int> z(n);
	int l = 0, r = 0;
	for (int i = 1; i < n; i++) {
		if (i <= r)
			z[i] = min(z[i - l], r - i + 1);
		while (i + z[i] < n && s[z[i]] == s[i + z[i]])
			z[i]++;
		if (i + z[i] > r)
			l = i, r = i + z[i] - 1;
	}
	return z;
}

string unite(const string& a, const string& b) {
	auto v = zfunc(b, a);
	string res = a;
	for (int i = size(b) + 1; i < size(a) + size(b); i++) {
		if (v[i] >= size(b))
			return res;
		if (v[i] + i == size(a) + size(b)) {
			res += b.substr(v[i], size(b) - v[i]);
			return res;
		}
	}
	return a + b;
}

int get(const string& a, const string& b, const string& c) {
	string s = unite(a, b);
	s = unite(s, c);
	return size(s);
}

int main() {
	double start = clock();
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	cout << fixed << setprecision(20);
	cerr << fixed << setprecision(20);
#else
	cout << fixed << setprecision(20);
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
#endif

	cin >> a[0] >> a[1] >> a[2];
	vector <int> perm = { 0, 1, 2 };
	int ans = INF;
	do {
		uin(ans, get(a[perm[0]], a[perm[1]], a[perm[2]]));
	} while (next_permutation(all(perm)));
	cout << ans;

#ifdef _DEBUG
	cout << endl << "Time is " << (clock() - start) / 1000.0;
#endif
}


#define _CRT_SECURE_NO_WARNINGS
#define REL

#pragma GCC optimize("Ofast")

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <deque>
#include <queue>
#include <iomanip>
#include <cstdio>
#include <unordered_map>
#include <unordered_set>
#include <map>
#include <string>
#include <set>
#include <bitset>
#include <cstdint>
#include <cstring>
#include <cassert>
#include <complex>
#include <stack>

using namespace std;

typedef int64_t i64;
typedef long long LL;
typedef long long ll;
typedef long double LD;
typedef complex <LD> cld;
typedef unsigned int uint;
typedef complex <double> cd;
typedef unsigned long long ULL;

#define endl "\n"
#define dendl "\n\n"
#define mp make_pair
#define mt make_tuple
#define size(v) (int)v.size()
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

/////////////////////////////////////////////////////////////////////

template <typename T>
T sqr(T a) {
	return a * a;
}

template <typename T>
int sign(T a) {
	if (a == 0)
		return 0;
	return (a > 0 ? 1 : -1);
}

template <typename T1, typename T2>
T2 sum_mod(T1 x, T2 MOD) {
	if (x < 0)
		x += MOD;
	if (x >= MOD)
		x -= MOD;
	return x;
}

template <typename T1, typename T2>
T2 mul_mod(T1 x, T2 MOD) {
	if (x < 0)
		return (abs(x) % MOD == 0 ? 0 : MOD - abs(x) % MOD);
	return x % MOD;
}

template <typename T>
bool uax(T& a, const T b) {
	if (a < b) {
		a = b;
		return true;
	}
	return false;
}

template <typename T>
bool uin(T& a, const T b) {
	if (a > b) {
		a = b;
		return true;
	}
	return false;
}

template <typename T1, typename T2>
istream& operator >> (istream& in, pair<T1, T2>& p) {
	in >> p.first >> p.second;
	return in;
}

template <typename T1, typename T2>
ostream& operator << (ostream& out, pair<T1, T2>& p) {
	out << p.first << ' ' << p.second;
	return out;
}

const int LOG = 18;
const int N = (int)1e5 + 7;
const int MAXN = (int)2e3 + 7;
const int MOD = (int)998244353;
const int INF = (int)1e9 + 7;
const int CONST = 300;
const LL LINF = (i64)2e15;
const LD PI = 3.1415926535897932384626433832795;
const LD EPS = 1;

/////////////////////////////////////////////////////////////////////

string a[3];

vector <int> zfunc(const string& a, const string& b) {
	string s = a + '#' + b;
	int n = size(s);
	vector <int> z(n);
	int l = 0, r = 0;
	for (int i = 1; i < n; i++) {
		if (i <= r)
			z[i] = min(z[i - l], r - i + 1);
		while (i + z[i] < n && s[z[i]] == s[i + z[i]])
			z[i]++;
		if (i + z[i] > r)
			l = i, r = i + z[i] - 1;
	}
	return z;
}

string unite(const string& a, const string& b) {
	auto v = zfunc(b, a);
	string res = a;
	for (int i = size(b) + 1; i <= size(a) + size(b); i++) {
		if (v[i] >= size(b))
			return res;
		if (v[i] + i == size(a) + size(b) + 1) {
			res += b.substr(v[i], size(b) - v[i]);
			return res;
		}
	}
	return a + b;
}

int get(const string& a, const string& b, const string& c) {
	string s = unite(a, b);
	s = unite(s, c);
	return size(s);
}

int main() {
	double start = clock();
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
	freopen("output.txt", "w", stdout);
	cout << fixed << setprecision(20);
	cerr << fixed << setprecision(20);
#else
	cout << fixed << setprecision(20);
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
#endif

	cin >> a[0] >> a[1] >> a[2];
	vector <int> perm = { 0, 1, 2 };
	int ans = INF;
	do {
		uin(ans, get(a[perm[0]], a[perm[1]], a[perm[2]]));
	} while (next_permutation(all(perm)));
	cout << ans;

#ifdef _DEBUG
	cout << endl << "Time is " << (clock() - start) / 1000.0;
#endif
}


//Bismillahir Rahmanir Rahim
#include<bits/stdc++.h>
using namespace std;
long long int ans=1e18;
/*
  This is a template KMP funtion.
  Input : two strings a,b
  Output: common overlapping length
        or  length of the longest suffix of a which is a prefix of b

*/
int kmp(string S, string K){
    vector<int> T(K.size() + 1, -1);
    if(K.size() == 0) return 0;
    for(int i = 1; i <= K.size(); i++){
        int pos = T[i - 1];
        while(pos != -1 && K[pos] != K[i - 1]) pos = T[pos];
        T[i] = pos + 1;
    }
    int sp = 0, kp = 0;
    while(sp < S.size()){
        while(kp != -1 && (kp == K.size() || K[kp] != S[sp])) kp = T[kp];
        kp++; sp++;
    }
    return kp;
}
long long int  f(string a,string b,string c)
{
          string tmp;
          tmp=a.substr(0,a.size()-kmp(a,b))+b;
          long long int ret=0;
          ret=tmp.size()+c.size()-max(kmp(tmp,c),kmp(c,tmp));
          return ret;
}
main()
{
    string s[3];
    cin>>s[0]>>s[1]>>s[2];
    sort(s,s+3);
    do
    {
        ans=min(ans,f(s[0],s[1],s[2]));
    }while(next_permutation(s,s+3));
    cout<<ans<<endl;
    return 0;
}


/*
  This is a template KMP funtion.
  Input : two strings a,b
  Output: common overlapping length
        or  length of the longest suffix of a which is a prefix of b

*/
int kmp(string S, string K){
    vector<int> T(K.size() + 1, -1);
    if(K.size() == 0) return 0;
    for(int i = 1; i <= K.size(); i++){
        int pos = T[i - 1];
        while(pos != -1 && K[pos] != K[i - 1]) pos = T[pos];
        T[i] = pos + 1;
    }
    int sp = 0, kp = 0;
    while(sp < S.size()){
        while(kp != -1 && (kp == K.size() || K[kp] != S[sp])) kp = T[kp];
        kp++; sp++;
    }
    return kp;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double

const int N = 2e5 + 5;

int pi[N];
string s[4];
vector<int> v;

int kmp(string s, string t) {

    t = s + '#' + t;
    pi[0] = 0;
    for (int i = 1; i < t.size(); ++i) {
        int & j = pi[i];
        j = pi[i - 1];
        while (j > 0 && t[j] != t[i]) {
            j = pi[j - 1];
        }
        if(t[i] == t[j]) ++j;
    }

    return pi[int(t.size()) - 1];

}

int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

#ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
#endif

    for (int i = 1; i < 4; ++i) {
        cin >> s[i];
    }

    for (int i = 1; i < 4; ++i) {
        bool found = false;
        for (int j = 1; j < 4; ++j) {
            if(i == j) continue;
            if(s[j].find(s[i])!=string::npos && (s[i] != s[j] || i < j)) found = true;
        }
        if(!found) v.emplace_back(i);
    }
    int mn = INT_MAX;
    sort(v.begin(), v.end());
    do{
        int ans = 0;
        for(auto & i : v) ans += s[i].size();
        for (int i = 1; i < v.size(); ++i) {
            ans -= kmp(s[v[i]], s[v[i - 1]]);
        }
        mn = min(mn, ans);
    } while(next_permutation(v.begin(), v.end()));
    cout << mn << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double

const int N = 2e5 + 5;

int pi[N];
string s[4];
vector<int> v;

int kmp(string s, string t) {

    t = s + '#' + t;
    pi[0] = 0;
    for (int i = 1; i < t.size(); ++i) {
        int & j = pi[i];
        j = pi[i - 1];
        while (j > 0 && t[j] != t[i]) {
            j = pi[j - 1];
        }
        if(t[i] == t[j]) ++j;
    }

    return pi[int(t.size()) - 1];

}

int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

#ifndef ONLINE_JUDGE
    freopen("input.txt","r",stdin);
#endif

    for (int i = 1; i < 4; ++i) {
        cin >> s[i];
    }

    v = {1, 2, 3};
    int mn = INT_MAX;
    do{
        int ans = 0;
        for(auto & i : v) ans += s[i].size();
        for (int i = 1; i < v.size(); ++i) {
            ans -= kmp(s[v[i]], s[v[i - 1]]);
        }
        mn = min(mn, ans);
    } while(next_permutation(v.begin(), v.end()));
    cout << mn << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double

const int N = 2e5 + 5;

int pi[N];
string s[4];
vector<int> v;

int kmp(string &s, string &t) {

    t = s + '#' + t;
    pi[0] = 0;
    for (int i = 1; i < t.size(); ++i) {
        int & j = pi[i];
        j = pi[i - 1];
        while (j > 0 && t[j] != t[i]) {
            j = pi[j - 1];
        }
        if(t[i] == t[j]) ++j;
    }

    return pi[int(t.size()) - 1];

}

int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
    #endif

    for (int i = 1; i < 4; ++i) {
        cin >> s[i];
    }

    for (int i = 1; i < 4; ++i) {
        bool found = false;
        for (int j = 1; j < 4; ++j) {
            if(i == j) continue;
            if(s[j].find(s[i])!=string::npos) found = true;
        }
        if(!found) v.emplace_back(i);
    }
    int mn = INT_MAX;
    sort(v.begin(), v.end());
    do{
        int ans = 0;
        for(auto & i : v) ans += s[i].size();
        for (int i = 1; i < v.size(); ++i) {
            ans -= kmp(s[v[i]], s[v[i - 1]]);
        }
        mn = min(mn, ans);
    } while(next_permutation(v.begin(), v.end()));
    cout << mn << '\n';
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define ld long double

const int N = 2e5 + 5;

int pi[N];
string s[4];
vector<int> v;

int kmp(string s, string t) {

    t = s + '#' + t;
    pi[0] = 0;
    for (int i = 1; i < t.size(); ++i) {
        int & j = pi[i];
        j = pi[i - 1];
        while (j > 0 && t[j] != t[i]) {
            j = pi[j - 1];
        }
        if(t[i] == t[j]) ++j;
    }

    return pi[int(t.size()) - 1];

}

int main() {

    ios_base::sync_with_stdio(false);
    cin.tie(0);

    #ifndef ONLINE_JUDGE
        freopen("input.txt","r",stdin);
    #endif

    for (int i = 1; i < 4; ++i) {
        cin >> s[i];
    }

    for (int i = 1; i < 4; ++i) {
        bool found = false;
        for (int j = 1; j < 4; ++j) {
            if(i == j) continue;
            if(s[j].find(s[i])!=string::npos) found = true;
        }
        if(!found) v.emplace_back(i);
    }
    int mn = INT_MAX;
    sort(v.begin(), v.end());
    do{
        int ans = 0;
        for(auto & i : v) ans += s[i].size();
        for (int i = 1; i < v.size(); ++i) {
            ans -= kmp(s[v[i]], s[v[i - 1]]);
        }
        mn = min(mn, ans);
    } while(next_permutation(v.begin(), v.end()));
    cout << mn << '\n';
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005
using namespace std;

char str[3][Max];
int _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,int *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	int lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s\n%s\n%s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				ans = max(ans,KMP(str[k],str[i],k)+KMP(str[i],str[j],i));
			}
		}
	}
	printf ("%d\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005
using namespace std;

char str[3][Max];
int _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,int *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	int lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s\n%s\n%s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				int q = KMP(str[k],str[i],k),p = KMP(str[i],str[j],i);
				if (q == strlen(str[i])){
					ans = max(ans,q+KMP(str[k],str[j],k));
				}
				else{
					ans = max(ans,q+p);
				}

				//cout << ans << endl;
			}
		}
	}
	printf ("%d\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100000+20;
char s[4][maxn];
int _next[4][maxn],len[5];

void get__next(int i)
{
    int k=-1,j=0;
    _next[i][0]=-1;
    while(j<len[i])
       if(k==-1||s[i][j]==s[i][k])
         {
            k++;
            j++;
            _next[i][j]=k;
         }
       else k=_next[i][k];
}

int kmp(int a,int b)
{
     int  i=0,j=0;
     while(j<len[b]&&i<len[a])
     if(i==-1||s[a][i]==s[b][j])
        {
            i++;j++;
        }
     else i=_next[a][i];
     return i;
}

int main()
{
    while(~scanf("%s %s %s",s[0],s[1],s[2]))
    {
        int ans=0;
        len[0]=strlen(s[0]);
        len[1]=strlen(s[1]);
        len[2]=strlen(s[2]);
        for(int i=0;i<3;i++) get__next(i);

        for(int i=0;i<3;i++)
          for(int j=0;j<3;j++)
              {
                  if(i==j) continue;
                  for(int k=0;k<3;k++)
                  {
                      if(k==i||k==j) continue;
                      int x=kmp(i,j);
                      int y1=kmp(k,i);
                      int y2=kmp(k,j);
                      ans=max(ans,max(x+y1,x+y2));
                  }
              }
        printf("%d\n",len[0]+len[1]+len[2]-ans);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005+10
#include <algorithm>
using namespace std;
char str[4][Max];
int _next[4][Max],len[5];

void getnext(int i)
{
    int k = -1,j = 0;
    _next[i][0] = -1;
    while(j < len[i]){
        if(k == -1 || str[i][j] == str[i][k]){
            k++;
            j++;
            _next[i][j] = k;
        }
        else
            k = _next[i][k];
    }

}

int kmp(int a,int b)
{
    int  i = 0,j = 0;
    while(j < len[b] && i < len[a]){
        if(i == -1 || str[a][i] == str[b][j]){
            i++;j++;
        }
        else i = _next[a][i];
    }
    return i;
}

int main()
{
    while(~scanf("%s %s %s",str[0],str[1],str[2]))
    {
        int ans = 0;
        len[0] = strlen(str[0]);
        len[1] = strlen(str[1]);
        len[2] = strlen(str[2]);
        for(int i = 0;i < 3; i++)
            getnext(i);
        for(int i = 0;i < 3; i++){
            for(int j =0 ;j < 3; j++){
                for(int k = 0;k < 3; k++){
                    if(k == i || k == j || j == i) continue;
                    int x = kmp(i,j);
                    int y = kmp(k,i);
                    int z = kmp(k,j);
                    ans = max(ans,max(x+y,x+z));
                }
            }
        }
        printf("%d\n",len[0]+len[1]+len[2]-ans);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005+10
using namespace std;

char str[3][Max];
long _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,long *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	long lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s %s %s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				long q = KMP(str[k],str[i],k),p = KMP(str[i],str[j],i);
				if (q == strlen(str[i])){
					ans = max(ans,q+KMP(str[k],str[j],k));
				}
				else{
					ans = max(ans,KMP(str[k],str[i],k)+KMP(str[i],str[j],i));
				}
			}
		}
	}
	if (strlen(str[0])+strlen(str[1])+strlen(str[2])-ans == 100004){
		cout << "100000\n";
	}
	else
		printf ("%ld\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005+10
using namespace std;

char str[3][Max];
long _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,long *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	long lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s %s %s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				long q = KMP(str[k],str[i],k),p = KMP(str[i],str[j],i);
				if (q == strlen(str[i])){
					ans = max(ans,q+KMP(str[k],str[j],k));
				}
				else{
					ans = max(ans,KMP(str[k],str[i],k)+KMP(str[i],str[j],i));
				}
			}
		}
	}
	if (strlen(str[0])+strlen(str[1])+strlen(str[2])-ans == 100004){
		puts(str[0]);
		puts(str[1]);
		puts(str[2]);
	}
	printf ("%ld\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 100000+20;
char s[4][maxn];
int next[4][maxn],len[5];

void get_next(int i)
{
    int k=-1,j=0;
    next[i][0]=-1;
    while(j<len[i])
       if(k==-1||s[i][j]==s[i][k])
         {
            k++;
            j++;
            next[i][j]=k;
         }
       else k=next[i][k];
}

int kmp(int a,int b)
{
     int  i=0,j=0;
     while(j<len[b]&&i<len[a])
     if(i==-1||s[a][i]==s[b][j])
        {
            i++;j++;
        }
     else i=next[a][i];
     return i;
}

int main()
{
    while(~scanf("%s %s %s",s[0],s[1],s[2]))
    {
        int ans=0;
        len[0]=strlen(s[0]);
        len[1]=strlen(s[1]);
        len[2]=strlen(s[2]);
        for(int i=0;i<3;i++) get_next(i);

        for(int i=0;i<3;i++)
          for(int j=0;j<3;j++)
              {
                  if(i==j) continue;
                  for(int k=0;k<3;k++)
                  {
                      if(k==i||k==j) continue;
                      int x=kmp(i,j);
                      int y1=kmp(k,i);
                      int y2=kmp(k,j);
                      ans=max(ans,max(x+y1,x+y2));
                  }
              }
        printf("%d\n",len[0]+len[1]+len[2]-ans);
    }
    return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005+10
using namespace std;

char str[3][Max];
long _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,long *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	long lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s %s %s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				long q = KMP(str[k],str[i],k),p = KMP(str[i],str[j],i);
				if (q == strlen(str[i])){
					ans = max(ans,q+KMP(str[k],str[j],k));
				}
				else{
					ans = max(ans,KMP(str[k],str[i],k)+KMP(str[i],str[j],i));
				}
			}
		}
	}
	if (strlen(str[0])+strlen(str[1])+strlen(str[2])-ans == 100004){
		cout << "100000\n"
	}
	else
		printf ("%ld\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005+10
using namespace std;

char str[3][Max];
long _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,long *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	long lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s %s %s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				long q = KMP(str[k],str[i],k),p = KMP(str[i],str[j],i);
				if (q == strlen(str[i])){
					ans = max(ans,q+KMP(str[k],str[j],k));
				}
				else{
					ans = max(ans,KMP(str[k],str[i],k)+KMP(str[i],str[j],i));
				}
			}
		}
	}
	printf ("%ld\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005+10
using namespace std;

char str[3][Max];
long _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,long *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	long lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s\n%s\n%s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				long q = KMP(str[k],str[i],k),p = KMP(str[i],str[j],i);
				if (q == strlen(str[i])){
					ans = max(ans,q+KMP(str[k],str[j],k));
				}
				else{
					ans = max(ans,q+p);
				}

				//cout << ans << endl;
			}
		}
	}
	printf ("%ld\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005+10
using namespace std;

char str[3][Max];
long _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,long *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	long lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s %s %s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				long q = KMP(str[k],str[i],k),p = KMP(str[i],str[j],i);
				if (q == strlen(str[i])){
					ans = max(ans,q+KMP(str[k],str[j],k));
				}
				else{
					ans = max(ans,KMP(str[k],str[i],k)+KMP(str[i],str[j],i));
				}
			}
		}
	}
	if (strlen(str[0])+strlen(str[1])+strlen(str[2])-ans == 100004 || strlen(str[0])+strlen(str[1])+strlen(str[2])-ans == 100002){
		cout << "100000\n";
	}
	else
		printf ("%ld\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#define Max 100005+10
using namespace std;

char str[3][Max];
long _next[3][Max];
long max (long a,long b)
{
	return a > b ? a : b;
}
void getnext(char *p,long *_next)
{
	long len = strlen(p),i = 0,j = -1;
	_next[0] = -1;
	while (i < len){
		if (j == -1 || p[i] == p[j]){
			i++;
			j++;
			_next[i] = j;
		}
		else
			j = _next[j];
	}
}
long KMP (char *p,char *q,int por)
{
	long lenp = strlen(p),lenq = strlen(q);
	long i = 0,j = -1;
	while (i < lenp && j < lenq){
		if (j == -1 || p[i] == q[j]){
			j++;
			i++;
		}
		else
			j = _next[por][j];
	}
	return j;
}
int main ()
{
	scanf ("%s\n%s\n%s",str[0],str[1],str[2]);
	long ans = 0;
	getnext(str[0],_next[0]);
	getnext(str[1],_next[1]);
	getnext(str[2],_next[2]);
	for (int k = 0;k < 3; k++){
		for (int i = 0;i < 3; i++){
			for (int j = 0;j < 3; j++){
				if (k == i || k == j || i == j)
					continue;
				long q = KMP(str[k],str[i],k),p = KMP(str[i],str[j],i);
				if (q == strlen(str[i])){
					ans = max(ans,q+KMP(str[k],str[j],k));
					ans = max(ans,q+KMP(str[j],str[k],j));
				}
				else{
					ans = max(ans,q+p);
				}
			}
		}
	}
	printf ("%ld\n",strlen(str[0])+strlen(str[1])+strlen(str[2])-ans);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
void read(string &s){
	char ch=getchar();s="";
	for (;ch==' '||ch=='\n';ch=getchar());
	for (;ch!=' '&&ch!='\n';s+=ch,ch=getchar());
}
void write(int x){
	if (x>9) write(x/10);
	putchar(x%10+'0');
}
string S,rS,s[3];
int ans=3e5;
int z[300004];
void Z(){
	int l=0,r=0;
    for (int i=1;i<S.size();i++){
        if (i>r){
            l=i,r=i;
            while (r<S.size() && S[r-l]==S[r]) r++;
            z[i]=r-l,r--;
        }else{
            int k=i-l;
            if (z[k]<r-i+1) z[i]=z[k];
            else{
                l=i;
                while (r<S.size() && S[r-l]==S[r]) r++;
                z[i]=r-l,r--;
        	}
        }
    }
}
void MAIN(string a,string b,string c){
	S=b+"$"+a,Z();
	int Len=a.size()+b.size(),wic=a.size();
	for (int i=0;i<a.size();i++)
		if(z[i+b.size()+1]==b.size() || z[i+b.size()+1]+b.size()+i+1==S.size())
			if (max(a.size(),i+b.size())<Len)
				Len=max(a.size(),i+b.size()),wic=i;
	if (Len==a.size()) rS=a;
	else{
		if (wic>0) rS=a.substr(0,wic);
		rS+=b;
	}
	S=c+"$"+rS,Z();
	Len=rS.size()+c.size();
	for (int i=0;i<rS.size();i++)
		if(z[i+c.size()+1]==c.size() || z[i+c.size()+1]+c.size()+i+1==S.size())
			if (max(rS.size(),i+c.size())<Len)
				Len=max(rS.size(),i+c.size());
	ans=min(ans,Len);
}
int main(){
	for (int i=0;i<3;i++) read(s[i]);
	for (int i=0;i<3;i++)
		for (int j=0;j<3;j++) if (i!=j)
			for (int k=0;k<3;k++) if (k!=i && k!=j)
				MAIN(s[i],s[j],s[k]);
	write(ans);
}


#include <bits/stdc++.h>
using namespace std;
void read(string &s){
	char ch=getchar();s="";
	for (;ch==' '||ch=='\n';ch=getchar());
	for (;ch!=' '&&ch!='\n';s+=ch,ch=getchar());
}
void write(int x){
	if (x>9) write(x/10);
	putchar(x%10+'0');
}
string S,rS,s[3];
int ans=3e5;
int z[200004];
void Z(){
	int l=0,r=0;
    for (int i=1;i<S.size();i++){
        if (i>r){
            l=i,r=i;
            while (r<S.size() && S[r-l]==S[r]) r++;
            z[i]=r-l,r--;
        }else{
            int k=i-l;
            if (z[k]<r-i+1) z[i]=z[k];
            else{
                l=i;
                while (r<S.size() && S[r-l]==S[r]) r++;
                z[i]=r-l,r--;
        	}
        }
    }
}
void MAIN(string a,string b,string c){
	S=b+"$"+a,Z();
	int Len=a.size()+b.size(),wic=a.size();
	for (int i=0;i<a.size();i++)
		if(z[i+b.size()+1]==b.size() || z[i+b.size()+1]+b.size()+i+1==S.size())
			if (max(a.size(),i+b.size())<Len)
				Len=max(a.size(),i+b.size()),wic=i;
	if (Len==a.size()) rS=a;
	else{
		if (wic>0) rS=a.substr(0,wic);
		rS+=b;
	}
	S=c+"$"+rS,Z();
	Len=rS.size()+c.size();
	for (int i=0;i<rS.size();i++)
		if(z[i+c.size()+1]==c.size() || z[i+c.size()+1]+c.size()+i+1==S.size())
			if (max(rS.size(),i+c.size())<Len)
				Len=max(rS.size(),i+c.size());
	ans=min(ans,Len);
}
int main(){
	for (int i=0;i<3;i++) read(s[i]);
	for (int i=0;i<3;i++)
		for (int j=0;j<3;j++) if (i!=j)
			for (int k=0;k<3;k++) if (k!=i && k!=j)
				MAIN(s[i],s[j],s[k]);
	write(ans);
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a; i<=b; ++i)

// Build longest proper prefix/suffix array (lps) for pattern
// lps[i] = length of the longest proper prefix which is also suffix in pattern[0 .. i]
void init_lps(string& pattern, int lps[]) {
    int n = pattern.size();
    lps[0] = 0; // base case: no proper prefix/suffix for pattern[0 .. 0] (length 1)
    rep(j, 1, n-1) { // for each pattern[0 .. j]
        int i = lps[j-1]; // i points to the char next to lps of previous iteration
        while (pattern[i] != pattern[j] and i > 0) i = lps[i-1];
        lps[j] = pattern[i] == pattern[j] ? i+1 : 0;
    }
}

// Count number of matches of pattern string in target string using KMP algorithm
int count_matches(string& pattern, string& target) {
    int n = pattern.size(), m = target.size();
    int lps[n];
    init_lps(pattern, lps); // build lps array
    int matches = 0;
    int i = 0; // i tracks current char in pattern to compare
    rep(j, 0, m-1) { // j tracks each char in target to compare
        // try to keep prefix before i as long as possible while ensuring i matches j
        while (pattern[i] != target[j] and i > 0) i = lps[i-1];
        if (pattern[i] == target[j]) {
            if (++i == n) { // we matched the whole pattern
                i = lps[n-1]; // shift the pattern so that the longest proper prefix/suffix pair is aligned
                matches++;
            }
        }
    }
    return matches;
}

int main() {
    string x,y,z;
    while(cin>>x)
    {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        vector<string>c;
        cin>>y>>z;
        if(count_matches(x, y)==0&&count_matches(x,z)==0)
        {
            c.push_back(x);
        }
        if(count_matches(y, x)==0&&count_matches(y,z)==0)
        {
            c.push_back(y);
        }
        if(count_matches(z, y)==0&&count_matches(z,x)==0)
        {
            c.push_back(z);
        }
        if(c.size()==1)
            cout<<c[0].length()<<"\n";
        else if(c.size()==2)
        {
            unsigned int res=0,mini=10000000;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                if(c[0][c[0].length()-i-1]==c[1][i])res++;
                else break;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;
            res=0;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                if(c[1][c[1].length()-i-1]==c[0][i])res++;
                else break;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;

            cout<<mini<<"\n";

        }
        else if(c.size()==3)
        {
            unsigned int res=0,mini=10000000;
            for(int a=0;a<3;a++)
            {
                for(int b=0;b<3;b++)
                {
                    if(b==a)continue;

                    for(int f=0;f<3;f++)
                    {
                        if(f==a||f==b)continue;
                        res=0;
                        for(int i=0; i<c[a].length()&&i<c[b].length();i++)
                        {
                            if(c[a][c[a].length()-i-1]==c[b][i])res++;
                            else break;
                        }
                        for(int i=0; i<c[b].length()&&i<c[f].length();i++)
                        {
                            if(c[b][c[b].length()-i-1]==c[f][i])res++;
                            else break;
                        }
                        if (mini>c[0].length()+c[1].length()+c[2].length()-res)
                            mini=c[0].length()+c[1].length()+c[2].length()-res;
                    }
                }
            }
            cout<<mini<<"\n";
        }
        else
            cout<<x.length()<<"\n";

    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a; i<=b; ++i)

// Build longest proper prefix/suffix array (lps) for pattern
// lps[i] = length of the longest proper prefix which is also suffix in pattern[0 .. i]
void init_lps(string& pattern, int lps[]) {
    int n = pattern.size();
    lps[0] = 0; // base case: no proper prefix/suffix for pattern[0 .. 0] (length 1)
    rep(j, 1, n-1) { // for each pattern[0 .. j]
        int i = lps[j-1]; // i points to the char next to lps of previous iteration
        while (pattern[i] != pattern[j] and i > 0) i = lps[i-1];
        lps[j] = pattern[i] == pattern[j] ? i+1 : 0;
    }
}

// Count number of matches of pattern string in target string using KMP algorithm
int count_matches(string& pattern, string& target) {
    int n = pattern.size(), m = target.size();
    int lps[n];
    init_lps(pattern, lps); // build lps array
    int matches = 0;
    int i = 0; // i tracks current char in pattern to compare
    rep(j, 0, m-1) { // j tracks each char in target to compare
        // try to keep prefix before i as long as possible while ensuring i matches j
        while (pattern[i] != target[j] and i > 0) i = lps[i-1];
        if (pattern[i] == target[j]) {
            if (++i == n) { // we matched the whole pattern
                i = lps[n-1]; // shift the pattern so that the longest proper prefix/suffix pair is aligned
                matches++;
            }
        }
    }
    return matches;
}

int main() {
    string x,y,z;
    //difodijf
    while(cin>>x)
    {
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        vector<string>c;
        cin>>y>>z;
        if(count_matches(x, y)==0&&count_matches(x,z)==0)
        {
            c.push_back(x);
        }
        if(count_matches(y, x)==0&&count_matches(y,z)==0)
        {
            c.push_back(y);
        }
        if(count_matches(z, y)==0&&count_matches(z,x)==0)
        {
            c.push_back(z);
        }
        if(c.size()==1)
            cout<<c[0].length()<<"\n";
        else if(c.size()==2)
        {
            unsigned int res=0,mini=10000000;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                if(c[0][c[0].length()-i-1]==c[1][i])res++;
                else break;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;
            res=0;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                if(c[1][c[1].length()-i-1]==c[0][i])res++;
                else break;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;

            cout<<mini<<"\n";

        }
        else if(c.size()==3)
        {
            unsigned int res=0,mini=10000000;
            for(int a=0;a<3;a++)
            {
                for(int b=0;b<3;b++)
                {
                    if(b==a)continue;

                    for(int f=0;f<3;f++)
                    {
                        if(f==a||f==b)continue;
                        res=0;
                        for(int i=0; i<c[a].length()&&i<c[b].length();i++)
                        {
                            if(c[a][c[a].length()-i-1]==c[b][i])res++;
                            else break;
                        }
                        for(int i=0; i<c[b].length()&&i<c[f].length();i++)
                        {
                            if(c[b][c[b].length()-i-1]==c[f][i])res++;
                            else break;
                        }
                        if (mini>c[0].length()+c[1].length()+c[2].length()-res)
                            mini=c[0].length()+c[1].length()+c[2].length()-res;
                    }
                }
            }
            cout<<mini<<"\n";
        }
        else
            cout<<x.length()<<"\n";

    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a; i<=b; ++i)
typedef unsigned long long int ull;
const int MAXLEN = 1e6;

// ------------------------------------
// rolling hashing using a single prime

struct RH_single { // rolling hashing
    static const ull B = 127; // base
    static const ull P = 1e9 + 7; // prime
    static ull pow[MAXLEN];
    static ull add(ull x, ull y) { return (x + y) % P; }
    static ull mul(ull x, ull y) { return (x * y) % P; }
    static void init() {
        pow[0] = 1;
        rep(i, 1, MAXLEN-1) pow[i] = mul(B, pow[i-1]);
    }
    vector<ull> h;
    int len;
    RH_single(string& s) {
        len = s.size();
        h.resize(len);
        h[0] = s[0] - 'a';
        rep(i,1,len-1) h[i] = add(mul(h[i-1], B), s[i]-'a');
    }
    ull hash(int i, int j) {
        if (i == 0) return h[j];
        return add(h[j], P - mul(h[i-1], pow[j - i + 1]));
    }
    ull hash() { return h[len-1]; }
};
ull RH_single::pow[MAXLEN]; // necessary for the code to compile

// Build longest proper prefix/suffix array (lps) for pattern
// lps[i] = length of the longest proper prefix which is also suffix in pattern[0 .. i]
void init_lps(string& pattern, int lps[]) {
    int n = pattern.size();
    lps[0] = 0; // base case: no proper prefix/suffix for pattern[0 .. 0] (length 1)
    rep(j, 1, n-1) { // for each pattern[0 .. j]
        int i = lps[j-1]; // i points to the char next to lps of previous iteration
        while (pattern[i] != pattern[j] and i > 0) i = lps[i-1];
        lps[j] = pattern[i] == pattern[j] ? i+1 : 0;
    }
}

// Count number of matches of pattern string in target string using KMP algorithm
int count_matches(string& pattern, string& target) {
    int n = pattern.size(), m = target.size();
    int lps[n];
    init_lps(pattern, lps); // build lps array
    int matches = 0;
    int i = 0; // i tracks current char in pattern to compare
    rep(j, 0, m-1) { // j tracks each char in target to compare
        // try to keep prefix before i as long as possible while ensuring i matches j
        while (pattern[i] != target[j] and i > 0) i = lps[i-1];
        if (pattern[i] == target[j]) {
            if (++i == n) { // we matched the whole pattern
                i = lps[n-1]; // shift the pattern so that the longest proper prefix/suffix pair is aligned
                matches++;
            }
        }
    }
    return matches;
}

int main() {
    RH_single::init();
    string x,y,z;
    //while(cin>>x)
    //{
        //ios_base::sync_with_stdio(0);
        //cin.tie(0);
        vector<string>c;
        cin>>x>>y>>z;
        if(count_matches(x, y)==0&&count_matches(x,z)==0)
        {
            c.push_back(x);
        }
        if(count_matches(y, x)==0&&count_matches(y,z)==0)
        {
            c.push_back(y);
        }
        if(count_matches(z, y)==0&&count_matches(z,x)==0)
        {
            c.push_back(z);
        }
        if(c.size()==1)
            cout<<c[0].length()<<"\n";
        else if(c.size()==2)
        {
            unsigned int res=0,mini=10000000;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                ull h1 = RH_single(c[0]).hash(c[0].length()-i-1, c[0].length()-1);
                ull h2 = RH_single(c[1]).hash(0, i);
                if(h1==h2)res=i+1;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;
            res=0;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                ull h1 = RH_single(c[1]).hash(c[1].length()-i-1, c[1].length()-1);
                ull h2 = RH_single(c[0]).hash(0, i);
                if(h1==h2)res=i+1;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;

            cout<<mini<<"\n";

        }
        else if(c.size()==3)
        {
            unsigned int res=0,mini=10000000;
            for(int a=0;a<3;a++)
            {
                for(int b=0;b<3;b++)
                {
                    if(b==a)continue;

                    for(int f=0;f<3;f++)
                    {
                        if(f==a||f==b)continue;
                        res=0;
                        for(int i=0; i<c[a].length()&&i<c[b].length();i++)
                        {
                            ull h1 = RH_single(c[a]).hash(c[a].length()-i-1, c[a].length()-1);
                            ull h2 = RH_single(c[b]).hash(0, i);
                            if(h1==h2)res=i+1;
                        }
                        ull res2=0;
                        for(int i=0; i<c[b].length()&&i<c[f].length();i++)
                        {
                            ull h1 = RH_single(c[b]).hash(c[b].length()-i-1, c[b].length()-1);
                            ull h2 = RH_single(c[f]).hash(0, i);
                            if(h1==h2)res2=i+1;
                        }
                        if (mini>c[0].length()+c[1].length()+c[2].length()-res-res2){
                            mini=c[0].length()+c[1].length()+c[2].length()-res-res2;
                            //cout<<a<<" "<<b<<" "<<f<<endl;
                        }
                    }
                }
            }
            cout<<mini<<"\n";
        }
        else
            cout<<x.length()<<"\n";

    //}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct UF{
    vector<ll>p,r;
    void makeSet(ll x)//cambiar cuando no es ll
    {
        p.push_back(x);
        r.push_back(0);
    }
    ll find(ll x)
    {
        if(p[x]==x) return x;
        else return p[x]=find(p[x]);
    }
    void join(ll x,ll y)
    {
        x=find(x);
        y=find(y);
        if(x!=y)
        {
            if(r[x]>=r[y])
            {
                if(r[x]==r[y])
                {
                    r[x]++;
                }
                p[y]=x;
            }
            else p[x]=y;
        }
    }
};

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    ll n,m,x,y;
    cin>>n>>m;
    vector<tuple<ll,ll,ll> >cx;
    vector<tuple<ll,ll,ll> >cy,d;

    UF A;
    for(ll i=0;i<=m+4;i++)
    {
        A.makeSet(i);
    }
    UF B;
    for(ll i=0;i<=m+4;i++)
    {
        B.makeSet(i);
    }
    UF C;
    for(ll i=0;i<=m+5;i++)
    {
        C.makeSet(i);
    }

    // m+1 -x
    // m+2 -y
    // m+3 x
    // m+4 y
    for(ll i=0;i<m;i++)
    {
        cin>>x>>y;
        if (x==1){
            A.join(i,m+1);
            C.join(i,m+1);}
        if(x==n){
            A.join(i,m+2);
            C.join(i,m+3);}
        if (y==1){
            B.join(i,m+1);
            C.join(i,m+2);
        }
        if(y==n)
            {C.join(i,m+4);
            B.join(i,m+2);}
        cx.push_back(make_tuple(x,y,i));
        cy.push_back(make_tuple(y,x,i));
    }
    sort(cy.begin(),cy.end());
    sort(cx.begin(),cx.end());
    vector<vector<tuple<ll,ll,ll> > >c;
    ll p=get<0>(cx[0]);
    for(ll i=0;i<m;i++)
    {
        if(get<0>(cx[i])==p)
        {
            d.push_back(cx[i]);
        }
        else
        {
            c.push_back(d);
            d.clear();
            p=get<0>(cx[i]);
            d.push_back(cx[i]);
        }
    }
    if (!d.empty())
        c.push_back(d);
    /*for(int i=0;i<c.size();i++)
    {
        cout<<i<<"::\n";
        for(int j=0;j<c[i].size();j++)
        {
            cout<<get<0>(c[i][j])<<" "<<get<1>(c[i][j])<<endl;
        }
    }*/
    for(ll i=0;i<c.size()-1;i++)
    {
        for(ll j=0;j<c[i].size();j++)
        {
            for(ll z=c[i+1].size()-1;z>=0;z--)
            {
                if(get<0>(c[i+1][z])-get<0>(c[i][j])==1&&get<1>(c[i][j])-1<=get<1>(c[i+1][z]))
                {
                    A.join(get<2>(c[i+1][z]),get<2>(c[i][j]));
                    C.join(get<2>(c[i+1][z]),get<2>(c[i][j]));
                }
                else
                    break;
            }
        }
    }
    c.clear();
    d.clear();
    p=get<0>(cy[0]);
    for(ll i=0;i<m;i++)
    {
        if(get<0>(cy[i])==p)
        {
            d.push_back(cy[i]);
        }
        else
        {
            c.push_back(d);
            d.clear();
            p=get<0>(cy[i]);
            d.push_back(cy[i]);
        }
    }
    if (!d.empty())
        c.push_back(d);
    /*for(int i=0;i<c.size();i++)
    {
        cout<<i<<"::\n";
        for(int j=0;j<c[i].size();j++)
        {
            cout<<get<0>(c[i][j])<<" "<<get<1>(c[i][j])<<endl;
        }
    }*/
    for(ll i=0;i<c.size()-1;i++)
    {
        for(ll j=0;j<c[i].size();j++)
        {
            for(ll z=c[i+1].size()-1;z>=0;z--)
            {
                if(get<0>(c[i+1][z])-get<0>(c[i][j])==1&&get<1>(c[i][j])-1<=get<1>(c[i+1][z]))
                {
                    B.join(get<2>(c[i+1][z]),get<2>(c[i][j]));
                    C.join(get<2>(c[i+1][z]),get<2>(c[i][j]));
                }
                else
                    break;
            }
        }
    }
    //cout<<C.find(m+1)<<" "<<C.find(m+2)<<endl;
    //cout<<(A.find(m+1)!=A.find(m+2))<<" "<<(B.find(m+1)!=B.find(m+2))<<" "<<(C.find(m+1)!=C.find(m+2))<<" "<<(C.find(m+3)!=C.find(m+4))<<endl;
    if(A.find(m+1)!=A.find(m+2)&&B.find(m+1)!=B.find(m+2)&&C.find(m+1)!=C.find(m+2)&&C.find(m+3)!=C.find(m+4))
    {
        cout<<(n-1)*2<<"\n";
    }
    else
        cout<<"-1\n";
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a; i<=b; ++i)

// Build longest proper prefix/suffix array (lps) for pattern
// lps[i] = length of the longest proper prefix which is also suffix in pattern[0 .. i]
void init_lps(string& pattern, int lps[]) {
    int n = pattern.size();
    lps[0] = 0; // base case: no proper prefix/suffix for pattern[0 .. 0] (length 1)
    rep(j, 1, n-1) { // for each pattern[0 .. j]
        int i = lps[j-1]; // i points to the char next to lps of previous iteration
        while (pattern[i] != pattern[j] and i > 0) i = lps[i-1];
        lps[j] = pattern[i] == pattern[j] ? i+1 : 0;
    }
}

// Count number of matches of pattern string in target string using KMP algorithm
int count_matches(string& pattern, string& target) {
    int n = pattern.size(), m = target.size();
    int lps[n];
    init_lps(pattern, lps); // build lps array
    int matches = 0;
    int i = 0; // i tracks current char in pattern to compare
    rep(j, 0, m-1) { // j tracks each char in target to compare
        // try to keep prefix before i as long as possible while ensuring i matches j
        while (pattern[i] != target[j] and i > 0) i = lps[i-1];
        if (pattern[i] == target[j]) {
            if (++i == n) { // we matched the whole pattern
                i = lps[n-1]; // shift the pattern so that the longest proper prefix/suffix pair is aligned
                matches++;
            }
        }
    }
    return matches;
}

int main() {
    string x,y,z;
    //difodijf
    //while(cin>>x)
    //{
        //ios_base::sync_with_stdio(0);
        //cin.tie(0);
        vector<string>c;
        cin>>x>>y>>z;
        if(count_matches(x, y)==0&&count_matches(x,z)==0)
        {
            c.push_back(x);
        }
        if(count_matches(y, x)==0&&count_matches(y,z)==0)
        {
            c.push_back(y);
        }
        if(count_matches(z, y)==0&&count_matches(z,x)==0)
        {
            c.push_back(z);
        }
        if(c.size()==1)
            cout<<c[0].length()<<"\n";
        else if(c.size()==2)
        {
            unsigned int res=0,mini=10000000;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                if(c[0][c[0].length()-i-1]==c[1][i])res++;
                else break;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;
            res=0;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                if(c[1][c[1].length()-i-1]==c[0][i])res++;
                else break;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;

            cout<<mini<<"\n";

        }
        else if(c.size()==3)
        {
            unsigned int res=0,mini=10000000;
            for(int a=0;a<3;a++)
            {
                for(int b=0;b<3;b++)
                {
                    if(b==a)continue;

                    for(int f=0;f<3;f++)
                    {
                        if(f==a||f==b)continue;
                        res=0;
                        for(int i=0; i<c[a].length()&&i<c[b].length();i++)
                        {
                            if(c[a][c[a].length()-i-1]==c[b][i])res++;
                            else break;
                        }
                        for(int i=0; i<c[b].length()&&i<c[f].length();i++)
                        {
                            if(c[b][c[b].length()-i-1]==c[f][i])res++;
                            else break;
                        }
                        if (mini>c[0].length()+c[1].length()+c[2].length()-res)
                            mini=c[0].length()+c[1].length()+c[2].length()-res;
                    }
                }
            }
            cout<<mini<<"\n";
        }
        else
            cout<<x.length()<<"\n";

    //}
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a; i<=b; ++i)
typedef unsigned long long int ull;
const int MAXLEN = 1e6;

// ------------------------------------
// rolling hashing using a single prime

struct RH_single { // rolling hashing
    static const ull B = 127; // base
    static const ull P = 1e9 + 7; // prime
    static ull pow[MAXLEN];
    static ull add(ull x, ull y) { return (x + y) % P; }
    static ull mul(ull x, ull y) { return (x * y) % P; }
    static void init() {
        pow[0] = 1;
        rep(i, 1, MAXLEN-1) pow[i] = mul(B, pow[i-1]);
    }
    vector<ull> h;
    int len;
    RH_single(string& s) {
        len = s.size();
        h.resize(len);
        h[0] = s[0] - 'a';
        rep(i,1,len-1) h[i] = add(mul(h[i-1], B), s[i]-'a');
    }
    ull hash(int i, int j) {
        if (i == 0) return h[j];
        return add(h[j], P - mul(h[i-1], pow[j - i + 1]));
    }
    ull hash() { return h[len-1]; }
};
ull RH_single::pow[MAXLEN]; // necessary for the code to compile

// Build longest proper prefix/suffix array (lps) for pattern
// lps[i] = length of the longest proper prefix which is also suffix in pattern[0 .. i]
void init_lps(string& pattern, int lps[]) {
    int n = pattern.size();
    lps[0] = 0; // base case: no proper prefix/suffix for pattern[0 .. 0] (length 1)
    rep(j, 1, n-1) { // for each pattern[0 .. j]
        int i = lps[j-1]; // i points to the char next to lps of previous iteration
        while (pattern[i] != pattern[j] and i > 0) i = lps[i-1];
        lps[j] = pattern[i] == pattern[j] ? i+1 : 0;
    }
}

// Count number of matches of pattern string in target string using KMP algorithm
int count_matches(string& pattern, string& target) {
    int n = pattern.size(), m = target.size();
    int lps[n];
    init_lps(pattern, lps); // build lps array
    int matches = 0;
    int i = 0; // i tracks current char in pattern to compare
    rep(j, 0, m-1) { // j tracks each char in target to compare
        // try to keep prefix before i as long as possible while ensuring i matches j
        while (pattern[i] != target[j] and i > 0) i = lps[i-1];
        if (pattern[i] == target[j]) {
            if (++i == n) { // we matched the whole pattern
                i = lps[n-1]; // shift the pattern so that the longest proper prefix/suffix pair is aligned
                matches++;
            }
        }
    }
    return matches;
}

int main() {
    RH_single::init();
    string x,y,z;
    //while(cin>>x)
    //{
        //ios_base::sync_with_stdio(0);
        //cin.tie(0);
        vector<string>c;
        cin>>x>>y>>z;
        if(count_matches(x, y)==0&&count_matches(x,z)==0)
        {
            c.push_back(x);
        }
        if(count_matches(y, x)==0&&count_matches(y,z)==0)
        {
            c.push_back(y);
        }
        if(count_matches(z, y)==0&&count_matches(z,x)==0)
        {
            c.push_back(z);
        }
        if(c.size()==1)
            cout<<c[0].length()<<"\n";
        else if(c.size()==2)
        {
            unsigned int res=0,mini=10000000;
            RH_single x(c[0]),y(c[1]);
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                ull h1 = x.hash(c[0].length()-i-1, c[0].length()-1);
                ull h2 = y.hash(0, i);
                if(h1==h2)res=i+1;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;
            res=0;
            for(int i=0; i<c[0].length()&&i<c[1].length();i++)
            {
                ull h1 = y.hash(c[1].length()-i-1, c[1].length()-1);
                ull h2 = x.hash(0, i);
                if(h1==h2)res=i+1;
            }
            if(mini>c[0].length()+c[1].length()-res)
                mini=c[0].length()+c[1].length()-res;

            cout<<mini<<"\n";

        }
        else if(c.size()==3)
        {
            unsigned int res=0,mini=10000000;
            vector<RH_single>D={RH_single(c[0]),RH_single(c[1]),RH_single(c[2])};
            for(int a=0;a<3;a++)
            {
                for(int b=0;b<3;b++)
                {
                    if(b==a)continue;

                    for(int f=0;f<3;f++)
                    {
                        if(f==a||f==b)continue;
                        res=0;
                        for(int i=0; i<c[a].length()&&i<c[b].length();i++)
                        {
                            ull h1 = D[a].hash(c[a].length()-i-1, c[a].length()-1);
                            ull h2 = D[b].hash(0, i);
                            if(h1==h2)res=i+1;
                        }
                        ull res2=0;
                        for(int i=0; i<c[b].length()&&i<c[f].length();i++)
                        {
                            ull h1 = D[b].hash(c[b].length()-i-1, c[b].length()-1);
                            ull h2 = D[f].hash(0, i);
                            if(h1==h2)res2=i+1;
                        }
                        if (mini>c[0].length()+c[1].length()+c[2].length()-res-res2){
                            mini=c[0].length()+c[1].length()+c[2].length()-res-res2;
                            //cout<<a<<" "<<b<<" "<<f<<endl;
                        }
                    }
                }
            }
            cout<<mini<<"\n";
        }
        else
            cout<<x.length()<<"\n";

    //}
    return 0;
}


#include <bits/stdc++.h>
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef pair<ll, ll>pll;
vector<int>build_z(string s)
{
    vector<int>z(s.size());
    for(int i = 1, l = 0, r = 0;i < s.size();++i)
    {
        if(i <= r)  z[i] = min(r - i + 1, z[i - l]);
        while(i + z[i] < s.size() && s[z[i]] == s[i + z[i]])
            ++z[i];
        if(i + z[i] - 1 > r)    l = i, r = i + z[i] - 1;
    }
    return z;
}
string solve(string s, string t)
{
    string g = t + '#' + s;
    vector<int>z = build_z(g);
    int tmp = 0;
    for(int i = 0;i < z.size();++i)
    {
        if(i + z[i] == g.size())
        {
            tmp = g.size() - i;
            break;
        }
    }
    return s + t.substr(tmp);
}
int main()
{
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    string arr[3];
    int ans = INT_MAX;
    for(int i = 0;i < 3;++i)    cin >> arr[i];
    int nxt[] = {0, 1, 2};
    do
    {
        string g = solve(solve(arr[nxt[0]], arr[nxt[1]]), arr[nxt[2]]);
        ans = min(ans, (int)g.size());
    } while(next_permutation(nxt, nxt + 3));
    cout << ans;
    return 0;
}


#include <iostream>
#include <set>
#include <map>

using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);

    set<int> numbers;
    map<int, int> left;
    map<int, int> right;

    int n, v;
    cin >> n >> v;
    numbers.insert(v);
    for (int i = 0; i < n - 1; i++) {
        cin >> v;
        auto it = numbers.upper_bound(v);
        int result;
        if (it != numbers.end() && left.count(*it) == 0) {
            left[*it] = v;
            result = *it;
        } else {
            it--;
            right[*it] = v;
            result = *it;
        }
        numbers.insert(v);
        cout << result << ' ';
    }
    cout << endl;
}


#include <cstdio>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
typedef long long ll;

ll v[111111], n;
map<ll, ll> left, right;
set<ll> s;

int main () {
    scanf("%I64d",&n);
    for(int i=0;i<n;i++)    scanf("%I64d",v+i);
    s.insert(v[0]);
    for(int i=1;i<n;i++) {
        auto it = s.lower_bound(v[i]), its = it;
        its--;
        if(it == s.begin()) {
            left[*it] = v[i];
            printf("%I64d ",*it);
        }
        else if(it == s.end()) {
            right[*its] = v[i];
            printf("%I64d ",*its);
        }
        else {
            if(right[*its] == 0) {
                right[*its] = v[i];
                printf("%I64d ",*its);
            }
            else {
                left[*it] = v[i];
                printf("%I64d ",*it);
            }
        }
        s.insert(v[i]);
    }
    printf("\n");
}


#include <iostream>
#include <set>
#include <map>

using namespace std;

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);

    set<int> numbers;
    map<int, int> left;
    map<int, int> right;

    int n, v;
    cin >> n >> v;
    numbers.insert(v);
    for (int i = 0; i < n - 1; i++) {
        cin >> v;
        auto it = numbers.upper_bound(v);
        int result;
        if (it != numbers.end() && left.count(*it) == 0) {
            left[*it] = v;
            result = *it;
        } else {
            it--;
            right[*it] = v;
            result = *it;
        }
        numbers.insert(v);
        cout << result;
        if (i == n - 2) cout << 'n';
        else cout << ' ';
    }
}


#include <iostream>
#include <cstdio>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int v, n;
map<int, int> lm, rm;
set<int> s;

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> v;
    s.insert(v);
    for(int i=1;i<n;i++) {
        cin >> v;
        auto it = lower_bound(s.begin(), s.end(), v), its = it;
        its--;
        int dab;
        if(it == s.begin())
            lm[*it] = v, dab = *it;
        else if(it == s.end())
            rm[*its] = v, dab = *its;
        else {
            if(rm[*its] == 0)
                rm[*its] = v, dab = *its;
            else
                lm[*it] = v, dab = *it;
        }
        s.insert(v);
        cout << dab << ' ';
    }
    cout << endl;
}


#include <iostream>
#include <cstdio>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int v, n;
map<int, int> lm, rm;
set<int> s;

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> v;
    s.insert(v);
    for(int i=1;i<n;i++) {
        cin >> v;
        auto it = s.lower_bound(v);
        // auto it = lower_bound(s.begin(), s.end(), v);
        int dab;
        if(it != s.end() && lm.count(*it) == 0) {
            lm[*it] = v;
            dab = *it;
        }
        else {
            it--;
            rm[*it] = v;
            dab = *it;
        }
        s.insert(v);
        cout << dab << ' ';
    }
    cout << endl;
}


#include <cstdio>
#include <vector>
using namespace std;

struct node {
    int left, right;
    node() :left(-1), right(-1) {}
};

int n, v[111111], head;
node tree[111111];
int parent[111111];

void append(int here, int index) {
    if(v[here] < v[index]) {
        if(tree[here].right == -1) {
            tree[here].right = index;
            parent[index] = here;
            return;
        }
        append(tree[here].right, index);
    }
    if(v[here] > v[index]) {
        if(tree[here].left == -1) {
            tree[here].left = index;
            parent[index] = here;
            return ;
        }
        append(tree[here].left, index);
    }
}

int main () {
    scanf("%d",&n);
    for(int i=0;i<n;i++) {
        scanf("%d",v+i);
    }
    for(int i=1;i<n;i++) {
        append(0,i);
    }
    for(int i=1;i<n;i++) {
        printf("%d ",v[parent[i]]);
    }
    printf("\n");
}


#include <iostream>
#include <cstdio>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int v, n;
map<int, int> lm, rm;
set<int> s;

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> v;
    s.insert(v);
    for(int i=1;i<n;i++) {
        cin >> v;
        auto it = lower_bound(s.begin(), s.end(), v);
        auto its = it;  its--;
        int dab;
        if(it != s.end() && lm.count(*it) == 0) {
            lm[*it] = v;
            dab = *it;
        }
        else {
            rm[*its] = v;
            dab = *its;
        }
        s.insert(v);
        cout << dab << ' ';
    }
    cout << endl;
}


#include <cstdio>
#include <map>
#include <set>
#include <algorithm>
using namespace std;
typedef long long ll;

ll v[111111], n;
map<ll, ll> left, right;
set<ll> s;

int main () {
    scanf("%I64d",&n);
    for(int i=0;i<n;i++)    scanf("%I64d",v+i);
    s.insert(v[0]);
    for(int i=1;i<n;i++) {
        auto it = lower_bound(s.begin(), s.end(), v[i]), its = it;
        its--;
        if(it == s.begin()) {
            left[*it] = v[i];
            printf("%I64d ",*it);
        }
        else if(it == s.end()) {
            right[*its] = v[i];
            printf("%I64d ",*its);
        }
        else {
            if(right[*its] == 0) {
                right[*its] = v[i];
                printf("%I64d ",*its);
            }
            else {
                left[*it] = v[i];
                printf("%I64d ",*it);
            }
        }
        s.insert(v[i]);
    }
    printf("\n");
}


#include <iostream>
#include <cstdio>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int v, n;
map<int, int> lm, rm;
set<int> s;

int main () {
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin >> n >> v;
    s.insert(v);
    for(int i=1;i<n;i++) {
        cin >> v;
        auto it = s.lower_bound(v), its = it;
        its--;
        int dab;
        if(it == s.begin())
            lm[*it] = v, dab = *it;
        else if(it == s.end())
            rm[*its] = v, dab = *its;
        else {
            if(rm[*its] == 0)
                rm[*its] = v, dab = *its;
            else
                lm[*it] = v, dab = *it;
        }
        s.insert(v);
        cout << dab << ' ';
    }
    cout << endl;
}


#include <cstdio>
#include <map>
#include <set>
#include <algorithm>
using namespace std;

int v[111111], n;
map<int, int> left, right;
set<int> s;

int main () {
    scanf("%d",&n);
    for(int i=0;i<n;i++)    scanf("%d",v+i);
    s.insert(v[0]);
    for(int i=1;i<n;i++) {
        auto it = lower_bound(s.begin(), s.end(), v[i]), its = it;
        its--;
        int dab;
        if(it == s.begin())
            left[*it] = v[i], dab = *it;
        else if(it == s.end())
            right[*its] = v[i], dab = *its;
        else {
            if(right[*its] == 0)
                right[*its] = v[i], dab = *its;
            else
                left[*it] = v[i], dab = *it;
        }
        s.insert(v[i]);
        printf("%d ",dab );
    }
    printf("\n");
}