Vanya plays a game of balloons on the field of size n × n, where each cell contains a balloon with one of the values 0, 1, 2 or 3. The goal is to destroy a cross, such that the product of all values of balloons in the cross is maximum possible. There are two types of crosses: normal and rotated. For example:
    
    
      
    **o**  
    **o**  
    ooooo  
    **o**  
    **o**  
    

or
    
    
      
    o***o  
    *o*o*  
    **o**  
    *o*o*  
    o***o  
    

Formally, the cross is given by three integers r, c and d, such that d ≤ r, c ≤ n - d + 1. The normal cross consists of balloons located in cells (x, y) (where x stay for the number of the row and y for the number of the column), such that |x - r|·|y - c| = 0 and |x - r| + |y - c| < d. Rotated cross consists of balloons located in cells (x, y), such that |x - r| = |y - c| and |x - r| < d.

Vanya wants to know the maximum possible product of the values of balls forming one cross. As this value can be large, output it modulo 109 + 7.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 1000) — the number of rows and columns in the table with balloons.

The each of the following n lines contains n characters '0', '1', '2' or '3' — the description of the values in balloons.

Output

Print the maximum possible product modulo 109 + 7. Note, that you are not asked to maximize the remainder modulo 109 + 7, but to find the maximum value and print it this modulo.

Examples

Input

4
1233
0213
2020
0303


Output

108


Input

5
00300
00300
33333
00300
00300


Output

19683


Input

5
00003
02030
00300
03020
30000


Output

108


Input

5
21312
10003
10002
10003
23231


Output

3


Input

5
12131
12111
12112
21311
21212


Output

24

Note

In the first sample, the maximum product is achieved for a rotated cross with a center in the cell (3, 3) and radius 1: 2·2·3·3·3 = 108.
import java.io.*;
import java.util.Arrays;

public class Main {
    private static final int C = 1010;

    static void dfs(int d,int x,int y){
        if (Per[d][x][y]!=-1)return;
        int xx=x+dx[d],yy=y+dy[d];
        if (Math.min(xx,yy)<1||Math.max(xx,yy)>n||V[xx][yy]==0){
            Per[d][x][y]=1;
            Sum[d][x][y]=A[x][y];
            return;
        }
        dfs(d,xx,yy);
        Per[d][x][y]=Per[d][xx][yy]+1;
        Sum[d][x][y]=Sum[d][xx][yy]+A[x][y];
    }

    static double[][] A = new double[C][C];
    static int[][] V = new int[C][C];
    static int[][][] Per = new int[8][C][C];
    static double[][][] Sum = new double[8][C][C];
    static final int[] dx = {1, 0, -1, 0, 1, 1, -1, -1};
    static final int[] dy = {0, 1, 0, -1, 1, -1, -1, 1};

