import java.io.*;
import java.util.*;
import java.lang.*;

public class Solution {
    public static void main(String[] args)
        throws Exception {
        new Solution().start();
    }

    public void start()
        throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        calc(br);
    }

    void calc(BufferedReader br) throws Exception {
        String[] line1 = br.readLine().split(" ");
        String line2 = br.readLine();
        int x = Integer.parseInt(line1[2]);
        int y = Integer.parseInt(line1[3]);
        int maxX = Integer.parseInt(line1[0]);
        int maxY = Integer.parseInt(line1[1]);

        HashSet<List<Integer>> set = new HashSet<List<Integer>>();
        System.out.print("1");
        int cnt = 1;
        for (int i = 0; i <= line2.length() - 2; i++) {
            char c = line2.charAt(i);
            switch(c) {
                case 'U':
                    if (x - 1 > 0) {
                        x--;
                    }
                    break;
                case 'D':
                    if (x + 1 <= maxX) {
                        x++;
                    }
                    break;
                case 'L':
                    if (y - 1 > 0) {
                        y--;
                    }
                    break;
                case 'R':
                    if (y + 1 <= maxY) {
                        y++;
                    }
                    break;
                default:
                    break;
            }
            List<Integer> list = new ArrayList<Integer>();
            list.add(x);
            list.add(y);
            if (set.contains(list) == false) {
                System.out.print(" 1");
                set.add(list);
                cnt++;
            } else {
                System.out.print(" 0");
            }
        }
        char c = line2.charAt(line2.length() - 1);
        switch(c) {
            case 'U':
                if (x - 1 > 0) {
                    x--;
                }
                break;
            case 'D':
                if (x + 1 <= maxX) {
                    x++;
                }
                break;
            case 'L':
                if (y - 1 > 0) {
                    y--;
                }
                break;
            case 'R':
                if (y + 1 <= maxY) {
                    y++;
                }
                break;
            default:
                break;
        }
        List<Integer> list = new ArrayList<Integer>();
        list.add(x);
        list.add(y);
        System.out.print(" " + ((maxX * maxY) - cnt));
    }
}


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<10)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		FOR(i,1,c) cnt[i] = 0;now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n-1){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n/c){
			reset();
			ROF(i,n,0){
				if(!f[i][j]){
					add(a[i]);continue;
				}
				int t=0;
				t = pw[n-i];
				if(now == c) ::add(t,ha-sm);
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 10) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<11)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		FOR(i,1,c) cnt[i] = 0;now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n-1){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n/c){
			reset();
			ROF(i,n,0){
				if(!f[i][j]){
					add(a[i]);continue;
				}
				int t=0;
				t = pw[n-i];
				if(now == c) ::add(t,ha-sm);
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 11) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define U unsigned
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<10)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			CLR(f[now^1],0);
			FOR(j,0,(i-1)/c){
				FOR(S,0,(1<<c)-2){
					if(!f[now][j][S]) continue;
					add(f[now^1][j][S],f[now][j][S]);
					int nxt = S|(1<<a[i]);
					add(f[now^1][j+(nxt==((1<<c)-1))][nxt==((1<<c)-1)?0:nxt],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		CLR(cnt,0);now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n){
			reset();
			ROF(i,n,0){
				int t=0;
				if(now != c) t = pw[n-i];
				else t = (pw[n-i]+ha-sm) % ha;
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 10) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<10)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		FOR(i,1,c) cnt[i] = 0;now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n){
			reset();
			ROF(i,n,0){
				int t=0;
				t = pw[n-i];
				if(now == c) ::add(t,ha-sm);
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 0) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<10)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		FOR(i,1,c) cnt[i] = 0;now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n-1){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n){
			reset();
			ROF(i,n,0){
				if(!f[i][j]) continue;
				int t=0;
				t = pw[n-i];
				if(now == c) ::add(t,ha-sm);
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 10) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<10)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		CLR(cnt,0);now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n){
			reset();
			ROF(i,n,0){
				int t=0;
				if(now != c) t = pw[n-i];
				else t = (pw[n-i]+ha-sm) % ha;
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 10) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<12)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		FOR(i,1,c) cnt[i] = 0;now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n-1){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n/c){
			reset();
			ROF(i,n,0){
				if(!f[i][j]){
					add(a[i]);continue;
				}
				int t=0;
				t = pw[n-i];
				if(now == c) ::add(t,ha-sm);
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 12) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<10)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		FOR(i,1,c) cnt[i] = 0;now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n){
			reset();
			ROF(i,n,0){
				int t=0;
				t = pw[n-i];
				if(now == c) ::add(t,ha-sm);
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 10) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<10)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		FOR(i,1,c) cnt[i] = 0;now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n-1){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n){
			reset();
			ROF(i,n,0){
				if(!f[i][j]){
					add(a[i]);continue;
				}
				int t=0;
				t = pw[n-i];
				if(now == c) ::add(t,ha-sm);
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 10) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include <bits/stdc++.h>

#define fi first
#define se second
#define db double
#define P std::pair<int,int>
#define LL long long
#define pb push_back
#define MP std::make_pair
#define all(x) x.begin(),x.end()
#define CLR(i,a) memset(i,a,sizeof(i))
#define FOR(i,a,b) for(int i = a;i <= b;++i)
#define ROF(i,a,b) for(int i = a;i >= b;--i)
#define DEBUG(x) std::cerr << #x << '=' << x << std::endl

const int MAXN = 3000+5;
const int ha = 998244353;
int n,c,a[MAXN];

inline void add(int &x,int y){
	x += y;if(x >= ha) x -= ha;
}

int ans[MAXN];

inline int qpow(int a,int n=ha-2){
	int res = 1;
	while(n){
		if(n & 1) res = 1ll*res*a%ha;
		a = 1ll*a*a%ha;
		n >>= 1;
	}
	return res;
}

namespace Subtask1{ // O(n^2/c * 2^c)
	int f[2][MAXN][(1<<10)+3],now;
	// 考虑了前i个数 凑了j个[1..c],当前段哪些还没凑
	inline void Solve(){
		int U = (1<<c)-1;
		f[now=0][0][0] = 1;FOR(i,1,n) --a[i];
		FOR(i,1,n){
			FOR(j,0,(i-1)/c) FOR(S,0,U-1) f[now^1][j][S] = f[now][j][S];
			int t = (1<<a[i]);
			FOR(j,0,(i-1)/c){
				FOR(S,0,U-1){
					if(!f[now][j][S]) continue;
					int nS = S|t,nj = j;
					if(nS == U) nS = 0,nj = j+1;
					add(f[now^1][nj][nS],f[now][j][S]);
				}
			}
			now ^= 1;
		}
		FOR(S,0,(1<<c)-2) FOR(j,0,n/c) add(ans[j],f[now][j][S]);
		add(ans[0],ha-1);// 空
	}
}

namespace Subtask2{
	int f[MAXN][MAXN],g[MAXN][MAXN];
	/*
	f[i][j]: 最后一次选的是i,搞出了j个段
	转移需要预处理 g[i][j]: 最后一次选的是j,选出了一段 计算g只需要得到出现次数就行了
	*/
	int cnt[MAXN],now,sm;
	int pw[MAXN],inv[MAXN];

	inline void reset(){
		FOR(i,1,c) cnt[i] = 0;now = 0;sm = 1;
	}

	inline void add(int x){
		if(!cnt[x]){
			++cnt[x];++now;
			return;
		}
		sm = 1ll*sm*inv[cnt[x]]%ha;
		++cnt[x];
		sm = 1ll*sm*(pw[cnt[x]]+ha-1)%ha;
	}

	inline void Solve(){
		pw[0] = 1;FOR(i,1,MAXN-1) pw[i] = 2ll*pw[i-1]%ha;
		FOR(i,0,MAXN-1) inv[i] = qpow((pw[i]+ha-1)%ha);
		FOR(r,1,n){
			reset();
			ROF(l,r,1){
				add(a[l]);
				if(now != c) g[l][r] = 0;
				else g[l][r] = 1ll*sm*inv[cnt[a[r]]]%ha;
			}
		}
		f[0][0] = 1;
		FOR(i,0,n-1){
			FOR(j,0,i/c){
				if(!f[i][j]) continue;
				FOR(k,i+c,n){
					::add(f[k][j+1],1ll*f[i][j]*g[i+1][k]%ha);
				}
			}
		}
		// DEBUG(f[2][2]);
		// exit(0);
		FOR(j,0,n/c){
			reset();
			ROF(i,n,0){
				if(!f[i][j]){
					add(a[i]);continue;
				}
				int t=0;
				t = pw[n-i];
				if(now == c) ::add(t,ha-sm);
				::add(ans[j],1ll*f[i][j]*t%ha);
				add(a[i]);
			}
		}
		::add(ans[0],ha-1);
	}
}

int main(){
	scanf("%d%d",&n,&c);
	FOR(i,1,n) scanf("%d",a+i);
	if(c <= 11) Subtask1::Solve();
	else Subtask2::Solve();
	FOR(i,0,n) printf("%d ",ans[i]);puts("");
	return 0;
}
/*
复杂度 O(n^3/log)
*/


#include<bits/stdc++.h>
using namespace std;
const int B=11;
const int maxn=3003;
const int mod=998244353;
int n,m,K;
int a[maxn],P[maxn],Inv[maxn];
int dp[maxn][maxn];
int f[maxn],cnt[maxn];
int g[maxn][1<<B|1];
inline int Pow(int a,int n){
	int ans=1;
	for(;n;n>>=1,a=a*1ll*a%mod)if(n&1)ans=ans*1ll*a%mod;
	return ans;
}
inline void Run_1(){
	int Lim=(1<<m)-1;
	g[0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=K;j>=0;j--){
			dp[j+1][i]=g[j][Lim^(1<<a[i]-1)];
			for(int S=Lim-1;S>=0;S--){
				if((S|(1<<a[i]-1))==Lim)(g[j+1][0]+=g[j][S])%=mod;
				else (g[j][S|(1<<a[i]-1)]+=g[j][S])%=mod;
			}
		}
	}
}
inline void Run_2(){
	dp[0][0]=1;
	for(int i=1;i<=K;i++){
		for(int j=1;j<=n;j++){
			memset(cnt,0,sizeof(int)*(m+3));
			++cnt[a[j]];
			int Bas=1,C=1;
			for(int k=j-1;k>=0;k--){
				if(C==m)(dp[i][j]+=dp[i-1][k]*1ll*Bas%mod)%=mod;
				if(a[k]!=a[j]){
					C+=(!cnt[a[k]]);
					Bas=Bas*1ll*Inv[cnt[a[k]]]%mod*(P[++cnt[a[k]]]-1+mod)%mod;
				}
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);K=n/m;
	P[0]=Inv[0]=1;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]),P[i]=P[i-1]*2%mod;
		Inv[i]=Pow(P[i]-1+mod,mod-2);
	}
	if(m<=B)Run_1();
	else Run_2();
	for(int i=1;i<=K;i++)
		for(int j=1;j<=n;j++)
			(f[i]+=dp[i][j]*1ll*P[n-j]%mod)%=mod;
	f[0]=(P[n]-1+mod)%mod;
	for(int i=0;i<=n;i++)printf("%d ",(f[i]-f[i+1]+mod)%mod);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int B=11;
const int maxn=3003;
const int mod=998244353;
int n,m,K;
int a[maxn],P[maxn],Inv[maxn];
int dp[maxn][maxn];
int f[maxn],cnt[maxn];
int g[maxn][1<<B|1];
inline int Pow(int a,int n){
	int ans=1;
	for(;n;n>>=1,a=a*1ll*a%mod)if(n&1)ans=ans*1ll*a%mod;
	return ans;
}
inline void Run_1(){
	int Lim=(1<<m)-1;
	g[0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=K;j>=0;j--){
			dp[j+1][i]=g[j][Lim^(1<<a[i]-1)];
			for(int S=Lim-1;S>=0;S--){
				if((S|(1<<a[i]-1))==Lim)(g[j+1][0]+=g[j][S])%=mod;
				else (g[j][S|(1<<a[i]-1)]+=g[j][S])%=mod;
			}
		}
	}
}
int num[maxn][maxn];
inline void Run_2(){
	dp[0][0]=1;
	for(int r=1;r<=n;r++){
		memset(cnt,0,sizeof(int)*(m+3));
		++cnt[a[r]];
		int Bas=1,C=1;
		for(int l=r-1;l>=0;l--){
			if(C==m)num[l+1][r]=Bas;
			if(a[l]!=a[r]){
				C+=(!cnt[a[l]]);
				Bas=Bas*1ll*Inv[cnt[a[l]]]%mod*(P[++cnt[a[l]]]-1+mod)%mod;
			}
		}
	}
	static unsigned long long Inf=17e18;
	for(int i=1;i<=K;i++){
		for(int j=1;j<=n;j++){
			int Bas=1,C=1;
			unsigned long long tmp=0;
			for(int k=j-1;k>=0;k--)if(dp[i-1][k]&&num[k+1][j]){
				tmp+=dp[i-1][k]*1ll*num[k+1][j];
				if(tmp>Inf)tmp%=mod;
			}
			dp[i][j]=tmp;
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);K=n/m;
	P[0]=Inv[0]=1;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]),P[i]=P[i-1]*2%mod;
		Inv[i]=Pow(P[i]-1+mod,mod-2);
	}
	if(m<=B)Run_1();
	else Run_2();
	for(int i=1;i<=K;i++)
		for(int j=1;j<=n;j++)
			(f[i]+=dp[i][j]*1ll*P[n-j]%mod)%=mod;
	f[0]=(P[n]-1+mod)%mod;
	for(int i=0;i<=n;i++)printf("%d ",(f[i]-f[i+1]+mod)%mod);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int B=11;
