#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
const int maxt = (1 << 19) + 20;
vector<pair<pair<int, int>, int> > ad[maxn];
vector<pair<pair<int, int>, int> > qs[maxn];
set<pair<int, int> > st;
set<pair<int, int> >::iterator it1, it2, it3;
int n, q;
long long val[maxt], taga[maxt], tagb[maxt];
void update(int x) {
  val[x] = val[x * 2] + val[x * 2 + 1];
  if (val[x] >= 998244353) val[x] -= 998244353;
}
void build(int x, int l, int r) {
  val[x] = tagb[x] = 0;
  taga[x] = 1;
  if (l == r) return;
  int mid = (l + r) >> 1;
  build(x * 2, l, mid);
  build(x * 2 + 1, mid + 1, r);
}
void taketag(int x, int l, int r) {
  if (l == r) {
    taga[x] = 1;
    tagb[x] = 0;
    return;
  }
  int mid = (l + r) >> 1;
  val[x * 2] = (val[x * 2] * taga[x]) % 998244353;
  val[x * 2] = (val[x * 2] + tagb[x] * (mid - l + 1)) % 998244353;
  val[x * 2 + 1] = (val[x * 2 + 1] * taga[x]) % 998244353;
  val[x * 2 + 1] = (val[x * 2 + 1] + tagb[x] * (r - mid)) % 998244353;
  taga[x * 2] = (taga[x * 2] * taga[x]) % 998244353;
  tagb[x * 2] = (tagb[x * 2] * taga[x]) % 998244353;
  tagb[x * 2] = tagb[x * 2] + tagb[x];
  if (tagb[x * 2] >= 998244353) tagb[x * 2] -= 998244353;
  taga[x * 2 + 1] = (taga[x * 2 + 1] * taga[x]) % 998244353;
  tagb[x * 2 + 1] = (tagb[x * 2 + 1] * taga[x]) % 998244353;
  tagb[x * 2 + 1] = tagb[x * 2 + 1] + tagb[x];
  if (tagb[x * 2 + 1] >= 998244353) tagb[x * 2 + 1] -= 998244353;
  taga[x] = 1;
  tagb[x] = 0;
}
void modify(int x, int l, int r, int tl, int tr, long long a, long long b) {
  if (l > tr || r < tl) return;
  if (tl <= l && r <= tr) {
    val[x] = (val[x] * a) % 998244353;
    val[x] = (val[x] + b * (r - l + 1)) % 998244353;
    taga[x] = (taga[x] * a) % 998244353;
    tagb[x] = (tagb[x] * a + b) % 998244353;
    taketag(x, l, r);
    return;
  }
  taketag(x, l, r);
  int mid = (l + r) >> 1;
  modify(x * 2, l, mid, tl, tr, a, b);
  modify(x * 2 + 1, mid + 1, r, tl, tr, a, b);
  update(x);
}
long long query(int x, int l, int r, int tl, int tr) {
  if (l > tr || r < tl) return 0;
  if (tl <= l && r <= tr) return val[x];
  taketag(x, l, r);
  int mid = (l + r) >> 1;
  long long ans =
      (query(x * 2, l, mid, tl, tr) + query(x * 2 + 1, mid + 1, r, tl, tr)) %
      998244353;
  return ans;
}
int main() {
  scanf("%d%d", &n, &q);
  for (int i = 1; i <= q; i++) {
    int t, l, r, x;
    scanf("%d%d%d", &t, &l, &r);
    if (t == 1) {
      scanf("%d", &x);
      ad[x].push_back(make_pair(make_pair(l, r), i));
    } else
      qs[i].push_back(make_pair(make_pair(l, r), 0));
  }
  for (int i = 1; i <= n; i++)
    if (!ad[i].empty()) {
      st.clear();
      st.insert(make_pair(1, 0));
      st.insert(make_pair(n, 1));
      for (int j = 0; j < ad[i].size(); j++) {
        int l = ad[i][j].first.first;
        int r = ad[i][j].first.second;
        if (st.empty()) {
          qs[ad[i][j].second].push_back(make_pair(ad[i][j].first, 2));
        } else {
          it1 = st.lower_bound(make_pair(l, -1));
          if ((*it1).second == 1) {
            st.insert(make_pair(l - 1, 1));
          }
          int pre = l;
          bool beg = 0, ed = 0;
          for (it2 = it1; it2 != st.end();) {
            int cur = (*it2).first;
            int op = (*it2).second;
            if (cur > r) break;
            if (op == 0) {
              if (pre <= cur - 1) {
                qs[ad[i][j].second].push_back(
                    make_pair(make_pair(pre, cur - 1), 2));
              }
              pre = cur;
            } else {
              qs[ad[i][j].second].push_back(make_pair(make_pair(pre, cur), 1));
              pre = cur + 1;
            }
            it1 = it2;
            ++it2;
            st.erase(it1);
          }
          if (pre <= r) {
            int op = 0;
            if (it2 != st.end()) op = (*it2).second;
            if (op == 0) {
              if (pre <= r) {
                qs[ad[i][j].second].push_back(make_pair(make_pair(pre, r), 2));
              }
            } else {
              qs[ad[i][j].second].push_back(make_pair(make_pair(pre, r), 1));
              st.insert(make_pair(r + 1, 0));
            }
          }
        }
      }
    }
  build(1, 1, n);
  for (int i = 1; i <= q; i++)
    for (int j = 0; j < qs[i].size(); j++) {
      if (qs[i][j].second == 0) {
        printf("%I64d\n",
               query(1, 1, n, qs[i][j].first.first, qs[i][j].first.second));
      } else if (qs[i][j].second == 1) {
        modify(1, 1, n, qs[i][j].first.first, qs[i][j].first.second, 1, 1);
      } else {
        modify(1, 1, n, qs[i][j].first.first, qs[i][j].first.second, 2, 0);
      }
    }
  return 0;
}
