#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <map>

using namespace std;
using ll = long long;

constexpr int INF = 1e9 + 7;
constexpr ll LINF = 1e18 + 7;
constexpr int MOD = 998244353;
//
// struct SegmentTree {
//    struct node {
//       ll s;
//       int mx;
//       int l, r;
//       node() {
//          s = 0;
//          mx = 0;
//          l = -1;
//          r = -1;
//       }
//    };
//
//    vector<node>tree;
//
//    inline int L(int v) {
//       if (tree[v].l == -1) {
//          tree[v].l = tree.size();
//          tree.push_back(node());
//       }
//       return tree[v].l;
//    }
//
//    inline int R(int v) {
//       if (tree[v].r == -1) {
//          tree[v].r = tree.size();
//          tree.push_back(node());
//       }
//       return tree[v].r;
//    }
//
//    void build(vector<int>&a, int l, int r, int v) {
//       if (r - l == 1) {
//          tree[v].s = tree[v].mx = a[l];
//          return;
//       }
//       int mid = (l + r) / 2;
//       build(a, l, mid, L(v));
//       build(a, mid, r, R(v));
//       tree[v].s = tree[L(v)].s + tree[R(v)].s;
//       tree[v].mx = max(tree[L(v)].mx, tree[R(v)].mx);
//    }
//
//    int getmax(int ql, int qr ,int l, int r, int v) {
//       if (qr <= l || ql >= r) return -INF;
//       if (ql <= l && r <= qr) return tree[v].mx;
//       int mid = (l + r) / 2;
//       return max(getmax(ql, qr, l, mid, L(v)), getmax(ql, qr, mid, r, R(v)));
//    }
//
//
//    ll getsum(int ql, int qr, int l, int r, int v) {
//       if (qr <= l || ql >= r) return 0;
//       if (ql <= l && r <= qr) return tree[v].s;
//       int mid = (l + r) / 2;
//       return getsum(ql, qr, l, mid, L(v)) + getsum(ql, qr, mid, r, R(v));
//    }
//
//    SegmentTree(vector<int>&a) {
//       int n = a.size();
//       build(a, 0, n, 0);
//    }
// };

ll binpow(ll s, ll n) {
	if (n == 0) return 1;
	if (n & 1) return binpow(s, n - 1) * s % MOD;
	ll d = binpow(s, n / 2);
	return d * d % MOD;
}

int main() {
	cin.tie(0)->sync_with_stdio(0);
	int n, q;
	cin >> n >> q;
	vector<int>p(n);
	vector<int>b(q);
	for (int i = 0; i < n; ++i) cin >> p[i];
	for (int i = 0; i < q; ++i) cin >> b[i];
	vector<vector<int>>a(8, vector<int>(n));
	for (int i = 0; i < n; ++i) {
		a[0][i] = p[i];
		a[1][i] = p[n - i - 1];
		a[2][i] = n - p[i] + 1;
	}
	for (int i = 0; i < n; ++i) {
		a[3][i] = n - a[1][i] + 1;
	}
	vector<pair<ll, ll>>s(8);
	for (int i = 0; i < 8; ++i) {
		for (int j = 0; j < n; ++j) {
			s[i].first = (s[i].first + binpow(a[i][j], j + 1)) % MOD;
			s[i].second = (s[i].second + binpow(j + 1, a[i][j])) % MOD;

		}
	}
	int t = 0;
	for (int i = 0; i < q; ++i) {
		if (b[i] == 3) {
			if (t & 4) {
				if (t == 4) t = 0;
				else if (t == 5) t = 2;
				else if (t == 6) t = 1;
				else if (t == 7) t = 3;
			}
			else {
				t = t + 4;
			}
		}
		else {
			if (t & 4) {
				b[i] = 3 - b[i];
			}
			t = t ^ (1 << (b[i] - 1));
		}
		if (t & 4) {
			cout << s[t % 4].second << ' ';
		}
		else {
			cout << s[t % 4].first << ' ';
		}
	}
}