#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T read() {
  T f = 0, x = 0;
  char c = getchar();
  while (!isdigit(c)) f = c == '-', c = getchar();
  while (isdigit(c)) x = x * 10 + c - 48, c = getchar();
  return f ? -x : x;
}
namespace run {
inline char getc() {
  char c = getchar();
  while (c != '0' && c != '1') c = getchar();
  return c;
}
const long long N = 21;
long long siz[1 << 18], n, f[N][1 << 18], g[1 << 18], h[N][1 << 18], limit;
bool ok[N][N];
vector<long long> tmp;
map<vector<long long>, long long> mp;
inline void fwt_or(long long *a, long long opt) {
  for (long long mid = 1; mid < limit; mid <<= 1)
    for (long long i = 0, R = mid << 1; i < limit; i += R)
      for (long long j = 0; j < mid; j++)
        a[i + j + mid] = a[i + j + mid] + (opt ? a[i + j] : -a[i + j]);
}
inline void fwt_and(long long *a, long long opt) {
  for (long long mid = 1; mid < limit; mid <<= 1)
    for (long long i = 0, R = mid << 1; i < limit; i += R)
      for (long long j = 0; j < mid; j++)
        a[i + j] = a[i + j] + (opt ? a[i + j + mid] : -a[i + j + mid]);
}
long long ans[N][1 << 18];
inline void dfs(long long sum, long long lst, long long dep) {
  if (sum == n) {
    fwt_or(ans[dep], 0), mp[tmp] = ans[dep][limit - 1];
    return;
  }
  for (long long i = lst; i <= n - sum; i++)
    if (n - sum - i >= i || n == sum + i) {
      for (long long j = 0; j < limit; j++)
        ans[dep + 1][j] = ans[dep][j] * h[i][j];
      tmp.push_back(i);
      dfs(sum + i, i, dep + 1);
      tmp.pop_back();
    }
}
long long main() {
  n = read<long long>(), limit = 1 << n;
  for (long long i = 1; i <= n; i++)
    for (long long j = 1; j <= n; j++) ok[i][j] = getc() - '0';
  for (long long i = 1; i < limit; i++) siz[i] = siz[i >> 1] + (i & 1);
  for (long long i = 0; i < n; i++) f[i + 1][1 << i] = 1;
  for (long long s = 0; s < limit; s++)
    for (long long i = 1; i <= n; i++) {
      for (long long j = 0; j < n; j++)
        if (ok[i][j + 1] && !((s >> j) & 1)) f[j + 1][s ^ (1 << j)] += f[i][s];
      g[s] += f[i][s];
    }
  for (long long i = 0; i < limit; i++) h[siz[i]][i] = g[i];
  for (long long i = 0; i <= n; i++) fwt_or(h[i], 1);
  for (long long i = 0; i < limit; i++) ans[0][i] = 1;
  dfs(0, 1, 0);
  for (long long i = 0; i < limit >> 1; i++) {
    tmp.clear();
    long long len = 1;
    for (long long j = 0; j < n; j++)
      if ((i >> j) & 1)
        len++;
      else
        tmp.push_back(len), len = 1;
    sort(tmp.begin(), tmp.end());
    g[i] = mp[tmp];
  }
  limit /= 2, fwt_and(g, 0);
  for (long long i = 0; i < limit; i++) printf("%lld ", g[i]);
  return 0;
}
}  // namespace run
int main() { return run::main(); }
