#include <bits/stdc++.h>
using namespace std;
const long double eps = 1e-13;
const long double PI = acos(-1);
const int INF = (int)1e9;
const long long INFF = (long long)1e18;
const int mod = 998244353;
const int MXN = (int)2e5 + 7;
inline void add(int &v1, int v2) {
  v1 += v2;
  if (v1 >= mod) v1 -= mod;
}
inline void mul(int &v1, int v2 = 2) { v1 = (v1 * 1LL * v2) % mod; }
struct Seg {
  int ll[MXN << 2], rr[MXN << 2];
  int v1[MXN << 2], v2[MXN << 2], v[MXN << 2];
  inline void pushup(int p) {
    v[p] = (v[p << 1] + v[p << 1 | 1]);
    if (v[p] >= mod) v[p] -= mod;
  }
  inline void pushdown(int p) {
    if (v2[p] != 1) {
      mul(v[p << 1], v2[p]);
      mul(v1[p << 1], v2[p]);
      mul(v2[p << 1], v2[p]);
      mul(v[p << 1 | 1], v2[p]);
      mul(v1[p << 1 | 1], v2[p]);
      mul(v2[p << 1 | 1], v2[p]);
      v2[p] = 1;
    }
    if (v1[p]) {
      add(v[p << 1], v1[p] * 1LL * (rr[p << 1] - ll[p << 1] + 1) % mod);
      add(v1[p << 1], v1[p]);
      add(v[p << 1 | 1],
          v1[p] * 1LL * (rr[p << 1 | 1] - ll[p << 1 | 1] + 1) % mod);
      add(v1[p << 1 | 1], v1[p]);
      v1[p] = 0;
    }
  }
  void bd(int l, int r, int p) {
    ll[p] = l, rr[p] = r;
    v2[p] = 1;
    if (l == r) return;
    int mid = (l + r) >> 1;
    bd(l, mid, p << 1);
    bd(mid + 1, r, p << 1 | 1);
  }
  void md1(int l, int r, int p) {
    if (l > r) return;
    if (ll[p] == l && rr[p] == r) {
      add(v[p], r - l + 1);
      add(v1[p], 1);
      return;
    }
    pushdown(p);
    int mid = (ll[p] + rr[p]) >> 1;
    if (r <= mid)
      md1(l, r, p << 1);
    else if (l > mid)
      md1(l, r, p << 1 | 1);
    else {
      md1(l, mid, p << 1);
      md1(mid + 1, r, p << 1 | 1);
    }
    pushup(p);
  }
  void md2(int l, int r, int p) {
    if (l > r) return;
    if (ll[p] == l && rr[p] == r) {
      mul(v[p]);
      mul(v2[p]);
      mul(v1[p]);
      return;
    }
    pushdown(p);
    int mid = (ll[p] + rr[p]) >> 1;
    if (r <= mid)
      md2(l, r, p << 1);
    else if (l > mid)
      md2(l, r, p << 1 | 1);
    else {
      md2(l, mid, p << 1);
      md2(mid + 1, r, p << 1 | 1);
    }
    pushup(p);
  }
  int qy(int l, int r, int p) {
    if (ll[p] == l && rr[p] == r) return v[p];
    int mid = (ll[p] + rr[p]) >> 1;
    pushdown(p);
    if (r <= mid)
      return qy(l, r, p << 1);
    else if (l > mid)
      return qy(l, r, p << 1 | 1);
    else
      return (qy(l, mid, p << 1) + qy(mid + 1, r, p << 1 | 1)) % mod;
  }
} seg;
set<pair<int, int> > st[MXN];
int main(void) {
  int n, q;
  scanf("%d %d", &n, &q);
  seg.bd(1, n, 1);
  while (q--) {
    int typ;
    scanf("%d", &typ);
    if (typ == 1) {
      int l, r, x;
      scanf("%d %d %d", &l, &r, &x);
      auto it = st[x].upper_bound(make_pair(l, l - 1));
      int nl = l, nr = r;
      if (it != st[x].begin()) {
        auto it2 = it;
        it2--;
        if (it2->second >= r) {
          seg.md2(l, r, 1);
          continue;
        } else if (it2->second >= l) {
          seg.md2(l, it2->second, 1);
          l = it2->second + 1;
          nl = it2->first;
          st[x].erase(it2);
        } else if (it2->second == l - 1) {
          nl = it2->first;
          st[x].erase(it2);
        }
      }
      it = st[x].upper_bound(make_pair(l, l - 1));
      while (it != st[x].end()) {
        if (it->first > r) {
          if (it->first == r + 1) {
            nr = it->second;
            st[x].erase(it);
          }
          break;
        } else if (it->second <= r) {
          seg.md1(l, it->first - 1, 1);
          seg.md2(it->first, it->second, 1);
          l = it->second + 1;
          st[x].erase(it);
          it = st[x].upper_bound(make_pair(l, l - 1));
        } else {
          seg.md1(l, it->first - 1, 1);
          seg.md2(it->first, r, 1);
          l = r = -1;
          nr = it->second;
          st[x].erase(it);
          break;
        }
      }
      st[x].insert(make_pair(nl, nr));
      if (l != -1) seg.md1(l, r, 1);
    } else {
      int l, r;
      scanf("%d %d", &l, &r);
      int ans = seg.qy(l, r, 1);
      printf("%d\n", ans);
    }
  }
  return 0;
}