    static int n;
    public static void main(String[] args) {
        final int mod= (int) (1e9+7);
        IO io = new IO();
        n=io.nextInt();
        for (int i = 0; i < Per.length; i++)
            for (int j = 0; j < Per[0].length; j++) Arrays.fill(Per[i][j],-1);

        for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if ((V[i][j]=io.nextChar()-'0')!=0)A[i][j]=Math.log(V[i][j]);
        for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)for (int t=0;t<8;t++)if (Per[t][i][j]==-1&&V[i][j]!=0)dfs(t,i,j);
        double resv=-1,val;
        int ress=0,r=0,c=0,resd=0,size;
        for (int i=1;i<=n;i++)for (int j=1;j<=n;j++)if (V[i][j]!=0)for (int s=0;s<=1;s++){
            size=C;val=A[i][j];;
            for (int t=s*4;t<=s*4+3;t++)size=Math.min(size,Per[t][i][j]);
            for (int t=s*4;t<=s*4+3;t++)val+=Sum[t][i][j]-A[i][j]-Sum[t][i+size*dx[t]][j+size*dy[t]];
            if (val>resv){
                resv=val;r=i;c=j;ress=size;resd=s;
            }
        }
        if (ress==0){
            io.println(0);return;
        }
        long ans=V[r][c];
        for (int i=1;i<=ress-1;i++)for (int t=resd*4;t<=resd*4+3;t++)ans=ans*V[r+i*dx[t]][c+i*dy[t]]%mod;
        io.println(ans);
    }

    static class IO {

        BufferedInputStream din;
        final int BUFFER_SIZE = 1 << 16;
        byte[] buffer;
        int byteRead, bufferPoint;

        StringBuilder builder;
        PrintWriter pw;

        public IO() {
            din = new BufferedInputStream(System.in);
            buffer = new byte[BUFFER_SIZE];
            bufferPoint = byteRead = 0;

            builder = new StringBuilder();
            pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
                    System.out
            )), true);
        }

        int read() {
            if (bufferPoint >= byteRead) {
                try {
                    byteRead = din.read(buffer, bufferPoint = 0, BUFFER_SIZE);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (byteRead == -1) buffer[0] = -1;
            }
            return buffer[bufferPoint++];
        }

        int peek() {
            if (byteRead == -1) return -1;
            if (bufferPoint >= byteRead) {
                try {
                    byteRead = din.read(buffer, bufferPoint = 0, BUFFER_SIZE);
                } catch (IOException e) {
                    return -1;
                }
                if (byteRead <= 0) return -1;
            }
            return buffer[bufferPoint];
        }

        boolean hasNext() {
            int c = peek();
            while (c != -1 && c <= ' ') {
                read();
                c = peek();
            }
            return c != -1;
        }

        char nextChar() {
            int c = read();
            while (c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1) {
                c = read();
            }
            return (char) c;
        }

        double nextDouble() {
            double ret = 0, div = 1;
            int c = read();
            while (c <= ' ')
                c = read();
            boolean neg = (c == '-');
            if (neg)
                c = read();
            do {
                ret = ret * 10 + c - '0';
            }
            while ((c = read()) >= '0' && c <= '9');
            if (c == '.') {
                while ((c = read()) >= '0' && c <= '9') {
                    ret += (c - '0') / (div *= 10);
                }
            }
            if (neg)
                return -ret;
            return ret;
        }

        String nextLine() {
            byte[] strBuf = new byte[64];
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (c == '\n') {
                    if (cnt == 0) {
                        continue;
                    } else {
                        break;
                    }
                }
                if (strBuf.length == cnt) {
                    strBuf = Arrays.copyOf(strBuf, strBuf.length * 2);
                }
                strBuf[cnt++] = (byte) c;
            }
            return new String(strBuf, 0, cnt);
        }


        String next() {
            byte[] strBuf = new byte[64];
            int cnt = 0, c;
            while ((c = read()) != -1) {
                if (Character.isWhitespace(c)) {
                    if (cnt == 0) {
                        continue;
                    } else {
                        break;
                    }
                }
                if (strBuf.length == cnt) {
                    strBuf = Arrays.copyOf(strBuf, strBuf.length * 2);
                }
                strBuf[cnt++] = (byte) c;
            }
            return new String(strBuf, 0, cnt);
        }

        int nextInt() {
            int ans = 0;
            int c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ans = ans * 10 + c - '0';
            } while ('0' <= (c = read()) && c <= '9');
            bufferPoint--;
            return neg ? -ans : ans;
        }

        long nextLong() {
            long ans = 0;
            int c = read();
            while (c <= ' ') c = read();
            boolean neg = (c == '-');
            if (neg) c = read();
            do {
                ans = ans * 10 + c - '0';
            } while ('0' <= (c = read()) && c <= '9');
            bufferPoint--;
            return neg ? -ans : ans;
        }

        void println(Object o) {
            pw.println(o);
        }

        void print(Object o) {
            pw.print(o);
        }

        void printf(String format, Object... objects) {
            pw.printf(format, objects);
        }

        void close() {
            pw.close();
        }

        void done(Object o) {
            print(o);
            close();
        }

    }

}
