#include <bits/stdc++.h>   using namespace std;   const int MOD = 998244353;   int add_MOD(int a, int b) {     a += b;     if (a >= MOD) {       return a - MOD;     }     if (a < 0) {       return a + MOD;     }     return a;   }   int mul_MOD(int a, int b) { return a * (long long)b % MOD; }   const int N = (int)2e5 + 7;   int n;   int q;   int brute[N];   vector<vector<int>> queries;   vector<pair<int, int>> segments[N];   vector<bool> is[N];   vector<int> urm[N];   map<int, int> who_l[N];   map<int, int> who_r[N];   map<int, int> id[N];   set<int> changes[N];   struct T {     int a;     int b;     int val;   };   T segt[4 * N];   void push(int v, int tl, int tr) {     segt[v].val =         add_MOD(mul_MOD(tr - tl + 1, segt[v].b), mul_MOD(segt[v].val, segt[v].a));     if (tl < tr) {       segt[2 * v].a = mul_MOD(segt[2 * v].a, segt[v].a);       segt[2 * v + 1].a = mul_MOD(segt[2 * v + 1].a, segt[v].a);       segt[2 * v].b = add_MOD(segt[v].b, mul_MOD(segt[2 * v].b, segt[v].a));       segt[2 * v + 1].b =           add_MOD(segt[v].b, mul_MOD(segt[2 * v + 1].b, segt[v].a));     }     segt[v].a = 1;     segt[v].b = 0;   }   void add(int v, int tl, int tr, int l, int r) {     push(v, tl, tr);     if (tr < l || r < tl) {       return;     }     if (l <= tl && tr <= r) {       segt[v].b = 1;       push(v, tl, tr);       return;     }     int tm = (tl + tr) / 2;     add(2 * v, tl, tm, l, r);     add(2 * v + 1, tm + 1, tr, l, r);     segt[v].val = add_MOD(segt[2 * v].val, segt[2 * v + 1].val);   }   void mult(int v, int tl, int tr, int l, int r) {     push(v, tl, tr);     if (tr < l || r < tl) {       return;     }     if (l <= tl && tr <= r) {       segt[v].a = 2;       push(v, tl, tr);       return;     }     int tm = (tl + tr) / 2;     mult(2 * v, tl, tm, l, r);     mult(2 * v + 1, tm + 1, tr, l, r);     segt[v].val = add_MOD(segt[2 * v].val, segt[2 * v + 1].val);   }   int get(int v, int tl, int tr, int l, int r) {     push(v, tl, tr);     if (tr < l || r < tl) {       return 0;     }     if (l <= tl && tr <= r) {       return segt[v].val;     } else {       int tm = (tl + tr) / 2;       return add_MOD(get(2 * v, tl, tm, l, r), get(2 * v + 1, tm + 1, tr, l, r));     }   }   void add_brute(int l, int r) {     add(1, 1, n, l, r);     return;     for (int i = l; i <= r; i++) {       brute[i] = add_MOD(brute[i], 1);     }   }   void mult_brute(int l, int r) {     mult(1, 1, n, l, r);     return;     for (int i = l; i <= r; i++) {       brute[i] = mul_MOD(brute[i], 2);     }   }   int get_brute(int l, int r) {     return get(1, 1, n, l, r);     int sol = 0;     for (int i = l; i <= r; i++) {       sol = add_MOD(sol, brute[i]);     }     return sol;   }   void add(int l, int r, int x) {     int p = who_l[x][l];     int p2 = who_r[x][r];     while (p <= p2) {       if (is[x][p]) {         int until = urm[x][p];         if (until > p2) {           until = p2;         }         mult_brute(segments[x][p].first, segments[x][until].second);         int ant_p = p;         p = urm[x][p] + 1;         urm[x][ant_p] = max(urm[x][ant_p], p2);       } else {         is[x][p] = 1;         add_brute(segments[x][p].first, segments[x][p].second);         urm[x][p] = p2;         p++;       }     }   }   int main() {     ios::sync_with_stdio(0);     cin.tie(0);     for (int i = 0; i < 4 * N; i++) {       segt[i].a = 1;     }     cin >> n >> q;     for (int i = 1; i <= q; i++) {       int t, l, r;       cin >> t >> l >> r;       if (t == 1) {         int x;         cin >> x;         queries.push_back({l, r, x});         changes[x].insert(l);         changes[x].insert(r + 1);       } else {         queries.push_back({l, r});       }     }     for (int x = 1; x <= n; x++) {       changes[x].insert(1);       changes[x].insert(n + 1);       int j = -1;       for (auto &i : changes[x]) {         if (j != -1) {           segments[x].push_back({j, i - 1});         }         j = i;       }       is[x].resize((int)segments[x].size(), 0);       urm[x].resize((int)segments[x].size());       for (int j = 0; j < (int)segments[x].size(); j++) {         who_l[x][segments[x][j].first] = j;         who_r[x][segments[x][j].second] = j;       }     }     for (auto &vec : queries) {       if ((int)vec.size() == 3) {         add(vec[0], vec[1], vec[2]);       } else {         cout << get_brute(vec[0], vec[1]) <<   n ;       }     }   }