#include<bits/stdc++.h>
#define int long long
using namespace std;
int mov[20][5],Pow[20],nxt[20];
bool vis[100000008];
struct node{
int a[20],g,h,f;
bool operator<(const node &y) const{
return f>y.f;
}
};
priority_queue<node>Q;
int get_h(int a[]){
int num=0;
for(int i=1;i<=12;i++){
if(a[i]==1)num+=0;
if(a[i]==2)num+=3;
if(a[i]==3)num+=2;
if(a[i]==4)num+=1;
}
num/=4;
return num;
}
int change(int a[]){
int num=0;
for(int i=1;i<=12;i++)
num+=a[i]*Pow[i];
return num;
}
signed main(){
Pow[0]=1;
for(int i=1;i<=15;i++)
Pow[i]=Pow[i-1]*4;
node Start;
for(int i=1;i<=12;i++){
cin>>Start.a[i];
for(int j=1;j<=4;j++)
cin>>mov[i][j];
}
Start.g=0;
Start.h=get_h(Start.a);
Start.f=Start.g+Start.h;
Q.push(Start);
vis[change(Start.a)]=1;
while(!Q.empty()){
node cmp=Q.top();
vis[change(cmp.a)]=1;
Q.pop();
for(int i=1;i<=12;i++){
for(int j=1;j<=12;j++)
nxt[j]=cmp.a[j];
nxt[mov[i][nxt[i]]]++;
if(nxt[mov[i][nxt[i]]]==5)
nxt[mov[i][nxt[i]]]++;
nxt[i]++;
if(nxt[i]==5)
nxt[i]=1;
if(vis[change(nxt)])
continue;
node p;
for(int j=1;j<=12;j++)
p.a[j]=nxt[j];
p.g=cmp.g+1;
p.h=get_h(nxt);
p.f=p.g+p.h;
Q.push(p);
bool f=1;
for(int i=1;i<=12;i++)
if(nxt[i]!=1){
f=0;
break;
}
if(f==1){
cout<<cmp.g+1;
return 0;
}
}
}
return 0;
}