#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <numbers>
#include <numeric>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <bit>
#include <deque>
using namespace std;
using ll = long long;
using db = double;


/* 
void dfs(int v, int p) {
    for (auto u : g[v]) {
        dfs(u, v);
    }
}
*/


/*
int l = 0, r = n + 1;
while (r - l > 1) {
    int mid = (l + r) / 2;
    if (...) {
        l = mid;
    } else {
        r = mid;
    }
}
*/


struct SparseTable {
    vector<vector<ll>> t;

    SparseTable(int n, vector<ll> &a) : t(21, vector<ll>(a.size())) {
        for (int k = 0; k < 21; k++) {
            for (int r = 0; r < n; r++) {
                if (k == 0) {
                    t[k][r] = a[r];
                    continue;
                }

                t[k][r] = max(t[k - 1][r], t[k - 1][r - (1 << (k - 1))]);
            }
        }
    }

    /* ll get(int l, int r) {
        return max(t[][r],
                   t[][r]);
    } */
};


struct Node {
    int val;

    Node() : val(0) {}

    Node(int val) : val(val) {}

    Node merge(const Node &other) const {
        return Node(val + other.val);
    }
};


template <typename Node>
struct Segtree {
    vector<Node> t;
    const Node NE;

    Segtree(int n, const Node &NE) : NE(NE) {
        t.resize(4 * n + 10);
    }

    void build(int v, int l, int r, vector<Node> &a) {
        if (l + 1 == r) {
            t[v] = a[l];
            return;
        }

        int mid = (l + r) / 2;
        build(2 * v + 1, l, mid, a);
        build(2 * v + 2, mid, r, a);
        t[v] = t[2 * v + 1]
        .merge(t[2 * v + 2]);
    }

    Node get(int v, int l, int r, int lq, int rq) {
        if (r <= lq || rq <= l) {
            return NE;
        }

        if (lq <= l && r <= rq) {
            return t[v];
        }

        int mid = (l + r) / 2;
        return get(2 * v + 1, l, mid, lq, rq)
        .merge(get(2 * v + 2, mid, r, lq, rq));
    }

    void update(int v, int l, int r, int i, const Node &x) {
        if (i < l || r <= i) {
            return;
        }

        if (l + 1 == r) {
            t[v] = x;
            return;
        }

        int mid = (l + r) / 2;
        update(2 * v + 1, l, mid, i, x);
        update(2 * v + 2, mid, r, i, x);
        t[v] = t[2 * v + 1]
        .merge(t[2 * v + 2]);
    }
};


vector<ll> rev(vector<ll> a) {
    reverse(a.begin(), a.end());
    return a;
}


vector<ll> res(vector<ll> a) {
    for (int i = 0; i < a.size(); i++) {
        a[i] = a.size() - a[i] + 1;
    }
    return a;
}


vector<ll> inv(vector<ll> a) {
    vector<ll> result(a.size());
    for (int i = 0; i < a.size(); i++) {
        result[a[i] - 1] = i + 1;
    }
    return result;
}


constexpr ll MOD = 998244353;


ll binpow(ll a, ll p) {
    ll res = 1;
    while (p) {
        if (p % 2 == 0) {
            a *= a;
            a %= MOD;
            p /= 2;
        } else {
            p--;
            res *= a;
            res %= MOD;
        }
    }
    return res;
}


int main() {
    cin.tie(0);
    iostream::sync_with_stdio(false);

    ll n, q, t, i;
    cin >> n >> q;
    vector<ll> a(n);
    for (int i = 0; i < n; i++) {
        cin >> a[i];
    }

    map<vector<ll>, ll> answers;
    for (int mask = 0; mask < (1 << 6); mask++) {
        vector<ll> c;
        if ((mask & (mask >> 3)) != (mask >> 3)) continue;
        for (int i = 0; i < 3; i++) {
            if ((1 << i) & mask) c.push_back(i + 1);
        }
        for (int i = 0; i < 3; i++) {
            if ((1 << (i + 3)) & mask) c.push_back(i + 1);
        }
        sort(c.begin(), c.end());
        if (c.size() > 3) continue;
        do {
            auto b = a;
            for (auto t : c) {
                if (t == 1) b = rev(b);
                if (t == 2) b = res(b);
                if (t == 3) b = inv(b);
            }

            ll ans = 0;
            for (int i = 1; i <= n; i++) {
                ans += binpow(b[i - 1], i);
                ans %= MOD;
            }
            answers[c] = ans;
        } while (next_permutation(c.begin(), c.end()));
    }

    vector<ll> order;
    int cnt3 = 0;
    while (q--) {
        cin >> t;

        if (t == 3) {
            if (order.empty()) {
                order.push_back(3);
                cnt3++;
            } else if (order.back() == 3) {
                order.pop_back();
                cnt3--;
            } else if (order.size() == 3) {
                order.clear();
                cnt3 = 0;
            } else {
                order.push_back(3);
                cnt3++;
            }
        } else {
            order.push_back(t);

            while (order.size() >= 2 && order.back() == order[order.size() - 2]) {
                order.pop_back();
                order.pop_back();
            }

            if (order.size() == 4) {
                if (cnt3 == 2) {
                    if (order[order.size() - 2] == 3 && order[order.size() - 3] != order.back()) {
                        order.clear();
                        cnt3 = 0;
                    }
                } else if (cnt3 == 1) {
                    if (order[0] == 3) {
                        if (order[1] == order[3]) {
                            order.pop_back();
                        }
                    } else if (order[1] == 3) {
                        if (order[0] == order[3]) {
                            order = {order[2], 3};
                        } else {
                            order = {order[3], 3};
                        }
                    } else {
                        if (order[0] == order[3]) {
                            order = {3, order[1]};
                        } else {
                            order = {3, order[0]};
                        }
                    }
                } else {
                    sort(order.begin(), order.end());
                    order.resize(unique(order.begin(), order.end()) - order.begin());
                }
            }
        }

        cout << answers[order] << ' ';
    }
}