const int maxn=3003;
const int mod=998244353;
int n,m,K;
int a[maxn],P[maxn],Inv[maxn];
int dp[maxn][maxn];
int f[maxn],cnt[maxn];
int g[maxn][1<<B|1];
inline int Pow(int a,int n){
	int ans=1;
	for(;n;n>>=1,a=a*1ll*a%mod)if(n&1)ans=ans*1ll*a%mod;
	return ans;
}
inline void Run_1(){
	int Lim=(1<<m)-1;
	g[0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=K;j>=0;j--){
			dp[j+1][i]=g[j][Lim^(1<<a[i]-1)];
			for(int S=Lim-1;S>=0;S--){
				if((S|(1<<a[i]-1))==Lim)(g[j+1][0]+=g[j][S])%=mod;
				else (g[j][S|(1<<a[i]-1)]+=g[j][S])%=mod;
			}
		}
	}
}
inline void Run_2(){
	dp[0][0]=1;
	for(int i=1;i<=K;i++){
		for(int j=1;j<=n;j++){
			memset(cnt,0,sizeof(int)*(m+3));
			++cnt[a[j]];
			int Bas=1,C=1;
			for(int k=j-1;k>=0;k--){
				if(C==m)(dp[i][j]+=dp[i-1][k]*1ll*Bas%mod)%=mod;
				C+=(!cnt[a[k]]);
				Bas=Bas*1ll*Inv[cnt[a[k]]]%mod*(P[++cnt[a[k]]]-1+mod)%mod;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);K=n/m;
	P[0]=Inv[0]=1;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]),P[i]=P[i-1]*2%mod;
		Inv[i]=Pow(P[i]-1+mod,mod-2);
	}
	if(m<=B)Run_1();
	else Run_2();
	for(int i=1;i<=K;i++)
		for(int j=1;j<=n;j++)
			(f[i]+=dp[i][j]*1ll*P[n-j]%mod)%=mod;
	f[0]=(P[n]-1+mod)%mod;
	for(int i=0;i<=n;i++)printf("%d ",(f[i]-f[i+1]+mod)%mod);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int B=11;
const int maxn=3003;
const int mod=998244353;
int n,m,K;
int a[maxn],P[maxn],Inv[maxn];
int dp[maxn][maxn];
int f[maxn],cnt[maxn];
int g[maxn][1<<B|1];
inline int Pow(int a,int n){
	int ans=1;
	for(;n;n>>=1,a=a*1ll*a%mod)if(n&1)ans=ans*1ll*a%mod;
	return ans;
}
inline void Run_1(){
	int Lim=(1<<m)-1;
	g[0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=K;j>=0;j--){
			dp[j+1][i]=g[j][Lim^(1<<a[i]-1)];
			for(int S=Lim-1;S>=0;S--){
				if((S|(1<<a[i]-1))==Lim)(g[j+1][0]+=g[j][S])%=mod;
				else (g[j][S|(1<<a[i]-1)]+=g[j][S])%=mod;
			}
		}
	}
}
int num[maxn][maxn];
inline void Run_2(){
	dp[0][0]=1;
	for(int r=1;r<=n;r++){
		memset(cnt,0,sizeof(int)*(m+3));
		++cnt[a[r]];
		int Bas=1,C=1;
		for(int l=r-1;l>=0;l--){
			if(C==m)num[l+1][r]=Bas;
			if(a[l]!=a[r]){
				C+=(!cnt[a[l]]);
				Bas=Bas*1ll*Inv[cnt[a[l]]]%mod*(P[++cnt[a[l]]]-1+mod)%mod;
			}
		}
	}
	for(int i=1;i<=K;i++){
		for(int j=1;j<=n;j++){
			int Bas=1,C=1;
			for(int k=j-1;k>=0;k--)if(dp[i-1][k]&&num[k+1][j]){
				(dp[i][j]+=dp[i-1][k]*1ll*num[k+1][j]%mod)%=mod;
			}
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);K=n/m;
	P[0]=Inv[0]=1;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]),P[i]=P[i-1]*2%mod;
		Inv[i]=Pow(P[i]-1+mod,mod-2);
	}
	if(m<=B)Run_1();
	else Run_2();
	for(int i=1;i<=K;i++)
		for(int j=1;j<=n;j++)
			(f[i]+=dp[i][j]*1ll*P[n-j]%mod)%=mod;
	f[0]=(P[n]-1+mod)%mod;
	for(int i=0;i<=n;i++)printf("%d ",(f[i]-f[i+1]+mod)%mod);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int B=11;
const int maxn=3003;
const int mod=998244353;
int n,m,K;
int a[maxn],P[maxn],Inv[maxn];
int dp[maxn][maxn];
int f[maxn],cnt[maxn];
int g[maxn][1<<B|1];
inline int Pow(int a,int n){
	int ans=1;
	for(;n;n>>=1,a=a*1ll*a%mod)if(n&1)ans=ans*1ll*a%mod;
	return ans;
}
inline void Run_1(){
	int Lim=(1<<m)-1;
	g[0][0]=1;
	for(int i=1;i<=n;i++){
		for(int j=K;j>=0;j--){
			dp[j+1][i]=g[j][Lim^(1<<a[i]-1)];
			for(int S=Lim-1;S>=0;S--){
				if((S|(1<<a[i]-1))==Lim)(g[j+1][0]+=g[j][S])%=mod;
				else (g[j][S|(1<<a[i]-1)]+=g[j][S])%=mod;
			}
		}
	}
}
int num[maxn][maxn];
inline void Run_2(){
	dp[0][0]=1;
	for(int r=1;r<=n;r++){
		memset(cnt,0,sizeof(int)*(m+3));
		++cnt[a[r]];
		int Bas=1,C=1;
		for(int l=r-1;l>=0;l--){
			if(C==m)num[l+1][r]=Bas;
			if(a[l]!=a[r]){
				C+=(!cnt[a[l]]);
				Bas=Bas*1ll*Inv[cnt[a[l]]]%mod*(P[++cnt[a[l]]]-1+mod)%mod;
			}
		}
	}
	static unsigned long long Inf=17e18;
	for(int i=1;i<=K;i++){
		for(int j=1;j<=n;j++){
			int Bas=1,C=1;
			unsigned long long tmp=0;
			for(int k=j-1;k>=0;k--)if(dp[i-1][k]&&num[k+1][j]){
				tmp+=dp[i-1][k]*1ll*num[k+1][j];
				if(tmp>Inf)tmp%=mod;
			}
			dp[i][j]=tmp%mod;
		}
	}
}
int main(){
	scanf("%d%d",&n,&m);K=n/m;
	P[0]=Inv[0]=1;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]),P[i]=P[i-1]*2%mod;
		Inv[i]=Pow(P[i]-1+mod,mod-2);
	}
	if(m<=B)Run_1();
	else Run_2();
	for(int i=1;i<=K;i++)
		for(int j=1;j<=n;j++)
			(f[i]+=dp[i][j]*1ll*P[n-j]%mod)%=mod;
	f[0]=(P[n]-1+mod)%mod;
	for(int i=0;i<=n;i++)printf("%d ",(f[i]-f[i+1]+mod)%mod);
	return 0;
}


#include<bits/stdc++.h>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 3005;
const int mo = 998244353;

LL add(LL x,LL y){return x+y>=mo?x+y-mo:x+y;}
LL dec(LL x,LL y){return x<y?x-y+mo:x-y;}

LL quickmi(LL x,LL tim){
	LL ret=1;
	for(;tim;tim/=2,x=x*x%mo)
		if (tim&1)ret=ret*x%mo;
	return ret;
}

int n,m;
int a[N];
LL f[N][N],g[N][N];
LL sum[N][N];
int cnt[N];
LL mi[N],iv[N];
LL ny[N],ans[N];
int mul[N];

int main(){
//	freopen("data.in","r",stdin);
	n=get();m=get();
	fo(i,1,n)a[i]=get();
	mi[0]=1;
	fo(i,1,n)mi[i]=mi[i-1]*2%mo;
	fo(i,1,n)ny[i]=quickmi(mi[i]-1,mo-2);
	iv[0]=1;
	iv[1]=(mo+1)/2;
	fo(i,2,n)iv[i]=iv[i-1]*iv[1]%mo;
	int L=n/m;
	fo(i,1,n){
		fo(x,1,m)cnt[x]=0;
		int res=m;
		LL val=0;
		fo(j,i,n){
			int pr=res;
			cnt[a[j]]++;
			if (cnt[a[j]]==1)res--;
			if (!res){
				if (pr){
					val=1;
					fo(x,1,m)val=val*(mi[cnt[x]]-1)%mo;
				}
				else
					val=val*ny[cnt[a[j]]-1]%mo*(mi[cnt[a[j]]]-1)%mo;
			//	g[i][j]=val*ny[cnt[a[j]]]%mo;
				g[i][j]=val;
			}
		}
		fd(j,n,i)g[i][j]=dec(g[i][j],g[i][j-1]*2%mo);
	}
	if ((m>20)||(1<<m)>n){
		fo(i,1,n)f[i][1]=g[1][i];
		int L=n/m;
		fo(i,1,n)
			fo(j,1,L)
				fo(k,i+1,n)
				f[k][j+1]=(f[k][j+1]+f[i][j]*g[i+1][k])%mo;
	}
	else{
		fo(i,1,n)f[i][1]=g[1][i];
		fo(i,1,n){
			fo(j,2,L)f[i][j]=sum[j-1][((1<<m)-1)^(1<<(a[i]-1))];
			fo(j,1,L){
				int r=(1<<(a[i])-1);
				for(int x=r;x<(1<<m);x=(x+1)|r)
					sum[j][x]=((sum[j][x]<<1)+sum[j][x^r])%mo;
				sum[j][0]=(sum[j][0]+f[i][j])%mo;
			}
		}
	}
	fo(i,1,n)
		fo(j,1,L){
			f[i][j]=(f[i][j]%mo+mo)%mo;
			ans[j]=(ans[j]+f[i][j]*mi[n-i])%mo;
		}
	fo(i,1,n)ans[i]=dec(ans[i],ans[i+1]);
	ans[0]=dec(mi[n],1);
	fo(i,1,L)ans[0]=dec(ans[0],ans[i]);
	fo(i,0,n)printf("%I64d%c",ans[i],i==n?'\n':' ');
	return 0;
}


#include<bits/stdc++.h>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 3005;
const int mo = 998244353;

LL add(LL x,LL y){return x+y>=mo?x+y-mo:x+y;}
LL dec(LL x,LL y){return x<y?x-y+mo:x-y;}

LL quickmi(LL x,LL tim){
	LL ret=1;
	for(;tim;tim/=2,x=x*x%mo)
		if (tim&1)ret=ret*x%mo;
	return ret;
}

int n,m;
int a[N];
LL f[N][N],g[N][N];
int cnt[N];
LL mi[N],iv[N];
LL ny[N],ans[N];
int pre[N][N];
LL sum[N][N];
int mul[N];

