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

// #define int long long
// #pragma GCC optimize("O3, unroll-loops")
// #pragma GCC target("avx2")

// using namespace __gnu_pbds;
using ll = long long;
using namespace std;

// template<class T> using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// template<class T> using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;

const int MOD = 998244353;

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

void solve() {
    int n, q, cnt = 0;
    cin >> n >> q;
    map<vector<int>, int> mp;
    vector<int> p(n);
    for (int i = 0; i < n; i++) {
        cin >> p[i];
    }
    for (int i = 0; i < q; i++) {
        int t;
        cin >> t;
        if (t == 1) {
            reverse(p.begin(), p.end());
        } else if (t == 2) {
            vector<int> q(n);
            for (int j = 0; j < n; j++) {
                q[j] = n - p[j] + 1;
            }
            p = q;
        } else {
            vector<int> q(n);
            for (int j = 0; j < n; j++) {
                q[p[j] - 1] = j + 1;
            }
            p = q;
        }
        if (mp.find(p) == mp.end()) {
            int ans = 0;
            for (int i = 0; i < n; i++) {
                ans += binpow(p[i], i + 1);
                ans %= MOD;
            }
            cout << ans << " ";
            mp[p] = ans;
            cnt++;
        } else {
            cout << mp[p] << " ";
        }
    }
    cout << "\n";
}

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