#include <bits/stdc++.h>
using std::bitset;
using std::cerr;
using std::cin;
using std::cout;
using std::deque;
using std::endl;
using std::fill;
using std::fixed;
using std::ios_base;
using std::iterator;
using std::map;
using std::max_element;
using std::min_element;
using std::multimap;
using std::multiset;
using std::pair;
using std::queue;
using std::reverse;
using std::set;
using std::setprecision;
using std::sort;
using std::stable_sort;
using std::stack;
using std::string;
using std::swap;
using std::unique;
using std::vector;
long long min(long long a, long long b) { return a < b ? a : b; }
long long min(int a, long long b) { return a < b ? a : b; }
long long min(long long a, int b) { return a < b ? a : b; }
long long min(int a, int b) { return a < b ? a : b; }
long long max(long long a, long long b) { return a > b ? a : b; }
long long max(int a, long long b) { return a > b ? a : b; }
long long max(long long a, int b) { return a > b ? a : b; }
long long max(int a, int b) { return a > b ? a : b; }
namespace MySpace {};
const int N = 16;
const int MOD = 998244353;
int n;
string s[N];
long long g[(1 << N)];
long long dp[N][(1 << N)];
long long ans[(1 << N) / 2];
vector<int> a;
vector<int> fr[1 << N][N + 1];
vector<int> with[N + 1];
vector<long long> dp2(1 << N);
void check() {
  fill((dp2).begin(), (dp2).end(), 0);
  dp2[0] = 1;
  int y = 0;
  for (int i = 0; i < a.size(); i++) {
    int x = a[i];
    y += x;
    for (auto mask2 : with[y]) {
      for (auto mask1 : fr[mask2][y - x]) {
        dp2[mask2] += g[mask2 - mask1] * dp2[mask1];
      }
    }
  }
  int mask = 0;
  for (int i = 0; i < a.size(); i++) {
    for (int j = 0; j < a[i] - 1; j++) {
      mask = 2 * mask + 1;
    }
    mask = 2 * mask;
  }
  mask /= 2;
  ans[mask] += dp2[(1 << n) - 1];
  return;
}
void rec(int x, int lst) {
  if (x == 0) {
    check();
    return;
  }
  for (int i = lst; i <= x; i++) {
    a.push_back(i);
    rec(x - i, i);
    a.pop_back();
  }
  return;
}
signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  for (int i = 0; i < (1 << N); i++) {
    with[__builtin_popcount(i)].push_back(i);
    for (int mask = i;; mask = (mask - 1) & i) {
      fr[i][__builtin_popcount(mask)].push_back(mask);
      if (mask == 0) break;
    }
  }
  cin >> n;
  for (int i = 0; i < n; i++) {
    cin >> s[i];
  }
  for (int i = 0; i < n; i++) {
    dp[i][(1 << i)] = 1;
  }
  for (int mask = 0; mask < (1 << n); mask++) {
    for (int i = 0; i < n; i++) {
      if ((1 << i) & mask) {
        int k = mask - (1 << i);
        if (k != 0) {
          for (int j = 0; j < n; j++) {
            if ((1 << j) & k) {
              if (s[i][j] == '1') {
                dp[i][mask] += dp[j][k];
              }
            }
          }
        }
      }
    }
  }
  for (int mask = 0; mask < (1 << n); mask++) {
    for (int i = 0; i < n; i++) {
      g[mask] += dp[i][mask];
    }
  }
  rec(n, 1);
  for (int mask = 0; mask < (1 << n) / 2; mask++) {
    vector<int> b;
    int len = 0;
    for (int i = 0; i < n - 1; i++) {
      if (mask & (1 << i)) {
        len++;
      } else {
        b.push_back(len + 1);
        len = 0;
      }
    }
    b.push_back(len + 1);
    sort((b).begin(), (b).end());
    int mask_ = 0;
    for (int i = 0; i < b.size(); i++) {
      for (int j = 0; j < b[i] - 1; j++) {
        mask_ = 2 * mask_ + 1;
      }
      mask_ = 2 * mask_;
    }
    mask_ /= 2;
    ans[mask] = ans[mask_];
  }
  for (int mask = 0; mask < (1 << n) / 2; mask++) {
    for (int upmask = mask; upmask < (1 << n) / 2;
         upmask = (upmask + 1) | mask) {
      int b = __builtin_popcount(upmask - mask);
      if (b == 0) continue;
      if (b % 2 == 1)
        ans[mask] -= ans[upmask];
      else
        ans[mask] += ans[upmask];
    }
  }
  for (int i = 0; i < (1 << n) / 2; i++) {
    cout << ans[i] << " ";
  }
  return 0;
}
