#include <bits/stdc++.h>
using namespace std;
int NUM_MULTISETS;
const int MAX_VALUE = 200000;
const int MOD = 998244353;
int sum[800000], mul[800000], add[800000];
void add_mod(int& x, int y) {
  x += y;
  if (x >= MOD) x -= MOD;
}
void propagate(int root, int l, int r) {
  if (mul[root] == 1 && add[root] == 0) return;
  if (l + 1 != r) {
    mul[2 * root + 1] = (long long)mul[root] * mul[2 * root + 1] % MOD;
    add[2 * root + 1] =
        ((long long)mul[root] * add[2 * root + 1] + add[root]) % MOD;
    mul[2 * root + 2] = (long long)mul[root] * mul[2 * root + 2] % MOD;
    add[2 * root + 2] =
        ((long long)mul[root] * add[2 * root + 2] + add[root]) % MOD;
  }
  sum[root] =
      ((long long)sum[root] * mul[root] + (long long)(r - l) * add[root]) % MOD;
  mul[root] = 1;
  add[root] = 0;
}
int query(int root, int l, int r, int a, int b) {
  if (r <= a || l >= b) return 0;
  if (l >= a && r <= b) {
    propagate(root, l, r);
    return sum[root];
  }
  propagate(root, l, r);
  int mid = (l + r) / 2;
  int ret = query(2 * root + 1, l, mid, a, b);
  add_mod(ret, query(2 * root + 2, mid, r, a, b));
  return ret;
}
void change(int root, int l, int r, int a, int b, int mult) {
  if (r <= a || l >= b) {
    propagate(root, l, r);
    return;
  }
  if (l >= a && r <= b) {
    if (mult) {
      add_mod(mul[root], mul[root]);
      add_mod(add[root], add[root]);
    } else
      add_mod(add[root], 1);
    propagate(root, l, r);
    return;
  }
  propagate(root, l, r);
  int mid = (l + r) / 2;
  change(2 * root + 1, l, mid, a, b, mult);
  change(2 * root + 2, mid, r, a, b, mult);
  sum[root] = sum[2 * root + 1];
  add_mod(sum[root], sum[2 * root + 2]);
}
set<pair<int, bool>> intervals[MAX_VALUE + 1];
void process_interval(set<pair<int, bool>>& s, int l, int r) {
  auto it = s.lower_bound(make_pair(l, true));
  bool opened = false;
  if (auto it2 = it; it != s.begin()) opened = !(--it2)->second;
  if (!opened) s.emplace(l, false);
  int prev = l;
  for (; it != s.end() && it->first <= r; it = s.erase(it), opened ^= 1) {
    change(0, 0, NUM_MULTISETS, prev, it->first, opened);
    prev = it->first;
  }
  change(0, 0, NUM_MULTISETS, prev, r, opened);
  if (!opened) s.emplace(r, true);
}
int main() {
  int n, q;
  scanf("%d %d", &n, &q);
  NUM_MULTISETS = n;
  for (int i = 0; i < 800000; i++) mul[i] = 1;
  while (q--) {
    int t, l, r;
    scanf("%d %d %d", &t, &l, &r);
    l--;
    if (t == 1) {
      int x;
      scanf("%d", &x);
      x--;
      process_interval(intervals[x], l, r);
    } else
      printf("%d\n", query(0, 0, NUM_MULTISETS, l, r));
  }
}
