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

public class cf559F {

	BufferedReader br;
	PrintWriter out;
	StringTokenizer st;
	boolean eof;

	static final int P = 998244353;

	static int pow(int a, int b) {
		int ret = 1;
		for (; b > 0; b >>= 1) {
			if ((b & 1) == 1) {
				ret = (int) ((long) ret * a % P);
			}
			a = (int) ((long) a * a % P);
		}
		return ret;
	}

	int[][] bigC(int[] a, int c) {
		int n = a.length;

		int k = n / c;

		int[][] dp = new int[k + 1][n + 1];
		dp[0][0] = 1;

		int[] cf = new int[n + 1];
		int[] icf = new int[n + 1];
		cf[0] = 0;
		for (int i = 1; i < cf.length; i++) {
			cf[i] = 2 * cf[i - 1] + 1;
			if (cf[i] >= P) {
				cf[i] -= P;
			}
			icf[i] = pow(cf[i], P - 2);
		}

		for (int i = 0; i < n; i++) {
			int[] cnt = new int[c];
			int nz = 0;
			int prod = 1;
			for (int j = i; j < n; j++) {
				int x = a[j];
				
				if (cnt[x] > 0) {
					prod = (int) ((long) prod * icf[cnt[x]] % P);
				}

				if (nz == c || (nz == c - 1 && cnt[x] == 0)) {
					for (int l = 0; l < k; l++) {
						dp[l + 1][j + 1] += (int) ((long) dp[l][i] * prod % P);
					}
				}
				
				if (cnt[x] == 0) {
					nz++;
				}
				cnt[x]++;
				
				prod = (int) ((long)prod * cf[cnt[x]] % P);
			}
		}
		
		return dp;
	}
	
	int[][] smallC(int[] a, int c) {
		int n = a.length;

		int k = n / c;

		int[][] dp = new int[k + 1][n + 1];
		dp[0][0] = 1;
		
		int[][] aux = new int[k + 1][1 << c];
		
		aux[0][0] = 1;
		
		int all = (1 << c) - 1;
		
		for (int i = 0; i < n; i++) {
			int x = a[i];
			
			int[][] nxt = new int[k + 1][1 << c];
			
			for (int j = 0; j < k; j++) {
				int delta = aux[j][all ^ (1 << x)];
				dp[j + 1][i + 1] += delta;
				if (dp[j + 1][i + 1] >= P) {
					dp[j + 1][i + 1] -= P;
				}
				nxt[j + 1][0] += delta;
				if (nxt[j + 1][0] >= P) {
					nxt[j + 1][0] -= P;
				}
				
				for (int mask = 0; mask < 1 << c; mask++) {
					delta = aux[j][mask];
					nxt[j][mask] += delta;
					if (nxt[j][mask] >= P) {
						nxt[j][mask] -= P;
					}
					
					nxt[j][mask | (1 << x)] += delta;
					if (nxt[j][mask | (1 << x)] >= P) {
						nxt[j][mask | (1 << x)] -= P;
					}
				}
				
			}
			
			aux = nxt;
			
		}
		
		return dp;
	}

	void solve() throws IOException {
		int n = nextInt();
		int c = nextInt();

		int[] a = new int[n];
		for (int i = 0; i < n; i++) {
			a[i] = nextInt() - 1;
		}
		
		int[][] dp = c > 10 ? bigC(a, c) : smallC(a, c);
		
		int[] atL = new int[n + 2];
		long p2 = 1;
		for (int j = n; j >= 0; j--) {
			for (int i = 0; i < dp.length; i++) {
				atL[i] += (int)(p2 * dp[i][j] % P);
				if (atL[i] >= P) {
					atL[i] -= P;
				}
			}
			p2 = 2 * p2 % P;
		}
		
		atL[0]--;
		if (atL[0] < 0) {
			atL[0] += P;
		}
		
		for (int i = 0; i <= n; i++) {
			int x = atL[i] - atL[i + 1];
			if (x < 0) {
				x += P;
			}
			out.print(x + " ");
		}
		out.println();
	}

	void inp() throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		solve();
		out.close();
	}

	public static void main(String[] args) throws IOException {
		new cf559F().inp();
	}

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return null;
			}
		}
		return st.nextToken();
	}

	String nextString() {
		try {
			return br.readLine();
		} catch (IOException e) {
			eof = true;
			return null;
		}
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}
}
