#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <random>

using namespace std;
//mt19937 rnd(1908);
int inf = 1e9;
struct Node {
	int min, color;
	Node() {}
	Node(int m, int c) : min(m), color(c) {}
};
Node merge(Node a, Node b) {
	Node now;
	if (b.min < a.min) {
		now.color = b.color;
		now.min = b.min;
	}
	else {
		now.color = a.color;
		now.min = a.min;
	}
	return now;
}
struct SegTree {
	int n;
	vector<Node> tree;
	void build(int v, int l, int r, vector<int>& a) {
		if (v == 1) {
			tree.resize(r << 2);
			n = r;
		}
		if (l + 1 == r) {
			tree[v].min = a[l];
			tree[v].color = l;
			return;
		}
		int mid = (l + r) >> 1;
		build(v << 1, l, mid, a);
		build((v << 1) + 1, mid, r, a);
		tree[v] = merge(tree[v << 1], tree[(v << 1) + 1]);
	}
	void update(int v, int l, int r, int i, int x) {
		if (l + 1 == r) {
			tree[v].min = x;
			return;
		}
		int mid = (l + r) >> 1;
		if (i < mid) {
			update(v << 1, l, mid, i, x);
		}
		else {
			update((v << 1) + 1, mid, r, i, x);
		}
		tree[v] = merge(tree[v << 1], tree[(v << 1) + 1]);
	}
	Node get(int v, int l, int r, int ql, int qr) {
		if (qr <= l || r <= ql) return Node(inf, n);
		if (ql <= l && r <= qr) return tree[v];
		int mid = (l + r) >> 1;
		return merge(get(v << 1, l, mid, ql, qr), get((v << 1) + 1, mid, r, ql, qr));
	}
};

/*struct Tree {
	int n;
	struct Vertex {
		int p, sp, len_sp, tin, tout, sz = 1, up, d = 0;
		vector<int> gr;
	};
	vector<Vertex> vertexes;
	SegTree HLD_array;
	int root = 0;
	int t = 0;
	void pred_dfs(int v) {
		vertexes[v].up = v;
		for (int u : vertexes[v].gr) {
			if (u != vertexes[v].p) {
				vertexes[u].d = vertexes[v].d + 1;
				vertexes[u].p = v;
				if (vertexes[v].len_sp == vertexes[vertexes[v].sp].len_sp) {
					vertexes[u].len_sp = vertexes[v].len_sp * 2 + 1;
					vertexes[u].sp = vertexes[vertexes[v].sp].sp;
				}
				else {
					vertexes[u].sp = v;
					vertexes[u].len_sp = 1;
				}
				pred_dfs(u);
				vertexes[v].sz += vertexes[u].sz;
			}
		}
	}
	void weight_dfs(int v) {
		vertexes[v].tin = ++t;
		if (vertexes[v].gr.size()) {
			int best = vertexes[v].gr[0];
			for (int u : vertexes[v].gr) {
				if (u != vertexes[v].p && vertexes[best].sz < vertexes[u].sz) {
					best = u;
				}
			}
			vertexes[best].up = vertexes[v].up;
			weight_dfs(best);
			for (int u : vertexes[v].gr) {
				if (u != vertexes[v].p && u != best) {
					weight_dfs(u);
				}
			}
		}
		vertexes[v].tout = t;
	}
	void build(int N, int r, vector<vector<int>>& gr) {
		root = r;
		n = N;
		vertexes.resize(n);
		vertexes[root].p = root;
		vertexes[root].sp = root;
		vertexes[root].len_sp = 0;
		for (int i = 0; i < n; ++i) {
			vertexes[i].gr = gr[i];
		}
		pred_dfs(root);
	}
	int la(int v, int d) {
		while (vertexes[v].d > d) {
			if (vertexes[vertexes[v].sp].d > d) {
				v = vertexes[v].sp;
			}
			else {
				v = vertexes[v].p;
			}
		}
		return v;
	}
	int lca(int v, int u) {
		if (vertexes[v].d > vertexes[u].d) swap(v, u);
		u = la(u, vertexes[v].d);
		while (u != v) {
			if (vertexes[u].sp != vertexes[v].sp) {
				v = vertexes[v].sp;
				u = vertexes[u].sp;
			}
			else {
				v = vertexes[v].p;
				u = vertexes[u].p;
			}
		}
		return v;
	}
	void build_HLD(vector<long long>& a) {
		weight_dfs(root);
		vector<long long> on_tin(n);
		for (int i = 0; i < n; ++i) {
			on_tin[vertexes[i].tin] = a[i];
		}
		HLD_array.build(1, 0, n, on_tin);
	}
};*/

