#include<bits/stdc++.h>
using namespace std;
int n,pre[2000],cnt,ans;
int a[440],b[440],c[440],d[440];
int fa[2000][4],ct[2000];
int f[2000][2000][4];
struct edge {
int e,s,nxt;
} ed[100100];
void inst(int s,int e) {
ed[++cnt].e=e;
ed[cnt].s=s;
ed[cnt].nxt=pre[s];
pre[s]=cnt;
ed[++cnt].e=s;
ed[cnt].s=e;
ed[cnt].nxt=pre[e];
pre[e]=cnt;
}
void build(int *t) {
int e=1;
for(int i=1; i*i<=n*n; i++) {
while(e<=i*i) {
if(e<i*i) {
inst(t[e],t[e+1]);
}
if(i!=n) {
if(i%2) {
if(e%2) {
inst(t[e],t[e+i*2]);
}
} else {
if(e%2==0) {
inst(t[e],t[e+i*2]);
}
}
}
e++;
}
}
}
int dfs(int pos,int v,int num) {
int l=0,r=0;
if(f[pos][v][fa[pos][num]])return f[pos][v][fa[pos][num]];
if(num>pos) {
l=v,r=num-1;
} else {
l=num+1;
r=v;
}
vector<int> lt,rt;
for(int i=pre[pos]; i; i=ed[i].nxt) {
if(ed[i].e<pos&&ed[i].e>=l) {
lt.push_back(ed[i].e);
}
if(ed[i].e>pos&&ed[i].e<=r) {
rt.push_back(ed[i].e);
}
}
int ml=0,mr=0;
for(int i=0; i<lt.size(); i++) {
ml=max(ml,dfs(lt[i],l,pos));
}
for(int i=0; i<rt.size(); i++) {
mr=max(mr,dfs(rt[i],r,pos));
}
f[pos][v][fa[pos][num]]=ml+mr+1;
return ml+mr+1;
}
void work() {
vector<int> lt,rt;
for(int i=1; i<=n*n*4; i++) {
for(int j=pre[i]; j; j=ed[j].nxt) {
if(ed[j].e<i) {
lt.push_back(ed[j].e);
} else {
rt.push_back(ed[j].e);
}
}
int ml=0,mr=0;
for(int j=0; j<lt.size(); j++) {
ml=max(ml,dfs(lt[j],1,i));
}
for(int j=0; j<rt.size(); j++) {
mr=max(mr,dfs(rt[j],n*n*4,i));
}
ans=max(ans,ml+mr+1);
lt.clear();
rt.clear();
}
cout<<ans<<endl;
}
int main() {
cin>>n;
for(int i=1; i<=n*n; i++) {
cin>>a[i];
}
for(int i=1; i<=n*n; i++) {
cin>>b[i];
}
for(int i=1; i<=n*n; i++) {
cin>>c[i];
}
for(int i=1; i<=n*n; i++) {
cin>>d[i];
}
build(a);
build(b);
build(c);
build(d);
for(int i=1; i<=n; i++) {
inst(a[i*i],b[(i-1)*(i-1)+1]);
inst(b[i*i],c[(i-1)*(i-1)+1]);
inst(c[i*i],a[(i-1)*(i-1)+1]);
inst(d[(i-1)*(i-1)+1],a[n*n+2-i*2]);
inst(d[i*i],b[(n-1)*(n-1)-1+i*2]);
inst(d[n*n+2-i*2],c[(n-1)*(n-1)-1+i*2]);
}
for(int i=1; i<=cnt; i++) {
fa[ed[i].s][ed[i].e]=++ct[ed[i].s];
}
work();
}