#include <bits/stdc++.h>
using namespace std;

using ll = long long;

static const ll NEG = -(1LL << 60);
static const int MOD = 998244353;
static const int s = 6; // 3 regex states * 2 bits prev-selected

struct cell {
    ll val;
    int cnt;
};

struct mat {
    cell a[s][s];
};

int n, q;
vector<ll> a;
vector<int> col;

int id(int r, int p) {
    return r * 2 + p;
}

int go[3][3];

cell make_cell(ll v = NEG, int c = 0) {
    return {v, c};
}

void relax(cell &x, ll v, int c) {
    if (c == 0) return;
    if (v > x.val) {
        x.val = v;
        x.cnt = c;
    } else if (v == x.val) {
        x.cnt += c;
        if (x.cnt >= MOD) x.cnt -= MOD;
    }
}

mat identity_mat() {
    mat m;
    for (int i = 0; i < s; ++i) {
        for (int j = 0; j < s; ++j) m.a[i][j] = make_cell();
        m.a[i][i] = {0, 1};
    }
    return m;
}

mat leaf_mat(ll val, int c) {
    mat m;
    for (int i = 0; i < s; ++i) {
        for (int j = 0; j < s; ++j) m.a[i][j] = make_cell();
    }

    for (int r = 0; r < 3; ++r) {
        for (int p = 0; p < 2; ++p) {
            int from = id(r, p);

            // skip current position
            int to_skip = id(r, 0);
            relax(m.a[from][to_skip], 0, 1);

            // take current position
            if (p == 0) {
                int nr = go[r][c];
                if (nr != -1) {
                    int to_take = id(nr, 1);
                    relax(m.a[from][to_take], val, 1);
                }
            }
        }
    }
    return m;
}

mat merge_mat(const mat &l, const mat &r) {
    mat res;
    for (int i = 0; i < s; ++i) {
        for (int j = 0; j < s; ++j) res.a[i][j] = make_cell();
    }

    for (int i = 0; i < s; ++i) {
        for (int k = 0; k < s; ++k) {
            if (l.a[i][k].cnt == 0) continue;
            for (int j = 0; j < s; ++j) {
                if (r.a[k][j].cnt == 0) continue;
                ll nv = l.a[i][k].val + r.a[k][j].val;
                int nc = int((1LL * l.a[i][k].cnt * r.a[k][j].cnt) % MOD);
                relax(res.a[i][j], nv, nc);
            }
        }
    }

    return res;
}

struct segtree {
    int sz;
    vector<mat> st;

    segtree() {}
    segtree(int n) { init(n); }

    void init(int n) {
        sz = 1;
        while (sz < n) sz <<= 1;
        st.assign(sz << 1, identity_mat());
    }

    void build(const vector<ll> &arr, const vector<int> &c) {
        int n = (int)arr.size() - 1;
        for (int i = 0; i < n; ++i) st[sz + i] = leaf_mat(arr[i + 1], c[i + 1]);
        for (int i = sz - 1; i >= 1; --i) st[i] = merge_mat(st[i << 1], st[i << 1 | 1]);
    }

    void update_val(int pos, ll val, int c) {
        int p = sz + pos - 1;
        st[p] = leaf_mat(val, c);
        for (p >>= 1; p; p >>= 1) st[p] = merge_mat(st[p << 1], st[p << 1 | 1]);
    }

    void update_col(int pos, ll val, int c) {
        update_val(pos, val, c);
    }

    pair<ll, int> answer() const {
        int start = id(0, 0);
        ll best = NEG;
        int ways = 0;
        for (int t = 0; t < s; ++t) {
            const cell &x = st[1].a[start][t];
            if (x.cnt == 0) continue;
            if (x.val > best) {
                best = x.val;
                ways = x.cnt;
            } else if (x.val == best) {
                ways += x.cnt;
                if (ways >= MOD) ways -= MOD;
            }
        }
        return {best, ways};
    }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    go[0][0] = 0;
    go[0][1] = 1;
    go[0][2] = -1;
    go[1][0] = 2;
    go[1][1] = 1;
    go[1][2] = -1;
    go[2][0] = 2;
    go[2][1] = -1;
    go[2][2] = -1;

    cin >> n >> q;
    a.assign(n + 1, 0);
    col.assign(n + 1, 0);

    for (int i = 1; i <= n; ++i) cin >> a[i];
    for (int i = 1; i <= n; ++i) cin >> col[i];

    segtree st(n);
    st.build(a, col);

    while (q--) {
        int tp;
        cin >> tp;
        if (tp == 1) {
            int x;
            ll y;
            cin >> x >> y;
            a[x] = y;
            st.update_val(x, a[x], col[x]);
        } else if (tp == 2) {
            int x, y;
            cin >> x >> y;
            col[x] = y;
            st.update_col(x, a[x], col[x]);
        } else {
            auto [mx, ways] = st.answer();
            cout << mx << ' ' << ways << '\n';
        }
    }

    return 0;
}