#include <bits/stdc++.h>
using namespace std;
const int M = 1000000007;
const int MM = 998244353;
const long double PI = acos(-1);
long long power(long long b, long long e, long long m) {
  if (e == 0) return 1;
  if (e & 1) return b * power(b * b % m, e / 2, m) % m;
  return power(b * b % m, e / 2, m);
}
long long power(long long b, long long e) {
  if (e == 0) return 1;
  if (e & 1) return b * power(b * b, e / 2);
  return power(b * b, e / 2);
}
template <typename T, typename U>
static inline void amin(T &x, U y) {
  if (y < x) x = y;
}
template <typename T, typename U>
static inline void amax(T &x, U y) {
  if (x < y) x = y;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << '(' << p.first << "," << p.second << ')';
}
struct node {
  int x, y, w;
  node(int w_, int x_, int y_) : w(w_), x(x_), y(y_) {}
};
const int N = 1502;
const int mod = MM;
vector<long long> v[N];
int a[N][N];
int p[N], r[N];
int mx[N];
vector<int> el[N];
int parent(int i) { return p[i] = (p[i] == i) ? p[i] : parent(p[i]); }
void merge(int x, int y, int w) {
  x = parent(x), y = parent(y);
  if (x == y) {
    if (mx[x] == w) {
      ++v[y][1];
      v[y][1] %= mod;
    }
    return;
  }
  if (r[x] > r[y]) swap(x, y);
  if (r[x] == r[y]) ++r[y];
  amax(mx[y], mx[x]);
  for (auto &j : el[x]) {
    for (auto &k : el[y]) amax(mx[y], a[j][k]);
  }
  vector<long long> t = v[y];
  v[y].resize((long long)v[y].size() + (long long)v[x].size());
  for (int i = 0; i < (long long)v[y].size(); ++i) v[y][i] = 0;
  for (int i = 0; i < (long long)v[x].size(); ++i) {
    for (int j = 0; j < (long long)t.size(); ++j) {
      (v[y][(i + j)] += v[x][i] * t[j] % mod) %= mod;
    }
  }
  for (auto &j : el[x]) el[y].push_back(j);
  el[x].clear();
  p[x] = y;
  if (mx[y] == w) {
    ++v[y][1];
    v[y][1] %= mod;
  }
}
int _runtimeTerror_() {
  int n;
  cin >> n;
  int m = 1;
  while (m < n + 1) m <<= 1;
  for (int i = 1; i <= n; ++i) {
    el[i].push_back(i);
    mx[i] = 0;
    p[i] = i, r[i] = 0;
    v[i].push_back(0);
    v[i].push_back(1);
  }
  vector<node> ed;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      int x;
      cin >> x;
      a[i][j] = x;
      ed.push_back(node(x, i, j));
    }
  }
  sort(ed.begin(), ed.end(), [&](node a, node b) { return a.w < b.w; });
  for (auto &j : ed) {
    if (j.x < j.y) merge(j.x, j.y, j.w);
  }
  int u = parent(1);
  for (int i = 1; i <= n; ++i) cout << v[u][i] << " ";
  cout << "\n";
  return 0;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int TESTS = 1;
  while (TESTS--) _runtimeTerror_();
  return 0;
}
