let N = Int(readLine()!)!

var a = [[Bool]]()
for _ in stride(from: 0, to: N, by: 1) {
    let row = readLine()!.split(separator: " ").map { Int($0)! == 1 }
    a.append(row)
}

let divider = 1_000_000_007

var dp = Array(repeating: Optional<Int>.none, count: 1 << N)
dp[0] = 1

/// - bit: 孤立している女性一覧
/// - i: 男性iさん
func dfs(_ bit: Int, _ i: Int) -> Int {
    guard dp[bit] == nil else {
        return dp[bit]!
    }

    var numberOfPatterns = 0
    /// 女性jさんについて
    for j in stride(from: 0, to: N, by: 1) {
        /// 孤立しており、かつ男性iさんと相性がいいならば
        if bit & (1 << j) > 0, a[i][j] {
            /// 排他的論理和でjさんのbitを0にする
            /// jさんのbitを0にして次の男性を調べに行く
            numberOfPatterns = (numberOfPatterns + dfs(bit ^ (1 << j), i + 1))
        }
    }
    let newValue = numberOfPatterns % divider
    dp[bit] = newValue
    return newValue
}

/// 女性が誰もペアを作っていない状態からスタート
print(dfs((1 << N) - 1, 0))
