// Miscellaneous Utilities

// Common Definition

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <numeric>
#include <type_traits>
#include <utility>

namespace {

using I8    = ::std::int8_t;
using I16   = ::std::int16_t;
using I32   = ::std::int32_t;
using I64   = ::std::int64_t;
using Iz    = ::std::ptrdiff_t;
using Iptr  = ::std::intptr_t;
using Imax  = ::std::intmax_t;

using U8    = ::std::uint8_t;
using U16   = ::std::uint16_t;
using U32   = ::std::uint32_t;
using U64   = ::std::uint64_t;
using Uz    = ::std::size_t;
using Uptr  = ::std::uintptr_t;
using Umax  = ::std::uintmax_t;

}

// Return: Absolute value of signed value N
template<class Int>
constexpr ::std::make_unsigned_t<Int> Abs(Int N) noexcept {
  using UInt = ::std::make_unsigned_t<Int>;
  using SInt = ::std::make_signed_t<Int>;
  return (SInt) N < 0 ? (UInt) -(SInt) N : (UInt) N;
}

// Require: No overflow
// Return: B-th power of A
template<class Arith, class UInt>
constexpr Arith Pow(Arith A, UInt B) noexcept {
  Arith res = 1;
  while (B) {
    if (B & 1)
      res *= A;
    A *= A;
    B >>= 1;
  }
  return res;
}

// Impl: Extract all factor P from N
template<class UInt, class Count>
constexpr Count ImplFactorize(UInt& N, UInt P) noexcept {
  Count res = 1;
  N /= P;
  while (!(N % P)) {
    ++res;
    N /= P;
  }
  return res;
}

// Factorize N into Prod{Pow(P[i], K[i])}
// Require: N > 0
// Return: Number of prime factors
template<class UInt, class Count>
constexpr Uz Factorize(UInt P[], Count K[], UInt N) noexcept {
  Uz cnt = 0;
  if (!(N & 1)) {
    P[cnt] = 2;
    K[cnt++] = ImplFactorize<UInt, Count>(N, 2);
  }
  if (!(N % 3)) {
    P[cnt] = 3;
    K[cnt++] = ImplFactorize<UInt, Count>(N, 3);
  }
  for (UInt i = 5; i * i <= N; i += 6) {
    if (!(N % i)) {
      P[cnt] = i;
      K[cnt++] = ImplFactorize<UInt, Count>(N, i);
    }
    if (!(N % (i + 2))) {
      P[cnt] = i + 2;
      K[cnt++] = ImplFactorize<UInt, Count>(N, i + 2);
    }
  }
  if (N != 1) {
    P[cnt] = N;
    K[cnt++] = 1;
  }
  return cnt;
}

constexpr int BitClz(unsigned int N) noexcept { return __builtin_clz(N); }
constexpr int BitClz(unsigned long N) noexcept { return __builtin_clzl(N); }
constexpr int BitClz(unsigned long long N) noexcept { return __builtin_clzll(N); }

constexpr int BitCtz(unsigned int N) noexcept { return __builtin_ctz(N); }
constexpr int BitCtz(unsigned long N) noexcept { return __builtin_ctzl(N); }
constexpr int BitCtz(unsigned long long N) noexcept { return __builtin_ctzll(N); }

template<class UInt>
constexpr int Log2P1(UInt N) noexcept {
  return ::std::numeric_limits<UInt>::digits - BitClz(N);
}

template<class UInt>
constexpr int Log2C(UInt N) noexcept { return N > 1 ? Log2P1(N - 1) : 0; }

// Next bit permutation
template<class UInt>
constexpr UInt NextPerm(UInt u) noexcept {
  auto t = u | (u - 1);
  return (t + 1) | (((~t & -~t) - 1) >> (BitCtz(u) + 1));
}

#include <algorithm>
#include <array>
#include <bitset>
#include <cctype>
#include <cinttypes>
#include <climits>
#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

int main() {
  constexpr auto Mod = 1000000007;
  int N;
  scanf("%d", &N);
  uint32_t mask = (1u << N) - 1;
  static int F[1 << 21];
  F[0] = 1;
  for (auto i = 0; i < N; ++i) {
    uint32_t s = 0;
    for (auto j = 0; j < N; ++j) {
      int x;
      scanf("%d", &x);
      s |= (uint32_t) x << j;
    }
    uint32_t t = (1u << (i + 1)) - 1;
    while (t <= mask) {
      auto u = s & t;
      for (auto v = u; v; ) {
        auto w = v & -v;
        v ^= w;
        F[t] = (F[t] + F[t ^ w]) % Mod;
      }
      t = NextPerm(t);
    }
  }
  printf("%d\n", F[mask]);
  return 0;
}


Measured memory_bytes: 8448