#include <bits/stdc++.h>
using namespace std;
const int N = 23, M = 270000;
int n, a[N][N];
long long dp[M][N], f[N][M], ans[M], h[400];
int bitread() {
  char ch = getchar();
  while (ch < '0' || ch > '1') ch = getchar();
  return ch - '0';
}
int bitcnt(int x) {
  int ret = 0;
  for (int i = 31; i >= 0; --i) ret += ((x >> i) & 1);
  return ret;
}
int cnt;
map<vector<int>, int> mp;
vector<int> vec[400], tmp;
void dfs(int cur, int las) {
  if (cur == n + 1) {
    mp[tmp] = ++cnt;
    vec[cnt] = tmp;
    return;
  }
  if (n - cur + 1 < las) return;
  for (int i = las; i + cur - 1 <= n; ++i) {
    tmp.push_back(i);
    dfs(cur + i, i);
    tmp.pop_back();
  }
}
void fwt_or(long long *g, int n, int type) {
  for (int mid = 1; mid < n; mid <<= 1)
    for (int j = 0; j < n; j += (mid << 1))
      for (int k = 0; k < mid; ++k) g[j + mid + k] += g[j + k] * type;
}
void fwt_and(long long *g, int n, int type) {
  for (int mid = 1; mid < n; mid <<= 1)
    for (int j = 0; j < n; j += (mid << 1))
      for (int k = 0; k < mid; ++k) g[j + k] += g[j + mid + k] * type;
}
long long ie[M], cur[M];
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) a[i][j] = bitread();
  }
  dfs(1, 1);
  for (int i = 1; i <= n; ++i) dp[1 << (i - 1)][i] = 1;
  int S = 1 << n;
  for (int s = 1; s < S; ++s) {
    for (int j = 1; j <= n; ++j)
      if (s & (1 << (j - 1)))
        for (int k = 1; k <= n; ++k)
          if (a[j][k] && !(s & (1 << (k - 1))))
            dp[s | (1 << (k - 1))][k] += dp[s][j];
    int t = bitcnt(s);
    for (int j = 1; j <= n; ++j) f[t][s] += dp[s][j];
  }
  for (int i = 1; i <= n; ++i) fwt_or(f[i], S, 1);
  ie[0] = 1;
  fwt_or(ie, S, 1);
  for (int i = 1; i <= cnt; ++i) {
    for (int s = 0; s < S; ++s) cur[s] = ie[s];
    for (int j = 0; j < vec[i].size(); ++j)
      for (int k = 0; k < S; ++k) {
        cur[k] = cur[k] * f[vec[i][j]][k];
      }
    fwt_or(cur, S, -1);
    h[i] = cur[S - 1];
  }
  S >>= 1;
  for (int s = 0; s < S; ++s) {
    tmp.clear();
    for (int j = 0; j <= n - 1;) {
      int pos = j + 1;
      while (pos <= n - 1 && (s & (1 << (pos - 1)))) ++pos;
      tmp.push_back(pos - j);
      j = pos;
    }
    sort(tmp.begin(), tmp.end());
    assert(mp.count(tmp));
    ans[s] = h[mp[tmp]];
  }
  fwt_and(ans, S, -1);
  for (int s = 0; s < S; ++s) printf("%lld ", ans[s]);
  return 0;
}
