#include <vector>
#include <queue>
#include <algorithm>
#include <set>
#include <unordered_map>
#include <map>
#include <unordered_set>
#include <bitset>
#include <cmath>
#include <cstring> 
#include <iostream>
#include <string>
#pragma ivdep
#pragma GCC target("avx2")

typedef long long ll;
using namespace std;
typedef pair<ll, ll> pi;
//namespace __gnu_pbds{
//  typedef tree<ll, null_type, less<ll>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
//}
//using namespace __gnu_pbds;

const ll maxN = 1e5 + 1, maxA = 1e6, mod = 998244353;

vector <ll> a, b;
ll ans[2][2][2] = {{{0}}};
ll bPow(ll n, ll b) {
    if (b == 0) return 1;
    if (b % 2) return bPow(n, b - 1) * n % mod;
    return bPow(n, b / 2) * bPow(n, b / 2) % mod;
}

ll findans(){
    ll Ans = 0;
    for (ll i = 0; i < b.size(); i++) {
        Ans += bPow(b[i], i + 1);
        Ans %= mod;
    }
    return Ans;
}

void solve(){
    ll n; cin >> n;
    ll q; cin >> q;
    a.resize(n);
    for (ll i  =0 ; i < n; i++) cin >> a[i];
    for (ll mask = 0; mask < 8; mask++) {
        bitset<3> bt(mask);
        b = a;
        if (bt[2]) {
            for (ll i = 0; i < n; i++) {
                b[a[i] - 1] = i + 1;
            }
        }
        if (bt[0]) {
            reverse(b.begin(), b.end());
        }
        if (bt[1]) {
            for (ll i = 0; i < n; i++) {
                b[i] = n - b[i] + 1;
            }
        }

        ans[bt[0]][bt[1]][bt[2]] = findans();
    }

    vector <bool> qs(3);
    while (q--) {
        ll t; cin >> t;
        if (t == 1) {
            qs[0] = 1 - qs[0];
        }

        else if (t == 2) {
            qs[1] = 1 - qs[1]; 
        }
        else {
            swap(qs[0], qs[1]);
            qs[2] = 1 - qs[2];
        }
        cout << ans[qs[0]][qs[1]][qs[2]] << " ";
    }
    return;
}
signed main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    ll T = 1;
    while (T--) {
        solve();
    }
}