#include <bits/stdc++.h>
using std::cin;
using std::cout;
using std::endl;
using std::memset;
using std::swap;
const int MAX_N = 3030;
const long long MOD = 998244353, MOD2 = MOD * MOD;
long long sqr(long long x) { return x * x % MOD; }
long long qpow(long long a, long long b) {
  return b ? sqr(qpow(a, b / 2)) * (b & 1 ? a : 1) % MOD : 1;
}
long long inv(long long x) { return qpow(x, MOD - 2); }
int N, M, C, A[MAX_N], ans[MAX_N];
void add(int &a, int b) {
  a += b;
  if (a >= MOD) a -= MOD;
}
namespace solve1 {
int cnt[MAX_N], bound[MAX_N];
long long P[MAX_N][MAX_N], p2m1[MAX_N], ip2m1[MAX_N];
long long f[MAX_N][MAX_N], g[MAX_N];
struct Table {
  int cnt0;
  long long a[MAX_N], res;
  void init() {
    cnt0 = C;
    res = 1;
    for (int i = 1; i <= N; i++) a[i] = 0;
  }
  void set(int x, int y) {
    if (a[x]) {
      if (!y) cnt0++;
      (res *= ip2m1[a[x]]) %= MOD;
      if (y) (res *= p2m1[y]) %= MOD;
    } else {
      if (y) cnt0--;
      if (y) (res *= p2m1[y]) %= MOD;
    }
    a[x] = y;
  }
  long long query(int x) { return cnt0 ? 0 : res * ip2m1[a[x]]; }
} tab;
void solve() {
  p2m1[0] = 0;
  for (int i = 1; i <= N; i++) p2m1[i] = (p2m1[i - 1] * 2 + 1) % MOD;
  for (int i = 0; i <= N; i++) ip2m1[i] = inv(p2m1[i]);
  for (int i = 1; i <= N; i++) {
    tab.init();
    memset(cnt, 0, sizeof(cnt));
    long long last = 0;
    for (int j = i; j <= N; j++) {
      tab.set(A[j], ++cnt[A[j]]);
      P[j][i] = (tab.query(A[j]) - last + MOD) % MOD;
    }
  }
  for (int i = 1; i <= N; i++)
    for (int j = i; j; j--)
      if (P[i][j]) {
        bound[i] = bound[j - 1] + 1;
        break;
      }
  f[0][0] = 1;
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= bound[i]; j++) {
      for (int k = 1; k <= i; k++) {
        f[j][i] += P[i][k] * f[j - 1][k - 1];
        if ((k & 7) == 0) f[j][i] %= MOD;
      }
      f[j][i] %= MOD;
    }
  for (int i = 0; i <= N; i++)
    for (int j = 0; j <= M; j++) (g[j] += f[j][i] * (p2m1[N - i] + 1)) %= MOD;
  for (int i = 0; i < M; i++) g[i] = (g[i] + MOD - g[i + 1]) % MOD;
  (g[0] += MOD - 1) %= MOD;
  for (int i = 0; i <= M; i++) ans[i] = g[i];
}
}  // namespace solve1
namespace solve2 {
const int MAX_C = 12;
struct State {
  int v[MAX_N][1 << MAX_C];
  void clear() {
    for (int i = 0; i <= M; i++)
      for (int j = 0; j < 1 << C; j++) v[i][j] = 0;
  }
} * last, *curr;
int g[MAX_N];
void solve() {
  last = new State;
  curr = new State;
  curr->v[0][0] = 1;
  for (int i = 1; i <= N; i++) {
    swap(curr, last);
    curr->clear();
    for (int j = 0; j <= M; j++) {
      for (int k = 0; k < 1 << C; k++) {
        add(curr->v[j][k], last->v[j][k]);
        int nk = k | 1 << A[i] - 1;
        if (nk < (1 << C) - 1)
          add(curr->v[j][nk], last->v[j][k]);
        else
          add(curr->v[j + 1][0], last->v[j][k]);
      }
    }
  }
  for (int i = 0; i <= M; i++)
    for (int j = 0; j < 1 << C; j++) add(g[i], curr->v[i][j]);
  add(g[0], MOD - 1);
  for (int i = 0; i <= M; i++) ans[i] = g[i];
}
}  // namespace solve2
int main() {
  cin >> N >> C;
  M = N / C;
  for (int i = 1; i <= N; i++) cin >> A[i];
  if (C > 11)
    solve1::solve();
  else
    solve2::solve();
  for (int i = 0; i <= N; i++) cout << ans[i] << " ";
  cout << endl;
}
