#include <iostream>
#include <cassert>
#include <queue>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <ctime>
#include <map>
#include <set>
using namespace std;
#define int long long
#define pii pair<int, int>
#define lowbit(x) (x & (-x))
#define eb emplace_back
#define F first
#define S second
#define test(x) cout << "Test: " << x << '\n'
#define debug puts("qwq");
#define open(x) freopen(#x".in", "r", stdin);freopen(#x".out", "w", stdout);
#define close fclose(stdin);fclose(stdout);
namespace FastIO {
template <typename T = int>
inline T read() {
T s = 0, w = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-') w = -1;
c = getchar();
}
while (isdigit(c)) s = (s << 1) + (s << 3) + (c ^ 48), c = getchar();
return s * w;
}
template <typename T>
inline void read(T &s) {
s = 0;
int w = 1;
char c = getchar();
while (!isdigit(c)) {
if (c == '-') w = -1;
c = getchar();
}
while (isdigit(c)) s = (s << 1) + (s << 3) + (c ^ 48), c = getchar();
s = s * w;
}
template <typename T, typename... Arp> inline void read(T &x, Arp &...arp) {
read(x), read(arp...);
}
template <typename T>
inline void write(T x, char ch) {
if (x < 0) x = -x, putchar('-');
static char stk[25];
int top = 0;
do {
stk[top++] = x % 10 + '0', x /= 10;
} while (x);
while (top) putchar(stk[--top]);
putchar(ch);
return;
}
template <typename T>
inline void smax(T &x, T y) {
if (x < y) x = y;
}
template <typename T>
inline void smin(T &x, T y) {
if (x > y) x = y;
}
void quit() {
exit(0);
}
} using namespace FastIO;
const int N = 2e5 + 19, sq = 500, mod = 998244353;
int a[N], b[N], n, m, taga[N], tagb[N], suma[N], sumb[N], L[N], ans[N], id[N];
void add(int &x, int y) { (x += y) %= mod; }
void rebuild(int id) {
ans[id] = suma[id] = sumb[id] = 0;
for (int i = L[id]; i < L[id + 1]; ++i) {
add(a[i], taga[id]);
add(b[i], tagb[id]);
add(suma[id], a[i]);
add(sumb[id], b[i]);
add(ans[id], a[i] * b[i] % mod);
}
taga[id] = tagb[id] = 0;
}
void AddA(int l, int r, int x) {
int P = id[l - 1] + 1, Q = id[r + 1] - 1;
for (int i = P; i <= Q; ++i) {
add(taga[i], x);
add(ans[i], x * sumb[i] % mod);
add(suma[i], (L[i+1] - L[i]) * x % mod);
}
if (id[l] < P) {
for (int i = l; i < L[P]; ++i) {
add(a[i], x);
}
rebuild(id[l]);
}
if (id[r] > Q) {
for (int i = L[Q + 1]; i <= r; ++i) {
add(a[i], x);
}
rebuild(id[r]);
}
}
void AddB(int l, int r, int x) {
int P = id[l - 1] + 1, Q = id[r + 1] - 1;
for (int i = P; i <= Q; ++i) {
add(tagb[i], x);
add(ans[i], x * suma[i] % mod);
add(sumb[i], (L[i+1] - L[i]) * x % mod);
}
if (id[l] < P) {
for (int i = l; i < L[P]; ++i) {
add(b[i], x);
}
rebuild(id[l]);
}
if (id[r] > Q) {
for (int i = L[Q + 1]; i <= r; ++i) {
add(b[i], x);
}
rebuild(id[r]);
}
}
int query(int l, int r) {
int P = id[l - 1] + 1, Q = id[r + 1] - 1, res = 0;
for (int i = P; i <= Q; ++i) add(res, ans[i]);
if (id[l] < P) {
for (int i = l; i < L[P]; ++i) {
add(res, (a[i] + taga[id[l]]) * (b[i] + tagb[id[l]]) % mod);
}
}
if (id[r] > Q) {
for (int i = L[Q + 1]; i <= r; ++i) {
add(res, (a[i] + taga[id[r]]) * (b[i] + tagb[id[r]]) % mod);
}
} return res;
}
signed main() {
read(n, m);
for (int i = 1; i <= n; ++i) read(a[i]);
for (int i = 1; i <= n; ++i) read(b[i]);
int len = 0;
for (int i = 1; i <= n; ++i) {
if ((i - 1) % sq == 0) ++len;
id[i] = len;
}
L[1] = 1;
for (int i = 2; i <= len; ++i) L[i] = sq;
for (int i = 1; i <= len; ++i) {
L[i] += L[i-1];
}
L[len + 1] = n + 1; id[n + 1] = len + 1;
for (int i = 1; i <= len; ++i) rebuild(i);
while (m--) {
int op, l, r;
read(op, l, r);
if (op == 3) write(query(l, r), '\n');
else {
if (op == 1) AddA(l, r, read());
else AddB(l, r, read());
}
}
return 0;
}