#include <bits/stdc++.h>
using namespace std;
int madd(int a, int b) { return (a += b) < 998244353 ? a : a - 998244353; }
int mmul(int a, int b) { return (long long)a * b % 998244353; }
int n, q, value[262144 * 2], a[262144 * 2], b[262144 * 2];
set<pair<int, int>> s[262144];
int lft(int p) { return p * 2; }
int rgt(int p) { return p * 2 + 1; }
void push(int p, int L, int R) {
  if (R - L > 1) {
    for (int c = lft(p); c <= rgt(p); c++) {
      a[c] = mmul(a[p], a[c]);
      b[c] = madd(mmul(a[p], b[c]), b[p]);
    }
  }
  value[p] = madd(mmul(a[p], value[p]), mmul(b[p], R - L));
  a[p] = 1;
  b[p] = 0;
}
void update(int i, int j, int xa, int xb, int p = 1, int L = 0, int R = n) {
  push(p, L, R);
  if (j <= L || R <= i) {
    return;
  } else if (i <= L && R <= j) {
    a[p] = xa;
    b[p] = xb;
    push(p, L, R);
  } else {
    int M = (L + R) / 2;
    update(i, j, xa, xb, lft(p), L, M);
    update(i, j, xa, xb, rgt(p), M, R);
    value[p] = madd(value[lft(p)], value[rgt(p)]);
  }
}
int query(int i, int j, int p = 1, int L = 0, int R = n) {
  push(p, L, R);
  if (j <= L || R <= i) {
    return 0;
  } else if (i <= L && R <= j) {
    return value[p];
  } else {
    int M = (L + R) / 2;
    return madd(query(i, j, lft(p), L, M), query(i, j, rgt(p), M, R));
  }
}
void insert(int x, int L, int R) {
  update(L, R, 1, 1);
  while (true) {
    auto i = s[x].lower_bound({L, R});
    if (i != s[x].begin()) {
      i--;
      if (i->second <= L) i++;
    }
    if (i == s[x].end() || i->first >= R) break;
    s[x].erase(i);
    int l = max(L, i->first), r = min(R, i->second);
    update(l, r, 2, 998244353 - 2);
    L = min(L, i->first);
    R = max(R, i->second);
  }
  s[x].insert({L, R});
}
int main() {
  fill(a, a + 262144 * 2, 1);
  scanf("%d %d", &n, &q);
  for (int i = 0; i < q; i++) {
    int t, l, r, x;
    scanf("%d %d %d", &t, &l, &r);
    --l;
    if (t == 1) {
      scanf("%d", &x);
      --x;
      insert(x, l, r);
    } else {
      printf("%d\n", query(l, r));
    }
  }
}
