#include <bits/stdc++.h>
using namespace std;
const int N = 1500 + 5, P = 998244353;
int n, m, cost[N][N], dp[N][N];
pair<int, int> edge[N * N];
int par[N], ed[N], sz[N];
int get_par(int u) { return ~par[u] ? par[u] = get_par(par[u]) : u; }
void merge(int u, int v) {
  ed[u = get_par(u)]++;
  v = get_par(v);
  if (u ^ v) {
    if (sz[u] < sz[v]) swap(u, v);
    for (int i = sz[u]; i; dp[u][i--] = 0)
      for (int j = sz[v]; j; j--)
        dp[u][i + j] = (1LL * dp[u][i] * dp[v][j] + dp[u][i + j]) % P;
    sz[par[v] = u] += sz[v];
    ed[u] += ed[v];
  }
  if (ed[u] == sz[u] * (sz[u] - 1) / 2) ++dp[u][1] %= P;
}
void sort_edges() {
  for (int u = 0; u < n; u++)
    for (int v = u + 1; v < n; v++) edge[m++] = {u, v};
  sort(edge, edge + m, [](pair<int, int> e1, pair<int, int> e2) {
    return cost[e1.first][e1.second] < cost[e2.first][e2.second];
  });
}
void calculate_dp() {
  memset(par, -1, sizeof par);
  for (int u = 0; u < n; u++) dp[u][1] = sz[u] = 1;
  for (int i = 0; i < m; i++) merge(edge[i].first, edge[i].second);
}
void read_input() {
  cin >> n;
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) cin >> cost[i][j];
}
void solve() {
  sort_edges();
  calculate_dp();
}
void write_output() {
  for (int i = 1; i <= n; i++) cout << dp[get_par(0)][i] << ' ';
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  read_input(), solve(), write_output();
  return 0;
}
