const MOD = 1e9 + 7;

function solve() {
    const readline = require('readline');
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout,
        terminal: false
    });

    let lines = [];
    rl.on('line', (line) => {
        lines.push(line.trim());
    });

    rl.on('close', () => {
        let idx = 0;
        const n = parseInt(lines[idx++]);
        // 1-based索引:a[i][j] 第i行第j列(i:1~n, j:1~i)
        const a = Array.from({ length: n + 1 }, () => Array(n + 1).fill(0));
        for (let i = 1; i <= n; i++) {
            const row = lines[idx++].split(' ').map(Number);
            for (let j = 1; j <= i; j++) {
                a[i][j] = row[j - 1];
            }
        }

        // 特殊情况:n=1,直接输出1
        if (n === 1) {
            console.log(1);
            return;
        }

        // 修复:将const改为let,允许后续重新赋值
        let dp = Array.from({ length: n + 2 }, () => Array(n + 2).fill(0));
        for (let c2 = 1; c2 <= n; c2++) {
            if (a[1][1] === a[n][c2]) {
                dp[1][c2] = 1;
            }
        }

        const half = Math.floor(n / 2);
        // 迭代i从2到half(正向路径从第2行到第half行)
        for (let i = 2; i <= half; i++) {
            const nextDp = Array.from({ length: n + 2 }, () => Array(n + 2).fill(0));
            // 正向第i行的列c1范围:1~i
            for (let c1 = 1; c1 <= i; c1++) {
                // 反向第(n - i + 1)行的列c2范围:1~(n - i + 1)
                for (let c2 = 1; c2 <= (n - i + 1); c2++) {
                    // 验证当前位置数字相等
                    if (a[i][c1] !== a[n - i + 1][c2]) continue;

                    // 累加4种合法转移路径数
                    let count = 0;
                    count = (count + dp[c1 - 1][c2]) % MOD;     // 正向c1-1 → c1,反向c2 → c2
                    count = (count + dp[c1 - 1][c2 + 1]) % MOD; // 正向c1-1 → c1,反向c2+1 → c2
                    count = (count + dp[c1][c2]) % MOD;         // 正向c1 → c1,反向c2 → c2
                    count = (count + dp[c1][c2 + 1]) % MOD;     // 正向c1 → c1,反向c2+1 → c2
                    nextDp[c1][c2] = count;
                }
            }
            dp = nextDp; // 现在可以正常赋值
        }

        // 计算结果
        let ans = 0;
        if (n % 2 === 0) {
            // 偶数行:中间相邻行,c2 == c1 或 c2 == c1+1
            for (let c1 = 1; c1 <= half; c1++) {
                ans = (ans + dp[c1][c1]) % MOD;
                ans = (ans + dp[c1][c1 + 1]) % MOD;
            }
        } else {
            // 奇数行:中间行,c2 == c1 或 c2 == c1+1(×2)或 c2 == c1+2
            for (let c1 = 1; c1 <= half; c1++) {
                for (let c2 = 1; c2 <= (n - half + 1); c2++) {
                    if (dp[c1][c2] === 0) continue;
                    if (c2 === c1 || c2 === c1 + 2) {
                        ans = (ans + dp[c1][c2]) % MOD;
                    } else if (c2 === c1 + 1) {
                        ans = (ans + dp[c1][c2] * 2) % MOD;
                    }
                }
            }
        }

        console.log(ans);
    });
}

solve();