RT,WA27
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define int ll
const int N = 200010;
const ll mod = 998244353;
int n, m;
ll a[200010], b[200010];
struct Node {
ll sumA, sumB;
ll C;
ll addA, addB;
} tr[N << 2];
void pushup(int u) {
tr[u].sumA = (tr[u << 1].sumA + tr[u << 1 | 1].sumA) % mod;
tr[u].sumB = (tr[u << 1].sumB + tr[u << 1 | 1].sumB) % mod;
tr[u].C = (tr[u << 1].C + tr[u << 1 | 1].C) % mod;
}
void pushdown(int u, int l, int r) {
int mid = (l + r) >> 1;
tr[u << 1].addA += tr[u].addA;
tr[u << 1].addA %= mod;
tr[u << 1 | 1].addA += tr[u].addA;
tr[u << 1 | 1].addA %= mod;
tr[u << 1].addB += tr[u].addB;
tr[u << 1].addB %= mod;
tr[u << 1 | 1].addB += tr[u].addB;
tr[u << 1 | 1].addB %= mod;
tr[u << 1].sumA += (tr[u].addA) * (l - mid + 1) % mod;
tr[u << 1].sumA %= mod;
tr[u << 1 | 1].sumA += (tr[u].addA) * (r - mid) % mod;
tr[u << 1 | 1].sumA %= mod;
tr[u << 1].C += (tr[u].addA) * (tr[u << 1].sumB) % mod;
tr[u << 1].C %= mod;
tr[u << 1 | 1].C += (tr[u].addA) * (tr[u << 1 | 1].sumB) % mod;
tr[u << 1 | 1].C %= mod;
tr[u << 1].sumB += (tr[u].addB) * (l - mid + 1) % mod;
tr[u << 1].sumB %= mod;
tr[u << 1 | 1].sumB += (tr[u].addB) * (r - mid) % mod;
tr[u << 1 | 1].sumB %= mod;
tr[u << 1].C += (tr[u].addB) * (tr[u << 1].sumA) % mod;
tr[u << 1].C %= mod;
tr[u << 1 | 1].C += (tr[u].addB) * (tr[u << 1 | 1].sumA) % mod;
tr[u << 1 | 1].C %= mod;
tr[u].addA = tr[u].addB = 0;
}
void build(int u, int l, int r) {
if (l == r) {
tr[u] = {a[l] % mod, b[l] % mod, (a[l] % mod) * (b[l] % mod) % mod, 0, 0};
return;
}
int mid = (l + r) >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
void modify(int u, int l, int r, int ql, int qr, ll AA, ll AB) {
if (l >= ql && r <= qr) {
tr[u].addA += AA;
tr[u].addA %= mod;
tr[u].addB += AB;
tr[u].addB %= mod;
tr[u].sumA += AA * (r - l + 1) % mod;
tr[u].sumA %= mod;
tr[u].C += AA * (tr[u].sumB) % mod;
tr[u].C %= mod;
tr[u].sumB += AB * (r - l + 1) % mod;
tr[u].sumB %= mod;
tr[u].C += AB * (tr[u].sumA) % mod;
tr[u].C %= mod;
return ;
}
pushdown(u, l, r);
int mid = (l + r) >> 1;
if (ql <= mid) modify(u << 1, l, mid, ql, qr, AA, AB);
if (qr > mid) modify(u << 1 | 1, mid + 1, r, ql, qr, AA, AB);
pushup(u);
// cout << l << ' ' << r << ' ' << tr[u].C << ' ' << tr[u << 1].C << ' ' << tr[u << 1 | 1].C << ' ' << l << ' ' << mid << ' ' << mid + 1 << ' ' << r << endl;
}
ll query(int u, int l, int r, int ql, int qr, bool flag = false) {
if (l >= ql && r <= qr) {
return tr[u].C;
}
ll res = 0;
int mid = (l + r) >> 1;
pushdown(u, l, r);
if (ql <= mid) res += query(u << 1, l, mid, ql, qr, flag), res %= mod;
if (qr > mid) res += query(u << 1 | 1, mid + 1, r, ql, qr, flag), res %= mod;
return res;
}
signed main() {
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; ++i) scanf("%lld", &a[i]);
for (int j = 1; j <= n; ++j) scanf("%lld", &b[j]);
build(1, 1, n);
for (int i = 1; i <= m; ++i) {
int opt, l, r, x; scanf("%lld%lld%lld", &opt, &l, &r);
if (opt == 1) {
scanf("%lld", &x);
modify(1, 1, n, l, r, x, 0);
} else if (opt == 2) {
scanf("%lld", &x);
modify(1, 1, n, l, r, 0, x);
} else printf("%lld\n", query(1, 1, n, l, r, true));
for (int j = 1; j <= n; ++j) {
printf("%lld ", query(1, 1, n, j, j));
}
puts("");
}
return 0;
}