/*struct SparceTable {
	int n;
	vector<vector<long long>> d;
	vector<int> log;
	void build(vector<long long>& a) {
		n = a.size();
		log.resize(n + 1);
		for (int k = 0; (1 << k) <= n; ++k) {
			log[(1 << k)] = 0;
		}
		for (int i = 2; i <= n; ++i) {
			if (!log[i]) log[i] = log[i - 1];
		}
		d.resize(log[n] + 1, vector<long long>(n));
		for (int i = 0; i < n; ++i) {
			d[0][i] = a[i];
		}
		for (int k = 1; k < d.size(); ++k) {
			for (int i = 0; i < n - (1 << k) + 1; ++i) {
				d[k][i] = min(d[k - 1][i], d[k - 1][i + (1 << k)]);
			}
		}
	}
	long long get_min(int l, int r) {
		int lg = log[r - l];
		return min(d[lg][l], d[lg][r - (1 << lg)]);
	}
};

struct Kurevo {
	Kurevo* l = nullptr, * r = nullptr;
	long long sz = 1;
	long long val;
	long long sum;
	long long y = rnd();
	Kurevo(long long x) : val(x), sum(x) {}
};

long long get_sum(Kurevo* t) {
	if (!t) return 0;
	return t->sum;
}
long long get_sz(Kurevo* t) {
	if (!t) return 0;
	return t->sz;
}
void upd(Kurevo* t) {
	if (!t) return;
	t->sum = get_sum(t->l) + t->sum * get_sum(t->r);
	t->sz = get_sz(t->l) + 1 + get_sz(t->r);
}

Kurevo* merge(Kurevo* t1, Kurevo* t2) {
	if (!t1) return t2;
	if (!t2) return t1;
	if (t1->y > t2->y) {
		t1->r = merge(t1->r, t2);
		upd(t1);
		return t1;
	}
	else {
		t2->l = merge(t1, t2->l);
		upd(t2);
		return t2;
	}
}
pair<Kurevo*, Kurevo*> split(Kurevo* t, int k) {
	if (!t) return make_pair(nullptr, nullptr);
	if (get_sz(t->l) < k) {
		auto q = split(t->r, k - get_sz(t->l) - 1);
		t->r = q.first;
		upd(t);
		return make_pair(t, q.second);
	}
	else {
		auto q = split(t->l, k);
		t->l = q.second;
		upd(t);
		return make_pair(q.first, t);
	}
}*/
long long mod = 998244353;

long long bin_pow(long long a, long long st) {
	if (!st) return 1;
	if (st & 1) return (a * bin_pow(a, st - 1)) % mod;
	long long c = bin_pow(a, st >> 1);
	return (c * c) % mod;
}

int main() {
	int n, m;
	cin >> n >> m;
	vector<int> p(n);
	for (int i = 0; i < n; ++i) {
		cin >> p[i];
	}
	vector<int> b(m);
	for (int i = 0; i < m; ++i) {
		cin >> b[i];
	}
	long long f = 0;
	for (int i = 0; i < n; ++i) {
		f = (f + bin_pow(p[i], i + 1)) % mod;
	}
	vector<int> q(n);
	long long s = 0;
	if (b[0] == 1) {
		for (int i = 0; i < n; ++i) {
			q[n - i - 1] = p[i];
		}
	}
	else if (b[0] == 2) {
		for (int i = 0; i < n; ++i) {
			q[i] = n - p[i] + 1;
		}
	}
	else {
		for (int i = 0; i < n; ++i) {
			q[p[i] - 1] = i + 1;
		}
	}
	for (int i = 0; i < n; ++i) {
		s = (s + bin_pow(q[i], i + 1)) % mod;
	}
	for (int t = 0; t < m; ++t) {
		if (t & 1) {
			cout << f << ' ';
		}
		else {
			cout << s << ' ';
		}
	}
}