#include <bits/stdc++.h>
using namespace std;
const int nsz = 18, msksz = (1 << nsz) - 1;
char s[nsz + 5], lg[msksz + 5];
int n, m, full, g[nsz + 5];
long long dp[msksz + 5][nsz + 5], f[nsz + 5][msksz + 5], r[nsz + 5][msksz + 5],
    ans[msksz + 5];
map<vector<int>, int> to;
map<vector<int>, long long> res;
void inline FWT(int sz, long long *a) {
  for (int len = 1; len < sz; len <<= 1) {
    for (int l = 0; l < sz; l += len << 1) {
      long long *w0 = a + l, *w1 = a + len + l;
      for (int i = 0; i < len; ++i, ++w0, ++w1) *w1 += *w0;
    }
  }
}
void inline UFWT(int sz, long long *a) {
  for (int len = 1; len < sz; len <<= 1) {
    for (int l = 0; l < sz; l += len << 1) {
      long long *w0 = a + l, *w1 = a + len + l;
      for (int i = 0; i < len; ++i, ++w0, ++w1) *w1 -= *w0;
    }
  }
}
void dfs(int k = 0, int m = n, int lst = 1) {
  static vector<int> a;
  if (m == 0) {
    long long res = 0;
    for (int S = 0; S <= full; ++S)
      res += __builtin_popcount(S ^ full) & 1 ? -r[k][S] : +r[k][S];
    ::res[a] = res;
    return;
  }
  for (int d = lst; d <= m; ++d)
    if (d <= m - d || m - d == 0) {
      for (int S = 0; S <= full; ++S) r[k + 1][S] = r[k][S] * f[d][S];
      a.push_back(d);
      dfs(k + 1, m - d, d);
      a.pop_back();
    }
}
void inline init() {
  full = (1 << n) - 1, m = (1 << (n - 1)) - 1;
  for (int i = 0; i < n; ++i) lg[1 << i] = i;
  for (int u = 0; u < n; ++u) dp[1 << u][u] = 1;
  for (int S = 1; S <= full; ++S) {
    for (int t = S, d = t & -t; d; t -= d, d = t & -t) {
      int u = lg[d];
      if (!dp[S][u]) continue;
      for (int t = (S ^ full) & g[u], d = t & -t; d; t -= d, d = t & -t) {
        int v = lg[d];
        dp[S | (1 << v)][v] += dp[S][u];
      }
    }
  }
  for (int S = 0; S <= full; ++S) {
    int len = __builtin_popcount(S);
    for (int u = 0; u < n; ++u) f[len][S] += dp[S][u];
  }
  for (int i = 0; i < n; ++i) FWT(1 << n, f[i]);
  for (int S = 0; S <= full; ++S) r[0][S] = 1;
  dfs();
}
void inline solve() {
  for (int S = 0; S <= m; ++S) {
    vector<int> d;
    int cur = 1;
    for (int i = 0; i < n - 1; ++i) {
      int c = (S >> i) & 1;
      if (c == 0)
        d.push_back(cur), cur = 1;
      else
        cur += 1;
    }
    d.push_back(cur);
    sort(d.begin(), d.end());
    ans[S ^ m] = res[d];
  }
  UFWT(1 << (n - 1), ans);
  reverse(ans, ans + m + 1);
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n; ++i) {
    scanf("%s", s);
    for (int j = 0; j < n; ++j)
      if (s[j] ^ 48) g[i] |= 1 << j;
  }
  init();
  solve();
  for (int S = 0; S <= m; ++S) printf("%lld%c", ans[S], "\n "[S < m]);
}
