#include <bits/stdc++.h>   using namespace std;   const int mod = 998244353;   const int MN = 200010;   int N, Q;   struct BIT {     vector<int> tree;     vector<pair<int, int> > lazy;     void init() {       tree = vector<int>(4 * N, 0);       lazy = vector<pair<int, int> >(4 * N, {1, 0});     }     void prop(int l, int r, int n) {       if (l != r) {         int m = (l + r) >> 1;         tree[2 * n] = (1LL * tree[2 * n] * lazy[n].first +                        1LL * (m - l + 1) * lazy[n].second) %                       mod;         lazy[2 * n].first = 1LL * lazy[2 * n].first * lazy[n].first % mod;         lazy[2 * n].second =             (1LL * lazy[2 * n].second * lazy[n].first + lazy[n].second) % mod;         tree[2 * n + 1] = (1LL * tree[2 * n + 1] * lazy[n].first +                            1LL * (r - m) * lazy[n].second) %                           mod;         lazy[2 * n + 1].first = 1LL * lazy[2 * n + 1].first * lazy[n].first % mod;         lazy[2 * n + 1].second =             (1LL * lazy[2 * n + 1].second * lazy[n].first + lazy[n].second) % mod;         lazy[n] = {1, 0};       }     }     void upd(int a, int b, pair<int, int> val, int l, int r, int n) {       if (b < l || r < a) return;       if (a <= l && r <= b) {         tree[n] =             (1LL * tree[n] * val.first + 1LL * (r - l + 1) * val.second) % mod;         lazy[n].first = 1LL * lazy[n].first * val.first % mod;         lazy[n].second = (1LL * lazy[n].second * val.first + val.second) % mod;         return;       }       prop(l, r, n);       int m = (l + r) >> 1;       upd(a, b, val, l, m, 2 * n);       upd(a, b, val, m + 1, r, 2 * n + 1);       tree[n] = (tree[2 * n] + tree[2 * n + 1]) % mod;     }     int quer(int a, int b, int l, int r, int n) {       if (b < l || r < a) return 0;       if (a <= l && r <= b) return tree[n];       prop(l, r, n);       int m = (l + r) >> 1;       int L = quer(a, b, l, m, 2 * n);       int R = quer(a, b, m + 1, r, 2 * n + 1);       return (L + R) % mod;     }   } bit;   set<pair<int, int> > st[MN];   void add(int x, int l, int r) {     set<pair<int, int> >::iterator it = st[x].lower_bound({l, -1});     int pre = l - 1;     if (it != st[x].begin()) {       --it;       if (it->second >= l) {         bit.upd(l, min(r, it->second), {2, 0}, 0, N - 1, 1);         l = it->first;         if (it->second >= r) return;         pre = it->second;         st[x].erase(it);       }     }     while (1) {       it = st[x].lower_bound({l, -1});       if (it == st[x].end()) break;       if (it->first > r) break;       bit.upd(it->first, min(it->second, r), {2, 0}, 0, N - 1, 1);       bit.upd(pre + 1, it->first - 1, {1, 1}, 0, N - 1, 1);       pre = it->second;       r = max(r, it->second);       st[x].erase(it);     }     bit.upd(pre + 1, r, {1, 1}, 0, N - 1, 1);     st[x].insert({l, r});   }   int main() {     scanf( %d %d , &N, &Q);     bit.init();     for (int i = 0; i < Q; i++) {       int t;       scanf( %d , &t);       if (t == 1) {         int l, r, x;         scanf( %d %d %d , &l, &r, &x);         l--;         r--;         add(x, l, r);       } else {         int l, r;         scanf( %d %d , &l, &r);         l--;         r--;         printf( %d n , bit.quer(l, r, 0, N - 1, 1));       }     }   }