int main(){
//	freopen("data.in","r",stdin);
	n=get();m=get();
	fo(i,1,n)a[i]=get();
	mi[0]=1;
	fo(i,1,n)mi[i]=mi[i-1]*2%mo;
	fo(i,1,n)ny[i]=quickmi(mi[i]-1,mo-2);
	iv[0]=1;
	iv[1]=(mo+1)/2;
	fo(i,2,n)iv[i]=iv[i-1]*iv[1]%mo;
	int L=n/m;
	fo(i,1,n){
		fo(x,1,m)cnt[x]=0;
		int res=m;
		LL val=0;
		fo(j,i,n){
			int pr=res;
			cnt[a[j]]++;
			if (cnt[a[j]]==1)res--;
			if (!res){
				if (pr){
					val=1;
					fo(x,1,m)val=val*(mi[cnt[x]]-1)%mo;
				}
				else
					val=val*ny[cnt[a[j]]-1]%mo*(mi[cnt[a[j]]]-1)%mo;
			//	g[i][j]=val*ny[cnt[a[j]]]%mo;
				g[i][j]=val;
			}
		}
		fd(j,n,i)g[i][j]=dec(g[i][j],g[i][j-1]*2%mo);
	}
	if ((m>20)||(1<<m)>n){
		fo(i,1,n)f[i][1]=g[1][i];
		int L=n/m;
		fo(i,1,n)
			fo(j,1,L)
				fo(k,i+1,n)
				f[k][j+1]=(f[k][j+1]+f[i][j]*g[i+1][k])%mo;
	}
	else{
		fo(u,0,(1<<m)-1){
			fo(i,1,n)pre[u][i]=pre[u][i-1]+(((1<<(a[i]-1))&u)>0);
			mul[u]=1;
			fo(x,1,m)if (((1<<(x-1))&u)==0)mul[u]*=-1;
			//mul[u]=(mul[u]+mo)%mo;
		}
		fo(i,1,n)f[i][1]=g[1][i];
		fo(i,1,n){
			fd(j,L,2){
				LL tmp=0;
				fo(u,0,(1<<m)-1)
				if((u&(1<<(a[i]-1)))==0){
					tmp=(tmp-sum[j-1][u]*mi[pre[u][i]]*mul[u])%mo;
				}
				f[i][j]=tmp;
				if(f[i][j])
				fo(u,0,(1<<m)-1)sum[j][u]=(sum[j][u]+f[i][j]*iv[pre[u][i]])%mo;
			}
			fo(j,1,1){
				fo(u,0,(1<<m)-1){
					sum[j][u]=(sum[j][u]+f[i][j]*iv[pre[u][i]])%mo;
				}
			}
		}
	}
	fo(i,1,n)
		fo(j,1,L){
			f[i][j]=(f[i][j]%mo+mo)%mo;
			ans[j]=(ans[j]+f[i][j]*mi[n-i])%mo;
		}
	fo(i,1,n)ans[i]=dec(ans[i],ans[i+1]);
	ans[0]=dec(mi[n],1);
	fo(i,1,L)ans[0]=dec(ans[0],ans[i]);
	fo(i,0,n)printf("%I64d%c",ans[i],i==n?'\n':' ');
	return 0;
}


#include<bits/stdc++.h>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 3005;
const int mo = 998244353;

LL add(LL x,LL y){return x+y>=mo?x+y-mo:x+y;}
LL dec(LL x,LL y){return x<y?x-y+mo:x-y;}

LL quickmi(LL x,LL tim){
	LL ret=1;
	for(;tim;tim/=2,x=x*x%mo)
		if (tim&1)ret=ret*x%mo;
	return ret;
}

int n,m;
int a[N];
LL f[N][N],g[N][N];
int cnt[N];
LL mi[N],iv[N];
LL ny[N],ans[N];
int pre[N][N];
LL sum[N][N];
int mul[N];

int main(){
	//freopen("data.in","r",stdin);
	n=get();m=get();
	fo(i,1,n)a[i]=get();
	mi[0]=1;
	fo(i,1,n)mi[i]=mi[i-1]*2%mo;
	fo(i,1,n)ny[i]=quickmi(mi[i]-1,mo-2);
	iv[0]=1;
	iv[1]=(mo+1)/2;
	fo(i,2,n)iv[i]=iv[i-1]*iv[1]%mo;
	int L=n/m;
	fo(i,1,n){
		fo(x,1,m)cnt[x]=0;
		int res=m;
		LL val=0;
		fo(j,i,n){
			int pr=res;
			cnt[a[j]]++;
			if (cnt[a[j]]==1)res--;
			if (!res){
				if (pr){
					val=1;
					fo(x,1,m)val=val*(mi[cnt[x]]-1)%mo;
				}
				else
					val=val*ny[cnt[a[j]]-1]%mo*(mi[cnt[a[j]]]-1)%mo;
			//	g[i][j]=val*ny[cnt[a[j]]]%mo;
				g[i][j]=val;
			}
		}
		fd(j,n,i)g[i][j]=dec(g[i][j],g[i][j-1]*2%mo);
	}
	if ((m>20)||(1<<m)>n){
		fo(i,1,n)f[i][1]=g[1][i];
		int L=n/m;
		fo(i,1,n)
			fo(j,1,L)
				fo(k,i+1,n)
				f[k][j+1]=(f[k][j+1]+f[i][j]*g[i+1][k])%mo;
	}
	else{
		fo(u,0,(1<<m)-1){
			fo(i,1,n)pre[u][i]=pre[u][i-1]+(((1<<(a[i]-1))&u)>0);
			mul[u]=1;
			fo(x,1,m)if (((1<<(x-1))&u)==0)mul[u]*=-1;
			mul[u]=(mul[u]+mo)%mo;
		}
		fo(i,1,n)f[i][1]=g[1][i];
		fo(i,1,n){
			fo(j,2,L){
				fo(u,0,(1<<m)-1){
					f[i][j]=(f[i][j]+sum[j-1][u]*(mi[pre[u][i]]+mo*2-2ll*mi[pre[u][i-1]])%mo*mul[u])%mo;
				}
			}
			fo(j,1,L){
				fo(u,0,(1<<m)-1){
					sum[j][u]=(sum[j][u]+f[i][j]*iv[pre[u][i]])%mo;
				}
			}
		}
	}
	fo(i,1,n)
		fo(j,1,L)ans[j]=(ans[j]+f[i][j]*mi[n-i])%mo;
	fo(i,1,n)ans[i]=dec(ans[i],ans[i+1]);
	ans[0]=dec(mi[n],1);
	fo(i,1,L)ans[0]=dec(ans[0],ans[i]);
	fo(i,0,n)printf("%I64d%c",ans[i],i==n?'\n':' ');
	return 0;
}


#include<bits/stdc++.h>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 3005;
const int mo = 998244353;
const LL INF = 4e18;

LL add(LL x,LL y){return x+y>=mo?x+y-mo:x+y;}
LL dec(LL x,LL y){return x<y?x-y+mo:x-y;}

LL quickmi(LL x,LL tim){
	LL ret=1;
	for(;tim;tim/=2,x=x*x%mo)
		if (tim&1)ret=ret*x%mo;
	return ret;
}

int n,m;
int a[N];
LL f[N][N],g[N][N];
LL sum[N][N];
int cnt[N];
LL mi[N],iv[N];
LL ny[N],ans[N];
int mul[N];

int main(){
//	freopen("data.in","r",stdin);
	n=get();m=get();
	fo(i,1,n)a[i]=get();
	mi[0]=1;
	fo(i,1,n)mi[i]=mi[i-1]*2%mo;
	fo(i,1,n)ny[i]=quickmi(mi[i]-1,mo-2);
	iv[0]=1;
	iv[1]=(mo+1)/2;
	fo(i,2,n)iv[i]=iv[i-1]*iv[1]%mo;
	int L=n/m;
	fo(i,1,n){
		fo(x,1,m)cnt[x]=0;
		int res=m;
		LL val=0;
		fo(j,i,n){
			int pr=res;
			cnt[a[j]]++;
			if (cnt[a[j]]==1)res--;
			if (!res){
				if (pr){
					val=1;
					fo(x,1,m)val=val*(mi[cnt[x]]-1)%mo;
				}
				else
					val=val*ny[cnt[a[j]]-1]%mo*(mi[cnt[a[j]]]-1)%mo;
			//	g[i][j]=val*ny[cnt[a[j]]]%mo;
				g[i][j]=val;
			}
		}
		fd(j,n,i)g[i][j]=dec(g[i][j],g[i][j-1]*2%mo);
	}
	if ((m>20)||(1<<m)>n){
		fo(i,1,n)f[i][1]=g[1][i];
		int L=n/m;
		fo(i,1,n)
			fd(j,i/m,2){
				fo(k,(j-1)*m,i-1){
					f[i][j]=f[i][j]+f[k][j-1]*g[k+1][i];
					if (f[i][j]>INF)f[i][j]-=INF;
				}
				f[i][j]=f[i][j]%mo;
			}
	}
	else{
		fo(i,1,n)f[i][1]=g[1][i];
		fo(i,1,n){
			fo(j,2,L)f[i][j]=sum[j-1][((1<<m)-1)^(1<<(a[i]-1))];
			fo(j,1,L){
				int r=(1<<(a[i])-1);
				for(int x=r;x<(1<<m);x=(x+1)|r)
					sum[j][x]=((sum[j][x]<<1)+sum[j][x^r])%mo;
				sum[j][0]=(sum[j][0]+f[i][j])%mo;
			}
		}
	}
	fo(i,1,n)
		fo(j,1,L){
			f[i][j]=(f[i][j]%mo+mo)%mo;
			ans[j]=(ans[j]+f[i][j]*mi[n-i])%mo;
		}
	fo(i,1,n)ans[i]=dec(ans[i],ans[i+1]);
	ans[0]=dec(mi[n],1);
	fo(i,1,L)ans[0]=dec(ans[0],ans[i]);
	fo(i,0,n)printf("%I64d%c",ans[i],i==n?'\n':' ');
	return 0;
}


#include<bits/stdc++.h>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef double db;
typedef long long LL;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 3005;
const int mo = 998244353;
const LL INF = 4ll*mo*mo;

LL add(LL x,LL y){return x+y>=mo?x+y-mo:x+y;}
LL dec(LL x,LL y){return x<y?x-y+mo:x-y;}

LL quickmi(LL x,LL tim){
	LL ret=1;
	for(;tim;tim/=2,x=x*x%mo)
		if (tim&1)ret=ret*x%mo;
	return ret;
}

int n,m;
int a[N];
LL f[N][N],g[N][N];
LL sum[N][N];
int cnt[N];
LL mi[N],iv[N];
LL ny[N],ans[N];
int mul[N];

