#include <bits/stdc++.h>
using namespace std;
int PREP = (cin.tie(nullptr), ios::sync_with_stdio(false), cout << fixed << setprecision(12), 0);
//int SEGV = getenv("D") || (exit(system("D= SEGFAULT_SIGNALS=all catchsegv ./prog.exe") >> 8), 0);
using Int = long long;
const Int MOD = 998244353;
struct SegTree {
    int N;
    vector<Int> A, B, C;
    SegTree(int n) {
        N = 1; while (N < n) N *= 2;
        A.resize(2 * N);
        B.resize(2 * N, 1);
        C.resize(2 * N);
    }
    void build(const vector<Int> &ary) {
        fill(begin(A), end(A), 0);
        fill(begin(B), end(B), 1);
        fill(begin(C), end(C), 0);
        for (int i = 0; i < ary.size(); i++) {
            A[N + i] = ary[i];
        }
        for (int i = N - 1; i > 0; i--) {
            A[i] = (A[2*i+0] + A[2*i+1]) % MOD;
        }
    }
    Int sum_0(int L, int R, int node, int nodeL, int nodeR) {
        if (R <= nodeL || nodeR <= L) return 0;
        if (L <= nodeL && nodeR <= R) return A[node];
        A[2*node+0] = (B[node] * A[2*node+0] + C[node] * (nodeR - nodeL) / 2) % MOD;
        A[2*node+1] = (B[node] * A[2*node+1] + C[node] * (nodeR - nodeL) / 2) % MOD;
        B[2*node+0] = B[node] * B[2*node+0] % MOD;
        B[2*node+1] = B[node] * B[2*node+1] % MOD;
        C[2*node+0] = (B[node] * C[2*node+0] + C[node]) % MOD;
        C[2*node+1] = (B[node] * C[2*node+1] + C[node]) % MOD;
        B[node] = 1, C[node] = 0;
        Int ans = 0;
        ans += sum_0(L, R, 2*node+0, nodeL, (nodeL + nodeR) / 2);
        ans += sum_0(L, R, 2*node+1, (nodeL + nodeR) / 2, nodeR);
        return ans % MOD;
    }
    Int sum(int L, int R) {
        return sum_0(L, R, 1, 0, N);
    }
    void modify_0(int L, int R, int b, int c, int node, int nodeL, int nodeR) {
        if (R <= nodeL || nodeR <= L) return;
        if (L <= nodeL && nodeR <= R) {
            A[node] = (b * A[node] + (Int)c * (nodeR - nodeL)) % MOD;
            B[node] = b * B[node] % MOD;
            C[node] = (b * C[node] + c) % MOD;
            return;
        }
        A[2*node+0] = (B[node] * A[2*node+0] + C[node] * (nodeR - nodeL) / 2) % MOD;
        A[2*node+1] = (B[node] * A[2*node+1] + C[node] * (nodeR - nodeL) / 2) % MOD;
        B[2*node+0] = B[node] * B[2*node+0] % MOD;
        B[2*node+1] = B[node] * B[2*node+1] % MOD;
        C[2*node+0] = (B[node] * C[2*node+0] + C[node]) % MOD;
        C[2*node+1] = (B[node] * C[2*node+1] + C[node]) % MOD;
        B[node] = 1, C[node] = 0;
        modify_0(L, R, b, c, 2*node+0, nodeL, (nodeL + nodeR) / 2);
        modify_0(L, R, b, c, 2*node+1, (nodeL + nodeR) / 2, nodeR);
        A[node] = (A[2*node+0] + A[2*node+1]) % MOD;
    }
    void modify(int L, int R, int b, int c) {
        modify_0(L, R, b, c, 1, 0, N);
    }
};
int main() {
    int N, Q; cin >> N >> Q;
    vector<Int> A(N); for (auto &a : A) cin >> a;
    SegTree st(N);
    st.build(A);
    for (int i = 0; i < Q; i++) {
        int type; cin >> type;
        if (type == 0) {
            int l, r, b, c; cin >> l >> r >> b >> c;
            st.modify(l, r, b, c);
        } else {
            int l, r; cin >> l >> r;
            cout << st.sum(l, r) << '\n';
        }
    }
    return 0;
}


Measured memory_bytes: 31608