#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>
#define MAXN 20
using namespace std;
int map[MAXN][MAXN];
int N;
int ans ;
int move(int mode) {
int max_num = 0;
// right
if (mode == 0) {
for (int i = 0; i < N; i++) {
queue<int> q;
for (int j = N - 1; j >= 0; j--) {
if (map[i][j] == 0) continue;
q.push(map[i][j]);
map[i][j] = 0;
}
int idx = N - 1;
while (!q.empty()) {
int now = q.front();
q.pop();
if (map[i][idx] == 0) {
map[i][idx] = now;
max_num = max(max_num,map[i][idx]);
}
else if (map[i][idx] == now) {
map[i][idx] *= 2;
max_num = max(max_num,map[i][idx]);
idx--;
}
else {
map[i][idx - 1] = now;
max_num = max(max_num,map[i][idx-1]);
idx--;
}
}
}
}
// left
else if (mode == 1) {
for (int i = 0; i < N; i++) {
queue<int> q;
for (int j = 0; j < N; j++) {
if (map[i][j] == 0) continue;
q.push(map[i][j]);
map[i][j] = 0;
}
int idx = 0;
while (!q.empty()) {
int now = q.front();
q.pop();
if (map[i][idx] == 0) {
map[i][idx] = now;
max_num = max(max_num,map[i][idx]);
}
else if (map[i][idx] == now) {
map[i][idx] *= 2;
max_num = max(max_num,map[i][idx]);
idx++;
}
else {
map[i][idx + 1] = now;
max_num = max(max_num,map[i][idx+1]);
idx++;
}
}
}
}
// up
else if (mode == 2) {
for (int j = 0; j < N; j++) {
queue<int> q;
for (int i = 0; i < N; i++) {
if (map[i][j] == 0) continue;
q.push(map[i][j]);
map[i][j] = 0;
}
int idx = 0;
while (!q.empty()) {
int now = q.front();
q.pop();
if (map[idx][j] == 0) {
map[idx][j] = now;
max_num = max(max_num,map[idx][j]);
}
else if (map[idx][j] == now) {
map[idx][j] *= 2;
max_num = max(max_num,map[idx][j]);
idx++;
}
else {
map[idx+1][j] = now;
max_num = max(max_num,map[idx+1][j]);
idx++;
}
}
}
}
// down
else if (mode == 3) {
for (int j = 0; j < N; j++) {
queue<int> q;
for (int i = N-1; i >= 0; i--) {
if (map[i][j] == 0) continue;
q.push(map[i][j]);
map[i][j] = 0;
}
int idx = N-1;
while (!q.empty()) {
int now = q.front();
q.pop();
if (map[idx][j] == 0) {
map[idx][j] = now;
max_num = max(max_num,map[idx][j]);
}
else if (map[idx][j] == now) {
map[idx][j] *= 2;
max_num = max(max_num,map[idx][j]);
idx--;
}
else {
map[idx-1][j] = now;
max_num = max(max_num,map[idx-1][j]);
idx--;
}
}
}
}
return max_num;
}
bool check(int copy_map[][MAXN]){
for (int i = 0; i<N; i++){
for (int j= 0 ;j <N; j++){
if (copy_map[i][j] != map[i][j]) return false;
}
}
return true;
}
void dfs(int now, int num) {
ans = max(ans,num);
if (now ==10) {
return;
}
int copy_map[MAXN][MAXN];
memcpy(copy_map,map,sizeof(map));
for (int i = 0; i < 4; i++) {
int max_num = move(i);
if (check(copy_map)) continue;
if (!(max_num*(1<<(9-now))<=ans)) dfs(now + 1,max_num);
memcpy(map,copy_map,sizeof(copy_map));
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> N;
int num = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> map[i][j];
num = max(num,map[i][j]);
}
}
ans = num;
dfs(0,0);
cout << ans << "\n";
return 0;
}