int main(){
//	freopen("data.in","r",stdin);
	n=get();m=get();
	fo(i,1,n)a[i]=get();
	mi[0]=1;
	fo(i,1,n)mi[i]=mi[i-1]*2%mo;
	fo(i,1,n)ny[i]=quickmi(mi[i]-1,mo-2);
	iv[0]=1;
	iv[1]=(mo+1)/2;
	fo(i,2,n)iv[i]=iv[i-1]*iv[1]%mo;
	int L=n/m;
	fo(i,1,n){
		fo(x,1,m)cnt[x]=0;
		int res=m;
		LL val=0;
		fo(j,i,n){
			int pr=res;
			cnt[a[j]]++;
			if (cnt[a[j]]==1)res--;
			if (!res){
				if (pr){
					val=1;
					fo(x,1,m)val=val*(mi[cnt[x]]-1)%mo;
				}
				else
					val=val*ny[cnt[a[j]]-1]%mo*(mi[cnt[a[j]]]-1)%mo;
			//	g[i][j]=val*ny[cnt[a[j]]]%mo;
				g[i][j]=val;
			}
		}
		fd(j,n,i)g[i][j]=dec(g[i][j],g[i][j-1]*2%mo);
	}
	if ((m>20)||(1<<m)>n){
		fo(i,1,n)f[i][1]=g[1][i];
		int L=n/m;
		fo(i,1,n)
			fd(j,i/m,2){
				fo(k,(j-1)*m,i-1){
					f[i][j]=(f[i][j]+f[k][j-1]*g[k+1][i]);
					if (f[i][j]>INF)f[i][j]-=INF;
				}
				f[i][j]=f[i][j]%mo;
			}
	}
	else{
		fo(i,1,n)f[i][1]=g[1][i];
		fo(i,1,n){
			fo(j,2,L)f[i][j]=sum[j-1][((1<<m)-1)^(1<<(a[i]-1))];
			fo(j,1,L){
				int r=(1<<(a[i])-1);
				for(int x=r;x<(1<<m);x=(x+1)|r)
					sum[j][x]=((sum[j][x]<<1)+sum[j][x^r])%mo;
				sum[j][0]=(sum[j][0]+f[i][j])%mo;
			}
		}
	}
	fo(i,1,n)
		fo(j,1,L){
			f[i][j]=(f[i][j]%mo+mo)%mo;
			ans[j]=(ans[j]+f[i][j]*mi[n-i])%mo;
		}
	fo(i,1,n)ans[i]=dec(ans[i],ans[i+1]);
	ans[0]=dec(mi[n],1);
	fo(i,1,L)ans[0]=dec(ans[0],ans[i]);
	fo(i,0,n)printf("%I64d%c",ans[i],i==n?'\n':' ');
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int bg=13, mod=998244353;
inline int sum(int a, int b)
{
    return (a+b<mod) ? (a+b) : (a+b-mod);
}
inline int dif(int a, int b)
{
    return (a-b>=0) ? (a-b) : (a-b+mod);
}
int po(int x, int y)
{
    int re=1;
    while(y)
    {
        if(y&1) re=(1ll*re*x)%mod;
        y>>=1;
        x=(1ll*x*x)%mod;
    }
    return re;
}
int main()
{
    //freopen("input.txt", "r", stdin);
    int n, c;
    cin>>n>>c;
    int m=n/c, ar[n], an[n+1];
    for(int a=0; a<n; a++)
    {
        cin>>ar[a], ar[a]--;
        an[a]=0;
    }
    an[n]=0;
    if(c<bg)
    {
        int dp[m+1][1<<c], dp2[m+1][1<<c];
        for(int b=0; b<=m; b++) for(int mask=0; mask<(1<<c); mask++) dp[b][mask]=dp2[b][mask]=0;
        dp[0][0]=1;

        short int one=1;

        for(short int a=0; a<n; a++)
        {
            for(short int b=0; b<=m; b++)
            {
                for(short int mask=0; mask<(one<<c); mask++)
                {
                    if(dp[b][mask])
                    {
                        dp2[b][mask]=sum(dp2[b][mask], dp[b][mask]);

                        short int nmask=(mask|(one<<ar[a])), nb=b;
                        if(nmask==(one<<c)-one) nmask=0, nb++;

                        dp2[nb][nmask]=sum(dp2[nb][nmask], dp[b][mask]);
                    }
                }
            }
            for(short int b=0; b<=m; b++) for(short int mask=0; mask<(one<<c); mask++) dp[b][mask]=dp2[b][mask], dp2[b][mask]=0;
        }
        for(int a=0; a<=m; a++)
        {
            for(int mask=0; mask<(1<<c); mask++) an[a]=sum(an[a], dp[a][mask]);
        }
    }
    else
    {
        int st2[n+1], rev_st2[n+1];
        st2[0]=0, rev_st2[0]=0;
        for(int a=1; a<=n; a++)
        {
            st2[a]=(st2[a-1]*2+1)%mod;
            rev_st2[a]=po(st2[a], mod-2);
        }
        int dp[n+1][m+1];
        for(int a=0; a<=n; a++) for(int b=0; b<=m; b++) dp[a][b]=0;
        dp[0][0]=1;
        for(int a=0; a<n; a++)
        {
            for(int b=0; b<m; b++)
            {
                if(dp[a][b])
                {
                    int q[c], dc=0, add=dp[a][b];
                    for(int i=0; i<c; i++) q[i]=0;
                    for(int r=a; r<n; r++)
                    {
                        if(dc==c)
                        {
                            add=(1ll*add*rev_st2[q[ar[r]]])%mod;
                            q[ar[r]]++;
                            add=(1ll*add*st2[q[ar[r]]])%mod;
                        }
                        else
                        {
                            if(q[ar[r]]==0) dc++;
                            q[ar[r]]++;
                            if(dc==c)
                            {
                                for(int i=0; i<c; i++) add=(1ll*add*st2[q[i]])%mod;
                            }
                        }

                        if(dc==c)
                        {
                            add=(1ll*add*rev_st2[q[ar[r]]])%mod;

                            dp[r+1][b+1]=sum(dp[r+1][b+1], add);

                            add=(1ll*add*st2[q[ar[r]]])%mod;
                        }
                    }
                }
            }
        }
        int st=1, bad=0, q[c], dc=0;
        for(int i=0; i<c; i++) q[i]=0;
        for(int a=n; a>=0; a--)
        {
            if(a<n)
            {
                if(dc==c)
                {
                    bad=(1ll*bad*rev_st2[q[ar[a]]])%mod;
                    q[ar[a]]++;
                    bad=(1ll*bad*st2[q[ar[a]]])%mod;
                }
                else
                {
                    if(q[ar[a]]==0) dc++;
                    q[ar[a]]++;
                    if(dc==c)
                    {
                        bad=1;
                        for(int i=0; i<c; i++) bad=(1ll*bad*st2[q[i]])%mod;
                    }
                }
            }

            for(int b=0; b<=m; b++)
            {
                an[b]=(an[b]+1ll*dp[a][b]*dif(st, bad))%mod;
            }

            st=sum(st, st);
        }
    }
    an[0]=dif(an[0], 1);
    for(int a=0; a<=n; a++) cout<<an[a]<<" ";
}


#include <bits/stdc++.h>
using namespace std;
const int bg=12, mod=998244353;
inline int sum(int a, int b)
{
    return (a+b<mod) ? (a+b) : (a+b-mod);
}
inline int dif(int a, int b)
{
    return (a-b>=0) ? (a-b) : (a-b+mod);
}
int po(int x, int y)
{
    int re=1;
    while(y)
    {
        if(y&1) re=(1ll*re*x)%mod;
        y>>=1;
        x=(1ll*x*x)%mod;
    }
    return re;
}
int main()
{
    //freopen("input.txt", "r", stdin);
    int n, c;
    cin>>n>>c;
    int m=n/c, ar[n], an[n+1];
    for(int a=0; a<n; a++)
    {
        cin>>ar[a], ar[a]--;
        an[a]=0;
    }
    an[n]=0;
    if(c<bg)
    {
        int dp[m+1][1<<c], dp2[m+1][1<<c];
        for(int b=0; b<=m; b++) for(int mask=0; mask<(1<<c); mask++) dp[b][mask]=dp2[b][mask]=0;
        dp[0][0]=1;

        short int one=1;

        for(short int a=0; a<n; a++)
        {
            for(short int b=0; b<=m; b++)
            {
                for(short int mask=0; mask<(one<<c); mask++)
                {
                    if(dp[b][mask])
                    {
                        dp2[b][mask]=sum(dp2[b][mask], dp[b][mask]);

                        short int nmask=(mask|(one<<ar[a])), nb=b;
                        if(nmask==(one<<c)-one) nmask=0, nb++;

                        dp2[nb][nmask]=sum(dp2[nb][nmask], dp[b][mask]);
                    }
                }
            }
            for(short int b=0; b<=m; b++) for(short int mask=0; mask<(one<<c); mask++) dp[b][mask]=dp2[b][mask], dp2[b][mask]=0;
        }
        for(int a=0; a<=m; a++)
        {
            for(int mask=0; mask<(1<<c); mask++) an[a]=sum(an[a], dp[a][mask]);
        }
    }
    else
    {
        int st2[n+1], rev_st2[n+1];
        st2[0]=0, rev_st2[0]=0;
        for(int a=1; a<=n; a++)
        {
            st2[a]=(st2[a-1]*2+1)%mod;
            rev_st2[a]=po(st2[a], mod-2);
        }
        int add[n][n];
        for(int a=0; a<n; a++)
        {
            int q[c], dc=0, x=1;
            for(int i=0; i<c; i++) q[i]=0;
            for(int b=a; b<n; b++)
            {
                if(dc==c)
                {
                    x=(1ll*x*rev_st2[q[ar[b]]])%mod;
                    q[ar[b]]++;
                    x=(1ll*x*st2[q[ar[b]]])%mod;
                }
                else
                {
                    if(q[ar[b]]==0) dc++;
                    q[ar[b]]++;
                    if(dc==c)
                    {
                        for(int i=0; i<c; i++) x=(1ll*x*st2[q[i]])%mod;
                    }
                }
                if(dc==c)
                {
                    x=(1ll*x*rev_st2[q[ar[b]]])%mod;

                    add[a][b]=x;

                    x=(1ll*x*st2[q[ar[b]]])%mod;
                }
                else add[a][b]=0;
            }
        }
        int dp[n+1][m+1];
        for(int a=0; a<=n; a++) for(int b=0; b<=m; b++) dp[a][b]=0;
        dp[0][0]=1;
        for(int a=0; a<n; a++)
        {
            for(int b=0; b<m; b++)
            {
                if(dp[a][b])
                {
                    for(int r=n-1; r>=a; r--)
                    {
                        if(add[a][r]) dp[r+1][b+1]=(dp[r+1][b+1]+1ll*dp[a][b]*add[a][r])%mod;
                        else break;
                    }
                }
            }
        }
        int st=1, bad=0, q[c], dc=0;
        for(int i=0; i<c; i++) q[i]=0;
        for(int a=n; a>=0; a--)
        {
            if(a<n)
            {
                if(dc==c)
                {
                    bad=(1ll*bad*rev_st2[q[ar[a]]])%mod;
                    q[ar[a]]++;
                    bad=(1ll*bad*st2[q[ar[a]]])%mod;
                }
                else
                {
                    if(q[ar[a]]==0) dc++;
                    q[ar[a]]++;
                    if(dc==c)
                    {
                        bad=1;
                        for(int i=0; i<c; i++) bad=(1ll*bad*st2[q[i]])%mod;
                    }
                }
            }

            for(int b=0; b<=m; b++)
            {
                an[b]=(an[b]+1ll*dp[a][b]*dif(st, bad))%mod;
            }

            st=sum(st, st);
        }
    }
    an[0]=dif(an[0], 1);
    for(int a=0; a<=n; a++) cout<<an[a]<<" ";
}


#include <bits/stdc++.h>
using namespace std;
const int bg=13, mod=998244353;
inline int sum(int a, int b)
{
    return (a+b<mod) ? (a+b) : (a+b-mod);
}
inline int dif(int a, int b)
{
    return (a-b>=0) ? (a-b) : (a-b+mod);
}
int po(int x, int y)
{
    int re=1;
    while(y)
    {
        if(y&1) re=(1ll*re*x)%mod;
        y>>=1;
        x=(1ll*x*x)%mod;
    }
    return re;
}
int main()
{
    //freopen("input.txt", "r", stdin);
    int n, c;
    cin>>n>>c;
    int m=n/c, ar[n], an[n+1];
    for(int a=0; a<n; a++)
    {
        cin>>ar[a], ar[a]--;
        an[a]=0;
    }
    an[n]=0;
    if(c<bg)
    {
        int dp[m+1][1<<c], dp2[m+1][1<<c];
        for(int b=0; b<=m; b++) for(int mask=0; mask<(1<<c); mask++) dp[b][mask]=dp2[b][mask]=0;
        dp[0][0]=1;
        for(int a=0; a<n; a++)
        {
            for(int b=0; b<=m; b++)
            {
                for(int mask=0; mask<(1<<c); mask++)
                {
                    if(dp[b][mask])
                    {
                        dp2[b][mask]=sum(dp2[b][mask], dp[b][mask]);

                        int nmask=(mask|(1<<ar[a])), nb=b;
                        if(nmask==(1<<c)-1) nmask=0, nb++;

                        dp2[nb][nmask]=sum(dp2[nb][nmask], dp[b][mask]);
                    }
                }
            }
            for(int b=0; b<=m; b++) for(int mask=0; mask<(1<<c); mask++) dp[b][mask]=dp2[b][mask], dp2[b][mask]=0;
        }
        for(int a=0; a<=m; a++)
        {
            for(int mask=0; mask<(1<<c); mask++) an[a]=sum(an[a], dp[a][mask]);
        }
    }
    else
    {
        int st2[n+1], rev_st2[n+1];
        st2[0]=0, rev_st2[0]=0;
        for(int a=1; a<=n; a++)
        {
            st2[a]=(st2[a-1]*2+1)%mod;
            rev_st2[a]=po(st2[a], mod-2);
        }
        int dp[n+1][m+1];
        for(int a=0; a<=n; a++) for(int b=0; b<=m; b++) dp[a][b]=0;
        dp[0][0]=1;
        for(int a=0; a<n; a++)
        {
            for(int b=0; b<m; b++)
            {
                if(dp[a][b])
                {
                    int q[c], dc=0, add=dp[a][b];
                    for(int i=0; i<c; i++) q[i]=0;
                    for(int r=a; r<n; r++)
                    {
                        if(dc==c)
                        {
                            add=(1ll*add*rev_st2[q[ar[r]]])%mod;
                            q[ar[r]]++;
                            add=(1ll*add*st2[q[ar[r]]])%mod;
                        }
                        else
                        {
                            if(q[ar[r]]==0) dc++;
                            q[ar[r]]++;
                            if(dc==c)
                            {
                                for(int i=0; i<c; i++) add=(1ll*add*st2[q[i]])%mod;
                            }
                        }

                        if(dc==c)
                        {
                            add=(1ll*add*rev_st2[q[ar[r]]])%mod;

                            dp[r+1][b+1]=sum(dp[r+1][b+1], add);

                            add=(1ll*add*st2[q[ar[r]]])%mod;
                        }
                    }
                }
            }
        }
        int st=1, bad=0, q[c], dc=0;
        for(int i=0; i<c; i++) q[i]=0;
        for(int a=n; a>=0; a--)
        {
            if(a<n)
            {
                if(dc==c)
                {
                    bad=(1ll*bad*rev_st2[q[ar[a]]])%mod;
                    q[ar[a]]++;
                    bad=(1ll*bad*st2[q[ar[a]]])%mod;
                }
                else
                {
                    if(q[ar[a]]==0) dc++;
                    q[ar[a]]++;
                    if(dc==c)
                    {
                        bad=1;
                        for(int i=0; i<c; i++) bad=(1ll*bad*st2[q[i]])%mod;
                    }
                }
            }

            for(int b=0; b<=m; b++)
            {
                an[b]=(an[b]+1ll*dp[a][b]*dif(st, bad))%mod;
            }

            st=sum(st, st);
        }
    }
    an[0]=dif(an[0], 1);
    for(int a=0; a<=n; a++) cout<<an[a]<<" ";
}


#include <bits/stdc++.h>
using namespace std;
const int bg=12, mod=998244353;
inline int sum(int a, int b)
{
    return (a+b<mod) ? (a+b) : (a+b-mod);
}
inline int dif(int a, int b)
{
    return (a-b>=0) ? (a-b) : (a-b+mod);
}
int po(int x, int y)
{
    int re=1;
    while(y)
    {
        if(y&1) re=(1ll*re*x)%mod;
        y>>=1;
        x=(1ll*x*x)%mod;
    }
    return re;
}
int main()
{
    //freopen("input.txt", "r", stdin);
    int n, c;
    cin>>n>>c;
    int m=n/c, ar[n], an[n+1];
    for(int a=0; a<n; a++)
    {
        cin>>ar[a], ar[a]--;
        an[a]=0;
    }
    an[n]=0;
    if(c<bg)
    {
        int dp[m+1][1<<c], dp2[m+1][1<<c];
        for(int b=0; b<=m; b++) for(int mask=0; mask<(1<<c); mask++) dp[b][mask]=dp2[b][mask]=0;
        dp[0][0]=1;
        for(int a=0; a<n; a++)
        {
            for(int b=0; b<=m; b++)
            {
                for(int mask=0; mask<(1<<c); mask++)
                {
                    if(dp[b][mask])
                    {
                        dp2[b][mask]=sum(dp2[b][mask], dp[b][mask]);

                        int nmask=(mask|(1<<ar[a])), nb=b;
                        if(nmask==(1<<c)-1) nmask=0, nb++;

                        dp2[nb][nmask]=sum(dp2[nb][nmask], dp[b][mask]);
                    }
                }
            }
            for(int b=0; b<=m; b++) for(int mask=0; mask<(1<<c); mask++) dp[b][mask]=dp2[b][mask], dp2[b][mask]=0;
        }
        for(int a=0; a<=m; a++)
        {
            for(int mask=0; mask<(1<<c); mask++) an[a]=sum(an[a], dp[a][mask]);
        }
    }
    else
    {
        int st2[n+1], rev_st2[n+1];
        st2[0]=0, rev_st2[0]=0;
        for(int a=1; a<=n; a++)
        {
            st2[a]=(st2[a-1]*2+1)%mod;
            rev_st2[a]=po(st2[a], mod-2);
        }
        int dp[n+1][m+1];
        for(int a=0; a<=n; a++) for(int b=0; b<=m; b++) dp[a][b]=0;
        dp[0][0]=1;
        for(int a=0; a<n; a++)
        {
            for(int b=0; b<m; b++)
            {
                if(dp[a][b])
                {
                    int q[c], dc=0, add=dp[a][b];
                    for(int i=0; i<c; i++) q[i]=0;
                    for(int r=a; r<n; r++)
                    {
                        if(dc==c)
                        {
                            add=(1ll*add*rev_st2[q[ar[r]]])%mod;
                            q[ar[r]]++;
                            add=(1ll*add*st2[q[ar[r]]])%mod;
                        }
                        else
                        {
                            if(q[ar[r]]==0) dc++;
                            q[ar[r]]++;
                            if(dc==c)
                            {
                                for(int i=0; i<c; i++) add=(1ll*add*st2[q[i]])%mod;
                            }
                        }

                        if(dc==c)
                        {
                            add=(1ll*add*rev_st2[q[ar[r]]])%mod;

                            dp[r+1][b+1]=sum(dp[r+1][b+1], add);

                            add=(1ll*add*st2[q[ar[r]]])%mod;
                        }
                    }
                }
            }
        }
        int st=1, bad=0, q[c], dc=0;
        for(int i=0; i<c; i++) q[i]=0;
        for(int a=n; a>=0; a--)
        {
            if(a<n)
            {
                if(dc==c)
                {
                    bad=(1ll*bad*rev_st2[q[ar[a]]])%mod;
                    q[ar[a]]++;
                    bad=(1ll*bad*st2[q[ar[a]]])%mod;
                }
                else
                {
                    if(q[ar[a]]==0) dc++;
                    q[ar[a]]++;
                    if(dc==c)
                    {
                        bad=1;
                        for(int i=0; i<c; i++) bad=(1ll*bad*st2[q[i]])%mod;
                    }
                }
            }

            for(int b=0; b<=m; b++)
            {
                an[b]=(an[b]+1ll*dp[a][b]*dif(st, bad))%mod;
            }

            st=sum(st, st);
        }
    }
    an[0]=dif(an[0], 1);
    for(int a=0; a<=n; a++) cout<<an[a]<<" ";
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3005;
const int M=998244353;
int n,c,a[maxn],dp[maxn][maxn],f[2][maxn][maxn],cnt[maxn],w[maxn][maxn],ans[maxn];
int invp[maxn],p[maxn];
int pow_(int x,int y){
    ll ret=1;
    while (y){
        if (y&1) ret=ret*x%M;
        x=1ll*x*x%M; y>>=1;
    }
    return (int)ret;
}
void add(int &x,int y){
    x+=y; if (x>=M) x-=M;
}
void sub(int &x,int y){
    x-=y; if (x<0) x+=M;
}

int main(){
    p[0]=0;for (int i=1;i<maxn;i++) p[i]=(p[i-1]*2+1)%M,invp[i]=pow_(p[i],M-2);
    cin >> n >> c;
    for (int i=1;i<=n;i++) {cin >> a[i];--a[i];}
    if (c>=10){
        for (int l=0;l<n;l++){
            ll res=1;
            int tot=0;
            memset(cnt,0,sizeof(cnt));
            for (int r=l+1;r<=n;r++){
                if (cnt[a[r]]) res=res*invp[cnt[a[r]]]%M; else ++tot;
                cnt[a[r]]++;
                if (tot==c) w[l][r]=res;
                res=res*p[cnt[a[r]]]%M;
            }
        }
        dp[0][0]=1;
        for (int i=0;i<n;i++)
            for (int j=i+1;j<=n;j++) if (w[i][j])
                for (int k=0;k<=i/c;k++)
                    add(dp[j][k+1],1ll*dp[i][k]*w[i][j]%M);
        for (int i=0;i<=n;i++)
            for (int k=0;k<=i/c;k++)
                add(ans[k],1ll*dp[i][k]*(p[n-i]+1)%M);
        for (int i=0;i<n;i++) sub(ans[i],ans[i+1]);
    } else {
        int r=1<<c; f[0][0][0]=1;
        for (int i=1;i<=n;i++){
            int o=i&1;
            for (int k=0;k<=i/c;k++)
                for (int j=0;j<r;j++) if (f[o^1][k][j]){
                    add(f[o][k][j],f[o^1][k][j]);
                    add(f[o][k][j|(1<<a[i])],f[o^1][k][j]);
                    f[o^1][k][j]=0;
                }
            for (int k=0;k<=i/c;k++) {
                add(f[o][k+1][0],f[o][k][r-1]);
                f[o][k][r-1]=0;
            }
        }
        for (int k=0;k<=n/c;k++)
            for (int j=0;j<r;j++)
                add(ans[k],f[n&1][k][j]);
    }
    sub(ans[0],1);
    for (int i=0;i<=n;i++) cout << ans[i] << ' '; cout << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3005;
const int M=998244353;
int n,c,a[maxn],dp[maxn][maxn],f[2][maxn][maxn],cnt[maxn],w[maxn][maxn],ans[maxn];
int invp[maxn],p[maxn];
int pow_(int x,int y){
    ll ret=1;
    while (y){
        if (y&1) ret=ret*x%M;
        x=1ll*x*x%M; y>>=1;
    }
    return (int)ret;
}
void add(int &x,int y){
    x+=y; if (x>=M) x-=M;
}
void sub(int &x,int y){
    x-=y; if (x<0) x+=M;
}
int mul(int x,int y){
    return (ll)x*y%M;
}

int main(){
    p[0]=0;for (int i=1;i<maxn;i++) p[i]=(p[i-1]*2+1)%M,invp[i]=pow_(p[i],M-2);
    cin >> n >> c;
    for (int i=1;i<=n;i++) {cin >> a[i];--a[i];}
    if (c>=12){
        for (int l=0;l<n;l++){
            ll res=1;
            int tot=0;
            memset(cnt,0,sizeof(cnt));
            for (int r=l+1;r<=n;r++){
                if (cnt[a[r]]) res=res*invp[cnt[a[r]]]%M; else ++tot;
                cnt[a[r]]++;
                if (tot==c) w[l][r]=res;
                res=res*p[cnt[a[r]]]%M;
            }
        }
        dp[0][0]=1;
        for (int i=0;i<n;i++)
            for (int j=i+1;j<=n;j++) if (w[i][j]){
                int res=w[i][j];
                for (int k=0;k<=i/c;k++)
                    add(dp[j][k+1],mul(dp[i][k],res));
            }
        for (int i=0;i<=n;i++)
            for (int k=0;k<=i/c;k++)
                add(ans[k],mul(dp[i][k],(p[n-i]+1)));
        for (int i=0;i<n;i++) sub(ans[i],ans[i+1]);
    } else {
        int r=1<<c; f[0][0][0]=1;
        for (int i=1;i<=n;i++){
            int o=i&1;
            for (int k=0;k<=i/c;k++)
                for (int j=0;j<r;j++) if (f[o^1][k][j]){
                    add(f[o][k][j],f[o^1][k][j]);
                    add(f[o][k][j|(1<<a[i])],f[o^1][k][j]);
                    f[o^1][k][j]=0;
                }
            for (int k=0;k<=i/c;k++) {
                add(f[o][k+1][0],f[o][k][r-1]);
                f[o][k][r-1]=0;
            }
        }
        for (int k=0;k<=n/c;k++)
            for (int j=0;j<r;j++)
                add(ans[k],f[n&1][k][j]);
    }
    sub(ans[0],1);
    for (int i=0;i<=n;i++) cout << ans[i] << ' '; cout << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3000;
const int M=998244353;
int n,c,a[maxn],dp[maxn][maxn],f[2][maxn][maxn],cnt[maxn],w[maxn][maxn],ans[maxn];
int invp[maxn],p[maxn];
int pow_(int x,int y){
    ll ret=1;
    while (y){
        if (y&1) ret=ret*x%M;
        x=1ll*x*x%M; y>>=1;
    }
    return (int)ret;
}
void add(int &x,int y){
    x+=y; if (x>=M) x-=M;
}
void sub(int &x,int y){
    x-=y; if (x<0) x+=M;
}

int main(){
    p[0]=0;for (int i=1;i<maxn;i++) p[i]=(p[i-1]*2+1)%M,invp[i]=pow_(p[i],M-2);
    cin >> n >> c;
    for (int i=1;i<=n;i++) {cin >> a[i];--a[i];}
    if (c>=10){
        for (int l=0;l<n;l++){
            ll res=1;
            int tot=0;
            memset(cnt,0,sizeof(cnt));
            for (int r=l+1;r<=n;r++){
                if (cnt[a[r]]) res=res*invp[cnt[a[r]]]%M; else ++tot;
                cnt[a[r]]++;
                if (tot==c) w[l][r]=res;
                res=res*p[cnt[a[r]]]%M;
            }
        }
        dp[0][0]=1;
        for (int i=0;i<n;i++)
            for (int j=i+1;j<=n;j++) if (w[i][j])
                for (int k=0;k<=i/c;k++)
                    add(dp[j][k+1],1ll*dp[i][k]*w[i][j]%M);
        for (int i=0;i<=n;i++)
            for (int k=0;k<=i/c;k++)
                add(ans[k],1ll*dp[i][k]*(p[n-i]+1)%M);
        for (int i=0;i<n;i++) sub(ans[i],ans[i+1]);
    } else {
        int r=1<<c; f[0][0][0]=1;
        for (int i=1;i<=n;i++){
            int o=i&1;
            for (int k=0;k<=i/c;k++)
                for (int j=0;j<r;j++) if (f[o^1][k][j]){
                    add(f[o][k][j],f[o^1][k][j]);
                    add(f[o][k][j|(1<<a[i])],f[o^1][k][j]);
                    f[o^1][k][j]=0;
                }
            for (int k=0;k<=i/c;k++) {
                add(f[o][k+1][0],f[o][k][r-1]);
                f[o][k][r-1]=0;
            }
        }
        for (int k=0;k<=n/c;k++)
            for (int j=0;j<r;j++)
                add(ans[k],f[n&1][k][j]);
    }
    sub(ans[0],1);
    for (int i=0;i<=n;i++) cout << ans[i] << ' '; cout << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3005;
const int M=998244353;
int n,c,a[maxn],dp[maxn][maxn],f[2][maxn][maxn],cnt[maxn],w[maxn][maxn],ans[maxn];
int invp[maxn],p[maxn];
int pow_(int x,int y){
    ll ret=1;
    while (y){
        if (y&1) ret=ret*x%M;
        x=1ll*x*x%M; y>>=1;
    }
    return (int)ret;
}
void add(int &x,int y){
    x+=y; if (x>=M) x-=M;
}
void sub(int &x,int y){
    x-=y; if (x<0) x+=M;
}
int mul(int x,int y){
    return (ll)x*y%M;
}

int main(){
    p[0]=0;for (int i=1;i<maxn;i++) p[i]=(p[i-1]*2+1)%M,invp[i]=pow_(p[i],M-2);
    cin >> n >> c;
    for (int i=1;i<=n;i++) {cin >> a[i];--a[i];}
    if (c>=12){
        for (int l=0;l<n;l++){
            ll res=1;
            int tot=0;
            memset(cnt,0,sizeof(cnt));
            for (int r=l+1;r<=n;r++){
                if (cnt[a[r]]) res=res*invp[cnt[a[r]]]%M; else ++tot;
                cnt[a[r]]++;
                if (tot==c) w[l][r]=res;
                res=res*p[cnt[a[r]]]%M;
            }
        }
        dp[0][0]=1;
        for (int i=0;i<n;i++)
            for (int j=i+1;j<=n;j++) if (w[i][j])
                for (int k=0;k<=i/c;k++)
                    add(dp[j][k+1],mul(dp[i][k],w[i][j]));
        for (int i=0;i<=n;i++)
            for (int k=0;k<=i/c;k++)
                add(ans[k],mul(dp[i][k],(p[n-i]+1)));
        for (int i=0;i<n;i++) sub(ans[i],ans[i+1]);
    } else {
        int r=1<<c; f[0][0][0]=1;
        for (int i=1;i<=n;i++){
            int o=i&1;
            for (int k=0;k<=i/c;k++)
                for (int j=0;j<r;j++) if (f[o^1][k][j]){
                    add(f[o][k][j],f[o^1][k][j]);
                    add(f[o][k][j|(1<<a[i])],f[o^1][k][j]);
                    f[o^1][k][j]=0;
                }
            for (int k=0;k<=i/c;k++) {
                add(f[o][k+1][0],f[o][k][r-1]);
                f[o][k][r-1]=0;
            }
        }
        for (int k=0;k<=n/c;k++)
            for (int j=0;j<r;j++)
                add(ans[k],f[n&1][k][j]);
    }
    sub(ans[0],1);
    for (int i=0;i<=n;i++) cout << ans[i] << ' '; cout << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3005;
const int M=998244353;
int n,c,a[maxn],dp[maxn][maxn],f[2][maxn][maxn],cnt[maxn],w[maxn][maxn],ans[maxn];
int invp[maxn],p[maxn];
int pow_(int x,int y){
    ll ret=1;
    while (y){
        if (y&1) ret=ret*x%M;
        x=1ll*x*x%M; y>>=1;
    }
    return (int)ret;
}
void add(int &x,int y){
    x+=y; if (x>=M) x-=M;
}
void sub(int &x,int y){
    x-=y; if (x<0) x+=M;
}
int mul(int x,int y){
    return (ll)x*y%M;
}

int main(){
    p[0]=0;for (int i=1;i<maxn;i++) p[i]=(p[i-1]*2+1)%M,invp[i]=pow_(p[i],M-2);
    cin >> n >> c;
    for (int i=1;i<=n;i++) {cin >> a[i];--a[i];}
    if (c>=12){
        for (int l=0;l<n;l++){
            ll res=1;
            int tot=0;
            memset(cnt,0,sizeof(cnt));
            for (int r=l+1;r<=n;r++){
                if (cnt[a[r]]) res=res*invp[cnt[a[r]]]%M; else ++tot;
                cnt[a[r]]++;
                if (tot==c) w[l][r]=res;
                res=res*p[cnt[a[r]]]%M;
            }
        }
        dp[0][0]=1;
        for (int i=0;i<n;i++)
            for (int j=i+1;j<=n;j++) if (w[i][j])
                for (int k=0;k<=i/c;k++)
                    add(dp[j][k+1],mul(dp[i][k],w[i][j]));
        for (int i=0;i<=n;i++)
            for (int k=0;k<=i/c;k++)
                add(ans[k],mul(dp[i][k]*(p[n-i]+1)));
        for (int i=0;i<n;i++) sub(ans[i],ans[i+1]);
    } else {
        int r=1<<c; f[0][0][0]=1;
        for (int i=1;i<=n;i++){
            int o=i&1;
            for (int k=0;k<=i/c;k++)
                for (int j=0;j<r;j++) if (f[o^1][k][j]){
                    add(f[o][k][j],f[o^1][k][j]);
                    add(f[o][k][j|(1<<a[i])],f[o^1][k][j]);
                    f[o^1][k][j]=0;
                }
            for (int k=0;k<=i/c;k++) {
                add(f[o][k+1][0],f[o][k][r-1]);
                f[o][k][r-1]=0;
            }
        }
        for (int k=0;k<=n/c;k++)
            for (int j=0;j<r;j++)
                add(ans[k],f[n&1][k][j]);
    }
    sub(ans[0],1);
    for (int i=0;i<=n;i++) cout << ans[i] << ' '; cout << endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=3005;
const int M=998244353;
int n,c,a[maxn],dp[maxn][maxn],f[2][maxn][maxn],cnt[maxn],w[maxn][maxn],ans[maxn];
int invp[maxn],p[maxn];
int pow_(int x,int y){
    ll ret=1;
    while (y){
        if (y&1) ret=ret*x%M;
        x=1ll*x*x%M; y>>=1;
    }
    return (int)ret;
}
void add(int &x,int y){
    x+=y; if (x>=M) x-=M;
}
void sub(int &x,int y){
    x-=y; if (x<0) x+=M;
}

int main(){
    p[0]=0;for (int i=1;i<maxn;i++) p[i]=(p[i-1]*2+1)%M,invp[i]=pow_(p[i],M-2);
    cin >> n >> c;
    for (int i=1;i<=n;i++) {cin >> a[i];--a[i];}
    if (c>=12){
        for (int l=0;l<n;l++){
            ll res=1;
            int tot=0;
            memset(cnt,0,sizeof(cnt));
            for (int r=l+1;r<=n;r++){
                if (cnt[a[r]]) res=res*invp[cnt[a[r]]]%M; else ++tot;
                cnt[a[r]]++;
                if (tot==c) w[l][r]=res;
                res=res*p[cnt[a[r]]]%M;
            }
        }
        dp[0][0]=1;
        for (int i=0;i<n;i++)
            for (int j=i+1;j<=n;j++) if (w[i][j])
                for (int k=0;k<=i/c;k++)
                    add(dp[j][k+1],1ll*dp[i][k]*w[i][j]%M);
        for (int i=0;i<=n;i++)
            for (int k=0;k<=i/c;k++)
                add(ans[k],1ll*dp[i][k]*(p[n-i]+1)%M);
        for (int i=0;i<n;i++) sub(ans[i],ans[i+1]);
    } else {
        int r=1<<c; f[0][0][0]=1;
        for (int i=1;i<=n;i++){
            int o=i&1;
            for (int k=0;k<=i/c;k++)
                for (int j=0;j<r;j++) if (f[o^1][k][j]){
                    add(f[o][k][j],f[o^1][k][j]);
                    add(f[o][k][j|(1<<a[i])],f[o^1][k][j]);
                    f[o^1][k][j]=0;
                }
            for (int k=0;k<=i/c;k++) {
                add(f[o][k+1][0],f[o][k][r-1]);
                f[o][k][r-1]=0;
            }
        }
        for (int k=0;k<=n/c;k++)
            for (int j=0;j<r;j++)
                add(ans[k],f[n&1][k][j]);
    }
    sub(ans[0],1);
    for (int i=0;i<=n;i++) cout << ans[i] << ' '; cout << endl;
    return 0;
}


#include <math.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define meow(args...) fprintf(stderr, args)
const int P=998244353;
int n, c, a[3000], f[3001], ff[3001][1<<11], cnt[3000], key[3001], ikey[3001];
int F()
{
	int a=0;
	unsigned char c;
	while((c=getchar()-48)>9);
	while(a=a*10+c, (c=getchar()-48)<=9);
	return a;
}
long long power(long long a, int b)
{
	long long ans=1;
	for(; b; a=a*a%P, b>>=1) if(b&1) ans=ans*a%P;
	return ans;
}
int main()
{
	n=F(), c=F();
	for(int i=0; i<n; ++i) a[i]=F()-1;
	if(c<=log2(n)) {
		int fs=(1<<c)-1, ans=-1;
		ff[0][0]=1;
		for(int i=n; i--; ) {
			for(int j=n/c; j>=0; --j) {
				for(int k=0; (k|=1<<a[i])<fs; ++k) ff[j][k]=(ff[j][k]*2ll+ff[j][k^1<<a[i]])%P;
				if(j) ff[j][0]=(ff[j][0]+ff[j-1][fs^1<<a[i]])%P;
			}
		}
		for(int j=0; j<fs; ++j) ans=(ans+ff[0][j])%P;
		printf("%d", ans);
		for(int i=1; i<=n/c; ++i) {
			ans=0;
			for(int j=0; j<fs; ++j) ans=(ans+ff[i][j])%P;
			printf(" %d", ans);
		}
		for(int i=n/c+1; i<=n; ++i) printf(" 0");
		printf("\n");
	} else {
		for(int i=1; i<=n; ++i) {
			key[i]=(key[i-1]*2+1)%P;
			ikey[i]=power(key[i], P-2)%P;
		}
		ff[n][0]=1;
		for(int i=n; i--; ) {
			int nzero=c-1;
			long long g=1;
			memset(cnt, 0, c*sizeof(int));
			for(int j=i; j<n; ++j) {
				if(a[j]!=a[i]) {
					if(cnt[a[j]]) g=g*ikey[cnt[a[j]]]%P; else --nzero;
					g=g*key[++cnt[a[j]]]%P;
				}
				if(nzero==0&&g) for(int k=1; k<=n/c; ++k) ff[i][k]=(ff[i][k]+ff[j+1][k-1]*g)%P;
			}
		}
		for(int i=0; i<=n; ++i) for(int j=0; j<=n/c; ++j) f[j]=(f[j]+ff[i][j]*(key[i]+1ll))%P;
		--f[0];
		for(int i=0; i<n; ++i) if((f[i]-=f[i+1])<0) f[i]+=P;
		for(int i=0; i<n; ++i) printf("%d ", f[i]);
		printf("%d\n", f[n]);
	}
	return 0;
}


#include <math.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define meow(args...) fprintf(stderr, args)
const int P=998244353;
int n, c, a[3000], f[3001], ff[3001][1<<12], cnt[3000], key[3001], ikey[3001];
int F()
{
	int a=0;
	unsigned char c;
	while((c=getchar()-48)>9);
	while(a=a*10+c, (c=getchar()-48)<=9);
	return a;
}
long long power(long long a, int b)
{
	long long ans=1;
	for(; b; a=a*a%P, b>>=1) if(b&1) ans=ans*a%P;
	return ans;
}
int main()
{
	n=F(), c=F();
	for(int i=0; i<n; ++i) a[i]=F()-1;
	if(c<=log2(n)) {
		int fs=(1<<c)-1, ans=-1;
		ff[0][0]=1;
		for(int i=n; i--; ) {
			for(int j=n/c; j>=0; --j) {
				for(int k=0; (k|=1<<a[i])<fs; ++k) ff[j][k]=(ff[j][k]*2ll+ff[j][k^1<<a[i]])%P;
				if(j) ff[j][0]=(ff[j][0]+ff[j-1][fs^1<<a[i]])%P;
			}
		}
		for(int j=0; j<fs; ++j) ans=(ans+ff[0][j])%P;
		printf("%d", ans);
		for(int i=1; i<=n/c; ++i) {
			ans=0;
			for(int j=0; j<fs; ++j) ans=(ans+ff[i][j])%P;
			printf(" %d", ans);
		}
		for(int i=n/c+1; i<=n; ++i) printf(" 0");
		printf("\n");
	} else {
		for(int i=1; i<=n; ++i) {
			key[i]=(key[i-1]*2+1)%P;
			ikey[i]=power(key[i], P-2)%P;
		}
		ff[n][0]=1;
		for(int i=n; i--; ) {
			int nzero=c-1;
			long long g=1;
			memset(cnt, 0, c*sizeof(int));
			for(int j=i; j<n; ++j) {
				if(a[j]!=a[i]) {
					if(cnt[a[j]]) g=g*ikey[cnt[a[j]]]%P; else --nzero;
					g=g*key[++cnt[a[j]]]%P;
				}
				if(nzero==0&&g) for(int k=0; k<=(n-j)/c; ++k) if(ff[j+1][k]) ff[i][k+1]=(ff[i][k+1]+ff[j+1][k]*g)%P;
			}
		}
		for(int i=0; i<=n; ++i) for(int j=0; j<=n/c; ++j) f[j]=(f[j]+ff[i][j]*(key[i]+1ll))%P;
		--f[0];
		for(int i=0; i<n; ++i) if((f[i]-=f[i+1])<0) f[i]+=P;
		for(int i=0; i<n; ++i) printf("%d ", f[i]);
		printf("%d\n", f[n]);
	}
	return 0;
}


#include <math.h>
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#define meow(args...) fprintf(stderr, args)
const int P=998244353;
int n, c, a[3000], f[3001], ff[3001][1<<12], cnt[3000], key[3001], ikey[3001];
int F()
{
	int a=0;
	unsigned char c;
	while((c=getchar()-48)>9);
	while(a=a*10+c, (c=getchar()-48)<=9);
	return a;
}
long long power(long long a, int b)
{
	long long ans=1;
	for(; b; a=a*a%P, b>>=1) if(b&1) ans=ans*a%P;
	return ans;
}
int main()
{
	n=F(), c=F();
	for(int i=0; i<n; ++i) a[i]=F()-1;
	if(c<=log2(n)+1) {
		int fs=(1<<c)-1, ans=-1;
		ff[0][0]=1;
		for(int i=n; i--; ) {
			for(int j=n/c; j>=0; --j) {
				for(int k=0; (k|=1<<a[i])<fs; ++k) ff[j][k]=(ff[j][k]*2ll+ff[j][k^1<<a[i]])%P;
				if(j) ff[j][0]=(ff[j][0]+ff[j-1][fs^1<<a[i]])%P;
			}
		}
		for(int j=0; j<fs; ++j) ans=(ans+ff[0][j])%P;
		printf("%d", ans);
		for(int i=1; i<=n/c; ++i) {
			ans=0;
			for(int j=0; j<fs; ++j) ans=(ans+ff[i][j])%P;
			printf(" %d", ans);
		}
		for(int i=n/c+1; i<=n; ++i) printf(" 0");
		printf("\n");
	} else {
		for(int i=1; i<=n; ++i) {
			key[i]=(key[i-1]*2+1)%P;
			ikey[i]=power(key[i], P-2)%P;
		}
		ff[n][0]=1;
		for(int i=n; i--; ) {
			int nzero=c-1;
			long long g=1;
			memset(cnt, 0, c*sizeof(int));
			for(int j=i; j<n; ++j) {
				if(a[j]!=a[i]) {
					if(cnt[a[j]]) g=g*ikey[cnt[a[j]]]%P; else --nzero;
					g=g*key[++cnt[a[j]]]%P;
				}
				if(nzero==0&&g) for(int k=0; k<=(n-j)/c; ++k) if(ff[j+1][k]) ff[i][k+1]=(ff[i][k+1]+ff[j+1][k]*g)%P;
			}
		}
		for(int i=0; i<=n; ++i) for(int j=0; j<=n/c; ++j) f[j]=(f[j]+ff[i][j]*(key[i]+1ll))%P;
		--f[0];
		for(int i=0; i<n; ++i) if((f[i]-=f[i+1])<0) f[i]+=P;
		for(int i=0; i<n; ++i) printf("%d ", f[i]);
		printf("%d\n", f[n]);
	}
	return 0;
}


#pragma region
#ifndef M207
#pragma GCC optimize("O2,Ofast,inline,unroll-all-loops,-ffast-math")
#endif
#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define il inline
#define LL long long
#define uint unsigned int
#define ull unsigned long long
#define solid const auto &
#define pb emplace_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<LL,LL>
#define fi first
#define se second
#define gm int mid((l+r)/2)
#define space putchar(' ')
#define enter putchar('\n')
#define rd() ({ri t;in(t);t;})
#define Size(x) ((int)x.size())
#define mem(x,y) memset(x,y,sizeof(x))
template<class T>il void in(T &x)
{
	x=0; char c=getchar(); bool f=0;
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=x*10+(c^'0'),c=getchar();
	f?x=-x:0;
}
template<class T>il void out(T x,const char c='\n')
{
	static short st[40]; short m=0;
	if(x<0) putchar('-'),x=-x;
	do st[++m]=x%10,x/=10; while(x);
	while(m) putchar(st[m--]|'0');
	putchar(c);
}
template<class T>il void err(const T &x,const char c='\n') {cerr<<x<<c;}
template<class T,class ...Args>il void in(T &x,Args &...args) {in(x); in(args...);}
template<class T,class ...Args>il void out(const T &x,const Args &...args) {out(x,' '); out(args...);}
template<class T,class ...Args>il void err(const T &x,const Args &...args) {err(x,' '); err(args...);}
template<class T>il void prt(T a,int n) {for(ri i=0; i<n; ++i) out(a[i],i==n-1?'\n':' ');}
template<class T>il void clr(T a[],int n) {memset(a,0,sizeof(T)*n);}
template<class T>il void clr(T *a,T *b) {memset(a,0,sizeof(T)*(b-a));}
template<class T>il bool ckmax(T &a,const T &b) {return a<b?a=b,1:0;}
template<class T>il bool ckmin(T &a,const T &b) {return a>b?a=b,1:0;}
namespace MOD_CALC
{
const int md=998244353,inv2=(md+1)/2;
il int add(const int a,const int b) {return a+b>=md?a+b-md:a+b;}
il int sub(const int a,const int b) {return a-b<0?a-b+md:a-b;}
il int mul(const int a,const int b) {return (LL)a*b%md;}
il void inc(int &a,const int b) {(a+=b)>=md?a-=md:0;}
il void dec(int &a,const int b) {(a-=b)<0?a+=md:0;}
il int qpow(int a,int b) {int r=1; for(; b; b>>=1,a=mul(a,a)) if(b&1) r=mul(r,a); return r;}
il int qpow(int a,int b,const int p) {int r=1; for(; b; b>>=1,a=(LL)a*a%p) if(b&1) r=(LL)r*a%p; return r;}
il int mdinv(const int a) {return qpow(a,md-2);}
template<class ...Args>il int add(const int a,const int b,const Args &...args) {return add(add(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
} using namespace MOD_CALC;
namespace i207M
{
#pragma endregion
#define N 3005
int n,sig;
int a[N];
namespace S1
{
int _dp[2][N][1<<12];
void solve()
{
	if(sig==1)
	{
		out(0,' '); int fac=1;
		for(ri i=1; i<=n; ++i)
		{
			fac=mul(fac,n-i+1,mdinv(i));
			out(fac,' ');
		}
		return;
	}
	auto f=_dp[0],g=_dp[1]; int U=(1<<sig)-1;
	f[0][0]=1;
	for(ri i=1; i<=n; ++i)
	{
		swap(f,g); int w=1<<(a[i]-1);
		for(ri j=0; j*sig<=i; ++j)
		{
			for(ri s=0; s<=U; ++s)
			{
				int &v=g[j][s];
				if(!v) continue;
				// not choose
				inc(f[j][s],v);
				// choose
				inc(f[j][s|w],v);
				v=0;
			}
			inc(f[j+1][0],f[j][U]);
			f[j][U]=0;
		}
	}
	--f[0][0];
	for(ri i=0; i<=n; ++i)
	{
		int t=0;
		for(ri s=0; s<=U; ++s) inc(t,f[i][s]);
		out(t,' ');
	}
}
}
namespace S2
{
int dp[N][N],f[N][N];
int cnt[N],prod;
int pw2[N],ipw21[N];
void solve()
{
	pw2[0]=ipw21[0]=1;
	for(ri i=1; i<=n; ++i)
	{
		pw2[i]=add(pw2[i-1],pw2[i-1]);
		ipw21[i]=mdinv(pw2[i]-1);
	}
	for(ri l=1; l<=n; ++l)
	{
		mem(cnt,0),prod=1; int app=0;
		for(ri r=l; r<=n; ++r)
		{
			if(++cnt[a[r]]==1)
			{
				if(++app==sig)
				{
					for(ri i=1; i<=sig; ++i) prod=mul(prod,pw2[cnt[i]]-1);
				}
			}
			if(app==sig)
			{
				prod=mul(prod,ipw21[cnt[a[r]]-1],pw2[cnt[a[r]]]-1);
				if(a[l]!=a[r]) f[l][r]=mul(prod,ipw21[cnt[a[l]]],ipw21[cnt[a[r]]],pw2[cnt[a[l]]-1]);
			}
		}
	}
	dp[n+1][0]=1;
	for(ri i=n; i>=1; --i)
	{
		for(ri k=i+1; k<=n; ++k)
			if(f[i][k]) for(ri j=1; j*sig<=n-i+1; ++j)
					inc(dp[i][j],mul(f[i][k],dp[k+1][j-1]));
		dp[i][0]=pw2[n-i];
		for(ri j=0; j*sig<=n-i+1; ++j)
			inc(dp[i][j],dp[i+1][j]);
	}
	--dp[1][0];
	for(ri i=0; i<=n; ++i) out(sub(dp[1][i],dp[1][i+1]),' ');
}
}
signed main()
{
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("ot.out","w",stdout);
#endif
	in(n,sig);
	for(ri i=1; i<=n; ++i) in(a[i]);
	if(sig<=12) S1::solve();
	else S2::solve();
	return 0;
}
#pragma region
}
signed main()
{
	i207M::main();
	return 0;
}
#pragma endregion


#pragma region
#ifndef M207
#pragma GCC optimize("O2,Ofast,inline,unroll-all-loops,-ffast-math")
#endif
#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define il inline
#define LL long long
#define uint unsigned int
#define ull unsigned long long
#define solid const auto &
#define pb emplace_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<LL,LL>
#define fi first
#define se second
#define gm int mid((l+r)/2)
#define space putchar(' ')
#define enter putchar('\n')
#define rd() ({ri t;in(t);t;})
#define Size(x) ((int)x.size())
#define mem(x,y) memset(x,y,sizeof(x))
template<class T>il void in(T &x)
{
	x=0; char c=getchar(); bool f=0;
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=x*10+(c^'0'),c=getchar();
	f?x=-x:0;
}
template<class T>il void out(T x,const char c='\n')
{
	static short st[40]; short m=0;
	if(x<0) putchar('-'),x=-x;
	do st[++m]=x%10,x/=10; while(x);
	while(m) putchar(st[m--]|'0');
	putchar(c);
}
template<class T>il void err(const T &x,const char c='\n') {cerr<<x<<c;}
template<class T,class ...Args>il void in(T &x,Args &...args) {in(x); in(args...);}
template<class T,class ...Args>il void out(const T &x,const Args &...args) {out(x,' '); out(args...);}
template<class T,class ...Args>il void err(const T &x,const Args &...args) {err(x,' '); err(args...);}
template<class T>il void prt(T a,int n) {for(ri i=0; i<n; ++i) out(a[i],i==n-1?'\n':' ');}
template<class T>il void clr(T a[],int n) {memset(a,0,sizeof(T)*n);}
template<class T>il void clr(T *a,T *b) {memset(a,0,sizeof(T)*(b-a));}
template<class T>il bool ckmax(T &a,const T &b) {return a<b?a=b,1:0;}
template<class T>il bool ckmin(T &a,const T &b) {return a>b?a=b,1:0;}
namespace MOD_CALC
{
const int md=998244353,inv2=(md+1)/2;
il int add(const int a,const int b) {return a+b>=md?a+b-md:a+b;}
il int sub(const int a,const int b) {return a-b<0?a-b+md:a-b;}
il int mul(const int a,const int b) {return (LL)a*b%md;}
il void inc(int &a,const int b) {(a+=b)>=md?a-=md:0;}
il void dec(int &a,const int b) {(a-=b)<0?a+=md:0;}
il int qpow(int a,int b) {int r=1; for(; b; b>>=1,a=mul(a,a)) if(b&1) r=mul(r,a); return r;}
il int qpow(int a,int b,const int p) {int r=1; for(; b; b>>=1,a=(LL)a*a%p) if(b&1) r=(LL)r*a%p; return r;}
il int mdinv(const int a) {return qpow(a,md-2);}
template<class ...Args>il int add(const int a,const int b,const Args &...args) {return add(add(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
} using namespace MOD_CALC;
namespace i207M
{
#pragma endregion
#define N 3005
int n,sig;
int a[N];
namespace S1
{
int _dp[2][N][1<<10];
void solve()
{
	if(sig==1)
	{
		out(0,' '); int fac=1;
		for(ri i=1; i<=n; ++i)
		{
			fac=mul(fac,n-i+1,mdinv(i));
			out(fac,' ');
		}
		return;
	}
	auto f=_dp[0],g=_dp[1]; int U=(1<<sig)-1;
	f[0][0]=1;
	for(ri i=1; i<=n; ++i)
	{
		swap(f,g); int w=1<<(a[i]-1);
		for(ri j=0; j*sig<=i; ++j)
		{
			for(ri s=0; s<=U; ++s)
			{
				int &v=g[j][s];
				if(!v) continue;
				// not choose
				inc(f[j][s],v);
				// choose
				inc(f[j][s|w],v);
				v=0;
			}
			inc(f[j+1][0],f[j][U]);
			f[j][U]=0;
		}
	}
	--f[0][0];
	for(ri i=0; i<=n; ++i)
	{
		int t=0;
		for(ri s=0; s<=U; ++s) inc(t,f[i][s]);
		out(t,' ');
	}
}
}
namespace S2
{
int dp[N][N],f[N][N];
int cnt[N],prod;
int pw2[N],ipw21[N];
void solve()
{
	pw2[0]=ipw21[0]=1;
	for(ri i=1; i<=n; ++i)
	{
		pw2[i]=add(pw2[i-1],pw2[i-1]);
		ipw21[i]=mdinv(pw2[i]-1);
	}
	for(ri l=1; l<=n; ++l)
	{
		mem(cnt,0),prod=1; int app=0;
		for(ri r=l; r<=n; ++r)
		{
			if(++cnt[a[r]]==1)
			{
				if(++app==sig)
				{
					for(ri i=1; i<=sig; ++i) prod=mul(prod,pw2[cnt[i]]-1);
				}
			}
			if(app==sig)
			{
				prod=mul(prod,ipw21[cnt[a[r]]-1],pw2[cnt[a[r]]]-1);
				if(a[l]!=a[r]) f[l][r]=mul(prod,ipw21[cnt[a[l]]],ipw21[cnt[a[r]]],pw2[cnt[a[l]]-1]);
			}
		}
	}
	dp[n+1][0]=1;
	for(ri i=n; i>=1; --i)
	{
		for(ri k=i+1; k<=n; ++k)
			if(f[i][k]) for(ri j=1; j*sig<=n-i+1; ++j)
					inc(dp[i][j],mul(f[i][k],dp[k+1][j-1]));
		dp[i][0]=pw2[n-i];
		for(ri j=0; j*sig<=n-i+1; ++j)
			inc(dp[i][j],dp[i+1][j]);
	}
	--dp[1][0];
	for(ri i=0; i<=n; ++i) out(sub(dp[1][i],dp[1][i+1]),' ');
}
}
signed main()
{
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("ot.out","w",stdout);
#endif
	in(n,sig);
	for(ri i=1; i<=n; ++i) in(a[i]);
	if(sig<=10) S1::solve();
	else S2::solve();
	return 0;
}
#pragma region
}
signed main()
{
	i207M::main();
	return 0;
}
#pragma endregion


#pragma region
#ifndef M207
#pragma GCC optimize("O2,Ofast,inline,unroll-all-loops,-ffast-math")
#endif
#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define il inline
#define LL long long
#define uint unsigned int
#define ull unsigned long long
#define solid const auto &
#define pb emplace_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<LL,LL>
#define fi first
#define se second
#define gm int mid((l+r)/2)
#define space putchar(' ')
#define enter putchar('\n')
#define rd() ({ri t;in(t);t;})
#define Size(x) ((int)x.size())
#define mem(x,y) memset(x,y,sizeof(x))
template<class T>il void in(T &x)
{
	x=0; char c=getchar(); bool f=0;
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=x*10+(c^'0'),c=getchar();
	f?x=-x:0;
}
template<class T>il void out(T x,const char c='\n')
{
	static short st[40]; short m=0;
	if(x<0) putchar('-'),x=-x;
	do st[++m]=x%10,x/=10; while(x);
	while(m) putchar(st[m--]|'0');
	putchar(c);
}
template<class T>il void err(const T &x,const char c='\n') {cerr<<x<<c;}
template<class T,class ...Args>il void in(T &x,Args &...args) {in(x); in(args...);}
template<class T,class ...Args>il void out(const T &x,const Args &...args) {out(x,' '); out(args...);}
template<class T,class ...Args>il void err(const T &x,const Args &...args) {err(x,' '); err(args...);}
template<class T>il void prt(T a,int n) {for(ri i=0; i<n; ++i) out(a[i],i==n-1?'\n':' ');}
template<class T>il void clr(T a[],int n) {memset(a,0,sizeof(T)*n);}
template<class T>il void clr(T *a,T *b) {memset(a,0,sizeof(T)*(b-a));}
template<class T>il bool ckmax(T &a,const T &b) {return a<b?a=b,1:0;}
template<class T>il bool ckmin(T &a,const T &b) {return a>b?a=b,1:0;}
namespace MOD_CALC
{
const int md=998244353,inv2=(md+1)/2;
il int add(const int a,const int b) {return a+b>=md?a+b-md:a+b;}
il int sub(const int a,const int b) {return a-b<0?a-b+md:a-b;}
il int mul(const int a,const int b) {return (LL)a*b%md;}
il void inc(int &a,const int b) {(a+=b)>=md?a-=md:0;}
il void dec(int &a,const int b) {(a-=b)<0?a+=md:0;}
il int qpow(int a,int b) {int r=1; for(; b; b>>=1,a=mul(a,a)) if(b&1) r=mul(r,a); return r;}
il int qpow(int a,int b,const int p) {int r=1; for(; b; b>>=1,a=(LL)a*a%p) if(b&1) r=(LL)r*a%p; return r;}
il int mdinv(const int a) {return qpow(a,md-2);}
template<class ...Args>il int add(const int a,const int b,const Args &...args) {return add(add(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
} using namespace MOD_CALC;
namespace i207M
{
#pragma endregion
#define N 3005
int n,sig;
int a[N];
namespace S1
{
int _dp[2][N][1<<11];
void solve()
{
	if(sig==1)
	{
		out(0,' '); int fac=1;
		for(ri i=1; i<=n; ++i)
		{
			fac=mul(fac,n-i+1,mdinv(i));
			out(fac,' ');
		}
		return;
	}
	auto f=_dp[0],g=_dp[1]; int U=(1<<sig)-1;
	f[0][0]=1;
	for(ri i=1; i<=n; ++i)
	{
		swap(f,g); int w=1<<(a[i]-1);
		for(ri j=0; j*sig<=i; ++j)
		{
			for(ri s=0; s<=U; ++s)
			{
				int &v=g[j][s];
				if(!v) continue;
				// not choose
				inc(f[j][s],v);
				// choose
				inc(f[j][s|w],v);
				v=0;
			}
			inc(f[j+1][0],f[j][U]);
			f[j][U]=0;
		}
	}
	--f[0][0];
	for(ri i=0; i<=n; ++i)
	{
		int t=0;
		for(ri s=0; s<=U; ++s) inc(t,f[i][s]);
		out(t,' ');
	}
}
}
namespace S2
{
int dp[N][N],f[N][N];
int cnt[N],prod;
int pw2[N],ipw21[N];
void solve()
{
	pw2[0]=ipw21[0]=1;
	for(ri i=1; i<=n; ++i)
	{
		pw2[i]=add(pw2[i-1],pw2[i-1]);
		ipw21[i]=mdinv(pw2[i]-1);
	}
	for(ri l=1; l<=n; ++l)
	{
		mem(cnt,0),prod=1; int app=0;
		for(ri r=l; r<=n; ++r)
		{
			if(++cnt[a[r]]==1)
			{
				if(++app==sig)
				{
					for(ri i=1; i<=sig; ++i) prod=mul(prod,pw2[cnt[i]]-1);
				}
			}
			if(app==sig)
			{
				prod=mul(prod,ipw21[cnt[a[r]]-1],pw2[cnt[a[r]]]-1);
				if(a[l]!=a[r]) f[l][r]=mul(prod,ipw21[cnt[a[l]]],ipw21[cnt[a[r]]],pw2[cnt[a[l]]-1]);
			}
		}
	}
	dp[n+1][0]=1;
	for(ri i=n; i>=1; --i)
	{
		for(ri k=i+1; k<=n; ++k)
			if(f[i][k]) for(ri j=1; j*sig<=n-i+1; ++j)
					inc(dp[i][j],mul(f[i][k],dp[k+1][j-1]));
		dp[i][0]=pw2[n-i];
		for(ri j=0; j*sig<=n-i+1; ++j)
			inc(dp[i][j],dp[i+1][j]);
	}
	--dp[1][0];
	for(ri i=0; i<=n; ++i) out(sub(dp[1][i],dp[1][i+1]),' ');
}
}
signed main()
{
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("ot.out","w",stdout);
#endif
	in(n,sig);
	for(ri i=1; i<=n; ++i) in(a[i]);
	if(sig<=11) S1::solve();
	else S2::solve();
	return 0;
}
#pragma region
}
signed main()
{
	i207M::main();
	return 0;
}
#pragma endregion


#pragma region
#ifndef M207
#pragma GCC optimize("O2,Ofast,inline,unroll-all-loops,-ffast-math")
#endif
#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define il inline
#define LL long long
#define uint unsigned int
#define ull unsigned long long
#define solid const auto &
#define pb emplace_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<LL,LL>
#define fi first
#define se second
#define gm int mid((l+r)/2)
#define space putchar(' ')
#define enter putchar('\n')
#define rd() ({ri t;in(t);t;})
#define Size(x) ((int)x.size())
#define mem(x,y) memset(x,y,sizeof(x))
template<class T>il void in(T &x)
{
	x=0; char c=getchar(); bool f=0;
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=x*10+(c^'0'),c=getchar();
	f?x=-x:0;
}
template<class T>il void out(T x,const char c='\n')
{
	static short st[40]; short m=0;
	if(x<0) putchar('-'),x=-x;
	do st[++m]=x%10,x/=10; while(x);
	while(m) putchar(st[m--]|'0');
	putchar(c);
}
template<class T>il void err(const T &x,const char c='\n') {cerr<<x<<c;}
template<class T,class ...Args>il void in(T &x,Args &...args) {in(x); in(args...);}
template<class T,class ...Args>il void out(const T &x,const Args &...args) {out(x,' '); out(args...);}
template<class T,class ...Args>il void err(const T &x,const Args &...args) {err(x,' '); err(args...);}
template<class T>il void prt(T a,int n) {for(ri i=0; i<n; ++i) out(a[i],i==n-1?'\n':' ');}
template<class T>il void clr(T a[],int n) {memset(a,0,sizeof(T)*n);}
template<class T>il void clr(T *a,T *b) {memset(a,0,sizeof(T)*(b-a));}
template<class T>il bool ckmax(T &a,const T &b) {return a<b?a=b,1:0;}
template<class T>il bool ckmin(T &a,const T &b) {return a>b?a=b,1:0;}
namespace MOD_CALC
{
const int md=998244353,inv2=(md+1)/2;
il int add(const int a,const int b) {return a+b>=md?a+b-md:a+b;}
il int sub(const int a,const int b) {return a-b<0?a-b+md:a-b;}
il int mul(const int a,const int b) {return (LL)a*b%md;}
il void inc(int &a,const int b) {(a+=b)>=md?a-=md:0;}
il void dec(int &a,const int b) {(a-=b)<0?a+=md:0;}
il int qpow(int a,int b) {int r=1; for(; b; b>>=1,a=mul(a,a)) if(b&1) r=mul(r,a); return r;}
il int qpow(int a,int b,const int p) {int r=1; for(; b; b>>=1,a=(LL)a*a%p) if(b&1) r=(LL)r*a%p; return r;}
il int mdinv(const int a) {return qpow(a,md-2);}
template<class ...Args>il int add(const int a,const int b,const Args &...args) {return add(add(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
} using namespace MOD_CALC;
namespace i207M
{
#pragma endregion
#define N 3005
int n,sig;
int a[N];
namespace S1
{
int _dp[2][N][1<<12];
void solve()
{
	if(sig==1)
	{
		out(0,' '); int fac=1;
		for(ri i=1; i<=n; ++i)
		{
			fac=mul(fac,n-i+1,mdinv(i));
			out(fac,' ');
		}
		return;
	}
	auto f=_dp[0],g=_dp[1]; int U=(1<<sig)-1;
	f[0][0]=1;
	for(ri i=1; i<=n; ++i)
	{
		swap(f,g); int w=1<<(a[i]-1);
		for(ri j=0; j*sig<=i; ++j)
		{
			for(ri s=0; s<=U; ++s)
			{
				int &v=g[j][s];
				if(!v) continue;
				// not choose
				inc(f[j][s],v);
				// choose
				inc(f[j][s|w],v);
				v=0;
			}
			inc(f[j+1][0],f[j][U]);
			f[j][U]=0;
		}
	}
	--f[0][0];
	for(ri i=0; i<=n; ++i)
	{
		int t=0;
		for(ri s=0; s<=U; ++s) inc(t,f[i][s]);
		out(t,' ');
	}
}
}
namespace S2
{
int dp[N][N],f[N][N];
int cnt[N],prod;
int pw2[N],ipw21[N];
void solve()
{
	pw2[0]=ipw21[0]=1;
	for(ri i=1; i<=n; ++i)
	{
		pw2[i]=add(pw2[i-1],pw2[i-1]);
		ipw21[i]=mdinv(pw2[i]-1);
	}
	for(ri l=1; l<=n; ++l)
	{
		mem(cnt,0),prod=1; int app=0;
		for(ri r=l; r<=n; ++r)
		{
			if(++cnt[a[r]]==1)
			{
				if(++app==sig)
				{
					for(ri i=1; i<=sig; ++i) prod=mul(prod,pw2[cnt[i]]-1);
				}
			}
			if(app==sig)
			{
				prod=mul(prod,ipw21[cnt[a[r]]-1],pw2[cnt[a[r]]]-1);
				if(a[l]!=a[r]) f[l][r]=mul(prod,ipw21[cnt[a[l]]],ipw21[cnt[a[r]]],pw2[cnt[a[l]]-1]);
			}
		}
	}
	dp[n+1][0]=1;
	for(ri i=n; i>=1; --i)
	{
		for(ri j=1; j*sig<=n-i+1; ++j)
		{
			for(ri k=i+sig-1; k<=n&&dp[k+1][j-1]; ++k)
				inc(dp[i][j],mul(f[i][k],dp[k+1][j-1]));
			if(!dp[i][j]) break;
		}
		dp[i][0]=pw2[n-i];
		for(ri j=0; j*sig<=n-i+1; ++j)
			inc(dp[i][j],dp[i+1][j]);
	}
	--dp[1][0];
	for(ri i=0; i<=n; ++i) out(sub(dp[1][i],dp[1][i+1]),' ');
}
}
signed main()
{
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("ot.out","w",stdout);
#endif
	in(n,sig);
	for(ri i=1; i<=n; ++i) in(a[i]);
	if(sig<=11) S1::solve();
	else S2::solve();
	return 0;
}
#pragma region
}
signed main()
{
	i207M::main();
	return 0;
}
#pragma endregion