#include <bits/stdc++.h>
using namespace std;
int n, Q;
const int md = 998244353;
const int maxn = 200010;
int t[4 * maxn], tmul[4 * maxn], tadd[4 * maxn];
inline int mod(long long x) { return (x % md + md) % md; }
void build(int v, int vl, int vr) {
  tmul[v] = 1, tadd[v] = 0;
  if (vl == vr) return;
  int vm = (vl + vr) >> 1;
  build(2 * v, vl, vm);
  build(2 * v + 1, vm + 1, vr);
}
void push(int v, int vl, int vr) {
  t[v] = mod(mod(1ll * tmul[v] * t[v]) + mod(1ll * tadd[v] * (vr - vl + 1)));
  if (vl != vr) {
    tmul[2 * v] = mod(1ll * tmul[2 * v] * tmul[v]);
    tmul[2 * v + 1] = mod(1ll * tmul[2 * v + 1] * tmul[v]);
    tadd[2 * v] = mod(1ll * tadd[2 * v] * tmul[v] + tadd[v]);
    tadd[2 * v + 1] = mod(1ll * tadd[2 * v + 1] * tmul[v] + tadd[v]);
  }
  tmul[v] = 1;
  tadd[v] = 0;
}
void update(int v, int vl, int vr, int l, int r, int m, int a) {
  push(v, vl, vr);
  if (l > vr || r < vl) return;
  if (l <= vl && vr <= r) {
    tmul[v] = m;
    tadd[v] = a;
    push(v, vl, vr);
    return;
  }
  int vm = (vl + vr) >> 1;
  update(2 * v, vl, vm, l, r, m, a);
  update(2 * v + 1, vm + 1, vr, l, r, m, a);
  t[v] = (t[2 * v] + t[2 * v + 1]) % md;
}
int getsum(int v, int vl, int vr, int l, int r) {
  push(v, vl, vr);
  if (l > vr || r < vl) return 0;
  if (l <= vl && vr <= r) return t[v];
  int vm = (vl + vr) >> 1;
  return mod(getsum(2 * v, vl, vm, l, r) + getsum(2 * v + 1, vm + 1, vr, l, r));
}
set<pair<int, int>> q[maxn];
int main() {
  ios_base::sync_with_stdio(false);
  cin >> n >> Q;
  build(1, 0, n - 1);
  for (int i = 0; i < Q; i++) {
    int t, l, r;
    cin >> t >> l >> r;
    --l, --r;
    if (t == 1) {
      int x;
      cin >> x;
      auto itl = q[x].lower_bound({l + 1, 0});
      if (itl != q[x].begin()) {
        --itl;
        if (itl->second >= l) {
          int ll = itl->first, rr = itl->second;
          q[x].erase(itl);
          if (ll <= l - 1) q[x].insert({ll, l - 1});
          q[x].insert({l, rr});
        }
      }
      auto itr = q[x].lower_bound({r + 1, 0});
      if (itr != q[x].begin()) {
        --itr;
        if (itr->second >= r) {
          int ll = itr->first, rr = itr->second;
          q[x].erase(itr);
          if (r + 1 <= rr) q[x].insert({r + 1, rr});
          q[x].insert({ll, r});
        }
      }
      int prev = l;
      while (true) {
        auto it = q[x].lower_bound({l, 0});
        if (it == q[x].end() || it->first > r) break;
        int ll = it->first, rr = it->second;
        q[x].erase(it);
        if (prev <= ll - 1) update(1, 0, n - 1, prev, ll - 1, 1, 1);
        update(1, 0, n - 1, ll, rr, 2, 0);
        prev = rr + 1;
      }
      if (prev <= r) update(1, 0, n - 1, prev, r, 1, 1);
      q[x].insert({l, r});
    } else {
      cout << getsum(1, 0, n - 1, l, r) << '\n';
    }
  }
}
