#include <bits/stdc++.h>
using namespace std;
using uint = unsigned int;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << H;
  debug_out(T...);
}
template <typename T1, typename T2>
ostream &operator<<(ostream &out, const pair<T1, T2> &item) {
  out << '(' << item.first << ", " << item.second << ')';
  return out;
}
template <typename T>
ostream &operator<<(ostream &out, const vector<T> &v) {
  for (const auto &item : v) out << item << ' ';
  return out;
}
const int N = 19;
int n;
int adj[N][N];
ll dp[N][1 << N], paths[N][1 << N], val[N][1 << N];
ll ans[1 << N];
vector<int> stk;
map<vector<int>, ll> m;
void dfs(int rem, int mx) {
  if (rem == 0) {
    int sz = stk.size();
    ll res = 0;
    for (int mask = 0; mask < (1 << n); ++mask) {
      int b = n - __builtin_popcount(mask);
      if (b & 1)
        res -= val[sz][mask];
      else
        res += val[sz][mask];
    }
    m[stk] = res;
    return;
  }
  int sz = stk.size();
  for (int i = 1; i <= mx && i <= rem; ++i) {
    for (int mask = 0; mask < (1 << n); ++mask)
      val[sz + 1][mask] = val[sz][mask] * dp[i][mask];
    stk.push_back(i);
    dfs(rem - i, i);
    stk.pop_back();
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  string s;
  cin >> n;
  for (int i = 0; i < n; ++i) {
    cin >> s;
    for (int j = 0; j < n; ++j) adj[i][j] = (s[j] == '1');
  }
  for (int i = 0; i < n; ++i) paths[i][1 << i] = 1;
  for (int mask = 1; mask < (1 << n); ++mask)
    for (int v = 0; v < n; ++v)
      for (int u = 0; u < n; ++u)
        if (!(mask & (1 << u)) && adj[v][u])
          paths[u][mask | (1 << u)] += paths[v][mask];
  for (int v = 0; v < n; ++v)
    for (int mask = 1; mask < (1 << n); ++mask)
      dp[__builtin_popcount(mask)][mask] += paths[v][mask];
  for (int len = 1; len <= n; ++len)
    for (int b = 0; b < n; ++b)
      for (int mask = 1; mask < (1 << n); ++mask)
        if (mask & (1 << b)) dp[len][mask] += dp[len][mask ^ (1 << b)];
  for (int mask = 0; mask < (1 << n); ++mask) val[0][mask] = 1;
  dfs(n, n);
  for (int mask = 0; mask < (1 << (n - 1)); ++mask) {
    vector<int> ms;
    for (int i = 0; i < n; ++i) {
      int nr = 1;
      while (i < n && (mask & (1 << i))) ++i, ++nr;
      ms.push_back(nr);
    }
    sort(ms.begin(), ms.end());
    reverse(ms.begin(), ms.end());
    ans[mask] = m[ms];
  }
  for (int b = 0; b < n - 1; ++b)
    for (int mask = 1; mask < (1 << (n - 1)); ++mask)
      if (mask & (1 << b)) ans[mask ^ (1 << b)] -= ans[mask];
  for (int i = 0; i < (1 << (n - 1)); ++i) cout << ans[i] << ' ';
  cout << '\n';
  return 0;
}
