#ifndef LOCAL
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<vector>
#pragma GCC optimize("avx2")
#endif

#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

using i128 = __int128;
using ll = long long;
using ld = long double;

template<typename T>
using orderet_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

template<typename T, typename V>
using table = gp_hash_table<T, V>;

const int MOD = 998244353;

#define int ll
int binpow(int a, int n) {
    int res = 1;
    while (n) {
        if (n & 1) res = (res * a) % MOD;
        a = (a * a) % MOD;
        n /= 2;
    }
    return res;
}

void solve() {
    int n, q;
    cin >> n >> q;
    vector<int> v(n + 1);
    for (int i = 1; i <= n; ++i) cin >> v[i];
    map<vector<int>, int> mp;
    mp[v]++;
    while (q--) {
        int x;
        cin >> x;
        vector<int> a(n + 1);
        for (int i = 1; i <= n; ++i) {
            if (x == 1) a[i] = v[n - i + 1];
            if (x == 2) a[i] = n - v[i] + 1;
            if (x == 3) a[v[i]] = i;
        }
        v = a;
        mp[v]++;
        int cost = 0;
        for (int i = 1; i <= n; ++i) cost = (cost + binpow(v[i], i)) % MOD;
        cout << cost << " ";
    }
    if (mp.size() > 20) exit(-1);
}

signed main() {
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif
    int t = 1;
    //cin>>t;
    while (t--) solve();
}
