#include <bits/stdc++.h>   using namespace std;   struct Number {     array<int, 4> x = {{0, 0, 0, 0}};     Number() {}     Number(int a) {       if (a != -1) x[a]++;     }     long double log_value() const {       if (x[0] > 0) return -INFINITY;       return x[2] * log(2L) + x[3] * log(3L);     }     int mod() const {       long long result = 1;       for (int i = 0; i < 4; i++)         for (int j = 0; j < x[i]; j++) result = (result * i) % (int)(1e9 + 7);       return result;     }     bool is_zero() const { return x[0] > 0; }   };   bool operator<(const Number& a, const Number& b) {     return a.log_value() < b.log_value();   }   Number operator*(const Number& a, const Number& b) {     Number result;     for (int i = 0; i < 4; i++) result.x[i] = a.x[i] + b.x[i];     return result;   }   Number operator/(const Number& a, const Number& b) {     Number result;     for (int i = 0; i < 4; i++) result.x[i] = a.x[i] - b.x[i];     return result;   }   template <typename T>   using Matrix = vector<vector<T>>;   template <typename T>   Matrix<T> matrix(int R, int C, T x = T()) {     return Matrix<T>(R, vector<T>(C, x));   }   struct RangeProduct {     int N;     Matrix<int> grid;     Matrix<Number> hprod;     Matrix<Number> vprod;     bool valid(int r, int c) { return 0 <= r && r < N && 0 <= c && c < N; }     RangeProduct(int N, Matrix<int> grid) : N(N), grid(grid) {       hprod = matrix<Number>(N + 1, N + 1);       vprod = matrix<Number>(N + 1, N + 1);       for (int r = 0; r < N; r++)         for (int c = 0; c < N; c++) {           hprod[r][c + 1] = hprod[r][c] * Number(grid[r][c]);           vprod[r + 1][c] = vprod[r][c] * Number(grid[r][c]);         }     }     Number hquery(int r, int c, int radius) {       int c1 = c - radius, c2 = c + radius;       if (!valid(r, c1) || !valid(r, c2)) return Number(0);       return hprod[r][c2 + 1] / hprod[r][c1];     }     Number vquery(int r, int c, int radius) {       int r1 = r - radius, r2 = r + radius;       if (!valid(r1, c) || !valid(r2, c)) return Number(0);       return vprod[r2 + 1][c] / vprod[r1][c];     }     Number cross(int r, int c, int radius) {       return hquery(r, c, radius) * vquery(r, c, radius) / Number(grid[r][c]);     }     Number max_cross(int r, int c) {       int a = 0, b = N;       while (a < b) {         int mid = (a + b + 1) / 2;         if (cross(r, c, mid).is_zero())           b = mid - 1;         else           a = mid;       }       return cross(r, c, a);     }   };   Number solve(int N, Matrix<int> grid) {     RangeProduct rp(N, grid);     Number result(0);     for (int r = 0; r < N; r++)       for (int c = 0; c < N; c++) result = max(result, rp.max_cross(r, c));     return result;   }   Matrix<int> rotate(int N, const Matrix<int>& grid, int shift) {     auto ngrid = matrix<int>(N, N);     for (int r = 0; r < N; r++)       for (int c = 0; c < N; c++)         if ((r + c) % 2 == shift)           ngrid[(r + c) / 2][(r - c + N) / 2] = grid[r][c];     return ngrid;   }   int main() {     int N;     cin >> N;     auto grid = matrix<int>(N, N);     for (int i = 0; i < N; i++) {       string s;       cin >> s;       for (int j = 0; j < N; j++) grid[i][j] = s[j] -  0 ;     }     auto rgrid0 = rotate(N, grid, 0);     auto rgrid1 = rotate(N, grid, 1);     Number answer = max({solve(N, grid), solve(N, rgrid0), solve(N, rgrid1)});     cout << answer.mod() << endl;   }