#include <bits/stdc++.h>
using namespace std;
template <class T>
void _R(T &x) {
  cin >> x;
}
void _R(int &x) { scanf("%d", &x); }
void _R(int64_t &x) { scanf("%lld", &x); }
void _R(double &x) { scanf("%lf", &x); }
void _R(char &x) { scanf(" %c", &x); }
void _R(char *x) { scanf("%s", x); }
void R() {}
template <class T, class... U>
void R(T &head, U &...tail) {
  _R(head);
  R(tail...);
}
template <class T>
void _W(const T &x) {
  cout << x;
}
void _W(const int &x) { printf("%d", x); }
void _W(const int64_t &x) { printf("%lld", x); }
void _W(const double &x) { printf("%.16f", x); }
void _W(const char &x) { putchar(x); }
void _W(const char *x) { printf("%s", x); }
template <class T, class U>
void _W(const pair<T, U> &x) {
  _W(x.first);
  putchar(' ');
  _W(x.second);
}
template <class T>
void _W(const vector<T> &x) {
  for (auto i = x.begin(); i != x.end(); _W(*i++))
    if (i != x.cbegin()) putchar(' ');
}
void W() {}
template <class T, class... U>
void W(const T &head, const U &...tail) {
  _W(head);
  putchar(sizeof...(tail) ? ' ' : '\n');
  W(tail...);
}
int MOD = 1e9 + 7;
void ADD(long long &x, long long v) {
  x = (x + v) % MOD;
  if (x < 0) x += MOD;
}
const int SIZE = 1 << 20;
vector<int> e[3005];
int ord[3005], ord_it;
int pos[3005];
int C2(int x) { return x * (x - 1) / 2; }
struct Union_Find {
  int d[3005], num[3005], rt[3005], e_num[3005];
  int ll[3005], rr[3005];
  int rt_id;
  void init(int n) {
    for (int i = 0; i < (n); ++i)
      d[i] = i, num[i] = 1, rt[i] = i, e_num[i] = 0, ll[i] = rr[i] = pos[i];
    rt_id = n;
  }
  int find(int x) {
    int y = x, z = x;
    while (y != d[y]) y = d[y];
    while (x != y) {
      x = d[x];
      d[z] = y;
      z = x;
    }
    return y;
  }
  bool is_root(int x) { return d[x] == x; }
  bool uu(int x, int y) {
    x = find(x);
    y = find(y);
    if (x == y) return 0;
    if (num[x] > num[y]) swap(x, y);
    num[y] += num[x];
    d[x] = y;
    e[rt_id].emplace_back(rt[x]);
    e[rt_id].emplace_back(rt[y]);
    e_num[y] += e_num[x];
    ll[y] = min(ll[y], ll[x]);
    rr[y] = max(rr[y], rr[x]);
    rt[y] = rt_id;
    rt_id++;
    return 1;
  }
} U;
void dfs(int x) {
  if (!((int)(e[x]).size())) {
    pos[x] = ord_it;
    ord[ord_it++] = x;
    return;
  }
  for (int y : e[x]) dfs(y);
}
pair<int, int> d[1125000];
int a[1505][1505];
long long dp[1505][1505];
vector<int> ker[1505];
void solve() {
  int n;
  R(n);
  for (int i = 0; i < (n); ++i)
    for (int j = 0; j < (n); ++j) {
      R(a[i][j]);
      if (i < j) d[a[i][j]] = make_pair(i, j);
    }
  U.init(n);
  for (int i = (1); i <= (n * (n - 1) / 2); ++i) {
    U.uu(d[i].first, d[i].second);
  }
  dfs(U.rt_id - 1);
  U.init(n);
  for (int i = 0; i < (n); ++i) ker[i].emplace_back(i);
  for (int i = (1); i <= (n * (n - 1) / 2); ++i) {
    U.uu(d[i].first, d[i].second);
    int g_id = U.find(d[i].first);
    U.e_num[g_id]++;
    if (U.e_num[g_id] == C2(U.num[g_id])) {
      ker[U.ll[g_id]].emplace_back(U.rr[g_id]);
    }
  }
  dp[0][0] = 1;
  MOD = 998244353;
  for (int x = 0; x < (n); ++x) {
    for (int y : ker[x]) {
      for (int j = 0; j < (n); ++j) {
        ADD(dp[y + 1][j + 1], dp[x][j]);
      }
    }
  }
  W(vector<int>(dp[n] + 1, dp[n] + n + 1));
}
void input() {}
int main() {
  input();
  solve();
  return 0;
}
