#include <bits/stdc++.h>
using namespace std;
int n, m;
int p[200005];
int sum[200005 << 2];
pair<int, int> lazy[200005 << 2];
map<int, int> coveredSegments[200005];
void apply(int i, int len, pair<int, int> val) {
  sum[i] = (1LL * sum[i] * val.first + 1LL * len * val.second) % 998244353;
  lazy[i].first = 1LL * lazy[i].first * val.first % 998244353;
  lazy[i].second = (1LL * lazy[i].second * val.first + val.second) % 998244353;
}
void update(int l, int r, int x, int y, int i, pair<int, int> val) {
  if (x <= l && r <= y) {
    apply(i, r - l + 1, val);
    return;
  }
  int mid = (l + r) >> 1;
  if (lazy[i].first != 1 || lazy[i].second != 0) {
    apply(i + i, mid - l + 1, lazy[i]);
    apply(i + i + 1, r - mid, lazy[i]);
    lazy[i] = make_pair(1, 0);
  }
  if (mid >= x) {
    update(l, mid, x, y, i + i, val);
  }
  if (mid < y) {
    update(mid + 1, r, x, y, i + i + 1, val);
  }
  sum[i] = (sum[i + i] + sum[i + i + 1]) % 998244353;
}
int get(int l, int r, int x, int y, int i) {
  if (l > y || r < x) {
    return 0;
  }
  if (x <= l && r <= y) {
    return sum[i];
  }
  int mid = (l + r) >> 1;
  if (lazy[i].first != 1 || lazy[i].second != 0) {
    apply(i + i, mid - l + 1, lazy[i]);
    apply(i + i + 1, r - mid, lazy[i]);
    lazy[i] = make_pair(1, 0);
  }
  return (get(l, mid, x, y, i + i) + get(mid + 1, r, x, y, i + i + 1)) %
         998244353;
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; i++) {
    coveredSegments[i][0] = 0;
    coveredSegments[i][n + 1] = n + 1;
  }
  for (int i = 1; i <= n << 2; i++) {
    lazy[i] = make_pair(1, 0);
  }
  for (int i = 0; i < m; i++) {
    int type, l, r;
    scanf("%d %d %d", &type, &l, &r);
    if (type == 1) {
      int num;
      scanf("%d", &num);
      auto it = coveredSegments[num].upper_bound(l);
      it--;
      int startingPoint = l;
      int terminatingPoint = r;
      vector<int> removedList;
      if (it->second >= l) {
        startingPoint = it->first;
      } else {
        it++;
        update(1, n, l, min(r, it->first - 1), 1, make_pair(1, 1));
      }
      while (it->first <= r) {
        update(1, n, max(l, it->first), min(r, it->second), 1, make_pair(2, 0));
        terminatingPoint = max(terminatingPoint, it->second);
        removedList.push_back(it->first);
        if (it->second < r) {
          int s = it->second + 1;
          it++;
          update(1, n, s, min(r, it->first - 1), 1, make_pair(1, 1));
        } else {
          it++;
        }
      }
      for (int p : removedList) {
        coveredSegments[num].erase(p);
      }
      coveredSegments[num][startingPoint] = terminatingPoint;
    } else {
      printf("%d\n", get(1, n, l, r, 1));
    }
  }
}
