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

using ll = long long;
static const ll NEG = -(1LL << 60);
static const int MOD = 998244353;

struct Cell {
    ll val;
    int cnt;
};

struct Mat {
    Cell a[6][6];
};

int n, q;
vector<ll> a;
vector<int> col;
vector<Mat> st;
int sz;

int go[3][3];

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

inline 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) {
        int nv = x.cnt + c;
        if (nv >= MOD) nv -= MOD;
        x.cnt = nv;
    }
}

Mat identity_mat() {
    Mat m;
    for (int i = 0; i < 6; ++i) {
        for (int j = 0; j < 6; ++j) {
            m.a[i][j] = {NEG, 0};
        }
        m.a[i][i] = {0, 1};
    }
    return m;
}

Mat leaf_mat(ll val, int c) {
    Mat m;
    for (int i = 0; i < 6; ++i)
        for (int j = 0; j < 6; ++j)
            m.a[i][j] = {NEG, 0};

    for (int s = 0; s < 6; ++s) {
        int r = s / 2;
        int b = s % 2;

        // skip current position
        relax(m.a[s][id(r, 0)], 0, 1);

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

Mat merge_mat(const Mat &L, const Mat &R) {
    Mat res;
    for (int i = 0; i < 6; ++i)
        for (int j = 0; j < 6; ++j)
            res.a[i][j] = {NEG, 0};

    for (int i = 0; i < 6; ++i) {
        for (int k = 0; k < 6; ++k) {
            if (L.a[i][k].cnt == 0) continue;
            ll lv = L.a[i][k].val;
            int lc = L.a[i][k].cnt;
            for (int j = 0; j < 6; ++j) {
                if (R.a[k][j].cnt == 0) continue;
                ll nv = lv + R.a[k][j].val;
                int nc = int((1LL * lc * R.a[k][j].cnt) % MOD);
                relax(res.a[i][j], nv, nc);
            }
        }
    }
    return res;
}

void build() {
    for (int i = sz - 1; i >= 1; --i) {
        st[i] = merge_mat(st[i << 1], st[i << 1 | 1]);
    }
}

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

pair<ll, int> get_answer() {
    const Cell &base = st[1].a[id(0, 0)][0];
    ll best = NEG;
    int ways = 0;
    for (int j = 0; j < 6; ++j) {
        const Cell &x = st[1].a[id(0, 0)][j];
        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];

    sz = 1;
    while (sz < n) sz <<= 1;
    st.assign(sz << 1, identity_mat());

    for (int i = 1; i <= n; ++i) {
        st[sz + i - 1] = leaf_mat(a[i], col[i]);
    }
    for (int i = n + 1; i <= sz; ++i) {
        st[sz + i - 1] = identity_mat();
    }
    build();

    while (q--) {
        int type;
        cin >> type;
        if (type == 1) {
            int x;
            ll y;
            cin >> x >> y;
            a[x] = y;
            update(x, a[x], col[x]);
        } else if (type == 2) {
            int x, y;
            cin >> x >> y;
            col[x] = y;
            update(x, a[x], col[x]);
        } else {
            auto [mx, ways] = get_answer();
            cout << mx << ' ' << ways << '\n';
        }
    }

    return 0;
}