#include <bits/stdc++.h>
using namespace std;
const int mod = 998244353;
const int maxn = 2e5 + 5;
template <class T>
inline void In(T &ret) {
  char c;
  ret = 0;
  while ((c = getchar()) < '0' || c > '9')
    ;
  while (c >= '0' && c <= '9') {
    ret = ret * 10 + (c - '0'), c = getchar();
  }
}
int add(int x, int y) {
  if ((x += y) >= mod) x -= mod;
  return x;
}
int mul(int x, int y) {
  long long z = 1LL * x * y;
  return z - z / mod * mod;
}
struct node {
  int s, a, b;
  void update(int x, int y, int z = 0) {
    b = mul(b, y);
    a = add(mul(a, y), x);
    if (z)
      s = add(mul(s, y), z);
    else
      s = add(mul(s, y), x);
  }
  void clear() {
    b = 1;
    a = 0;
  }
} f[maxn << 2];
void push_down(int t, int l, int r) {
  int mid = (l + r) >> 1;
  f[t << 1].update(f[t].a, f[t].b, mul(f[t].a, mid - l + 1));
  f[t << 1 | 1].update(f[t].a, f[t].b, mul(f[t].a, r - mid));
  f[t].clear();
}
void update(int t, int l, int r, int ll, int rr, int a, int b) {
  if (ll <= l && r <= rr) {
    f[t].update(a, b, mul(a, r - l + 1));
    return;
  }
  push_down(t, l, r);
  int mid = (l + r) >> 1;
  if (ll <= mid) update(t << 1, l, mid, ll, rr, a, b);
  if (rr > mid) update(t << 1 | 1, mid + 1, r, ll, rr, a, b);
  f[t].s = add(f[t << 1].s, f[t << 1 | 1].s);
}
int query(int t, int l, int r, int ll, int rr) {
  if (ll <= l && r <= rr) return f[t].s;
  push_down(t, l, r);
  int mid = (l + r) >> 1, res = 0;
  if (ll <= mid) res = add(res, query(t << 1, l, mid, ll, rr));
  if (rr > mid) res = add(res, query(t << 1 | 1, mid + 1, r, ll, rr));
  return res;
}
set<pair<int, int> > g[maxn];
vector<pair<int, int> > u;
int main() {
  int n, q, op, l, r, x, d;
  In(n);
  In(q);
  while (q--) {
    In(op);
    In(l);
    In(r);
    if (op == 1) {
      In(x);
      u.clear();
      auto e = g[x].lower_bound(pair<int, int>(l, 0));
      if (e != g[x].begin()) {
        auto ee = e;
        ee--;
        if ((*ee).second >= l) u.push_back((*ee));
      }
      auto ee = g[x].lower_bound(pair<int, int>(r + 1, 0));
      while (e != ee) {
        u.push_back((*e));
        e++;
      }
      d = l;
      for (auto c : u) {
        if (d < c.first) update(1, 1, n, d, c.first - 1, 1, 1);
        update(1, 1, n, max(c.first, l), min(c.second, r), 0, 2);
        d = c.second + 1;
      }
      if (d <= r) update(1, 1, n, d, r, 1, 1);
      for (auto c : u) {
        l = min(l, c.first);
        r = max(r, c.second);
        g[x].erase(c);
      }
      g[x].insert(pair<int, int>(l, r));
    } else
      printf("%d\n", query(1, 1, n, l, r));
  }
  return 0;
}
