#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline void Read(T &x) {
  char c = getchar();
  bool f = false;
  for (x = 0; !isdigit(c); c = getchar()) {
    if (c == '-') {
      f = true;
    }
  }
  for (; isdigit(c); c = getchar()) {
    x = x * 10 + c - '0';
  }
  if (f) {
    x = -x;
  }
}
template <typename T>
inline bool CheckMax(T &a, const T &b) {
  return a < b ? a = b, true : false;
}
template <typename T>
inline bool CheckMin(T &a, const T &b) {
  return a > b ? a = b, true : false;
}
const int N = 200005;
const int mod = 998244353;
int n, m, add[N << 2], mul[N << 2], sum[N << 2];
set<pair<pair<int, int>, int>> s[N];
inline void Add(int x, int l, int r, int v) {
  add[x] = (add[x] + v) % mod;
  sum[x] = (sum[x] + 1LL * v * (r - l + 1)) % mod;
}
inline void Mul(int x, int v) {
  mul[x] = 1LL * mul[x] * v % mod;
  add[x] = 1LL * add[x] * v % mod;
  sum[x] = 1LL * sum[x] * v % mod;
}
inline void PushUp(int x) { sum[x] = (sum[x << 1] + sum[x << 1 | 1]) % mod; }
inline void PushDown(int x, int l, int r) {
  int mid = l + r >> 1;
  if (mul[x] != 1) {
    Mul(x << 1, mul[x]), Mul(x << 1 | 1, mul[x]), mul[x] = 1;
  }
  if (add[x]) {
    Add(x << 1, l, mid, add[x]), Add(x << 1 | 1, mid + 1, r, add[x]),
        add[x] = 0;
  }
}
inline void Build(int x, int l, int r) {
  mul[x] = 1;
  if (l == r) {
    return;
  }
  int mid = l + r >> 1;
  Build(x << 1, l, mid), Build(x << 1 | 1, mid + 1, r);
}
inline void Add(int x, int l, int r, int ql, int qr) {
  if (l == ql && r == qr) {
    Add(x, l, r, 1);
    return;
  }
  PushDown(x, l, r);
  int mid = l + r >> 1;
  if (qr <= mid) {
    Add(x << 1, l, mid, ql, qr);
  } else if (ql > mid) {
    Add(x << 1 | 1, mid + 1, r, ql, qr);
  } else {
    Add(x << 1, l, mid, ql, mid), Add(x << 1 | 1, mid + 1, r, mid + 1, qr);
  }
  PushUp(x);
}
inline void Mul(int x, int l, int r, int ql, int qr) {
  if (l == ql && r == qr) {
    Mul(x, 2);
    return;
  }
  PushDown(x, l, r);
  int mid = l + r >> 1;
  if (qr <= mid) {
    Mul(x << 1, l, mid, ql, qr);
  } else if (ql > mid) {
    Mul(x << 1 | 1, mid + 1, r, ql, qr);
  } else {
    Mul(x << 1, l, mid, ql, mid), Mul(x << 1 | 1, mid + 1, r, mid + 1, qr);
  }
  PushUp(x);
}
inline int Query(int x, int l, int r, int ql, int qr) {
  if (l == ql && r == qr) {
    return sum[x];
  }
  PushDown(x, l, r);
  int mid = l + r >> 1;
  if (qr <= mid) {
    return Query(x << 1, l, mid, ql, qr);
  } else if (ql > mid) {
    return Query(x << 1 | 1, mid + 1, r, ql, qr);
  } else {
    return (Query(x << 1, l, mid, ql, mid) +
            Query(x << 1 | 1, mid + 1, r, mid + 1, qr)) %
           mod;
  }
}
inline void Insert(set<pair<pair<int, int>, int>> &s, int l, int r) {
  auto i = --s.lower_bound(make_pair(make_pair(l + 1, l + 1), 0)),
       j = --s.lower_bound(make_pair(make_pair(r + 1, r + 1), 0));
  if (i == j) {
    int L = i->first.first, R = i->first.second, z = i->second;
    if (i->second) {
      Mul(1, 1, n, l, r);
    } else {
      Add(1, 1, n, l, r);
    }
    s.erase(i);
    s.insert(make_pair(make_pair(l, r), 1));
    if (l != L) {
      s.insert(make_pair(make_pair(L, l - 1), z));
    }
    if (r != R) {
      s.insert(make_pair(make_pair(r + 1, R), z));
    }
  } else {
    if (i->second) {
      Mul(1, 1, n, l, i->first.second);
    } else {
      Add(1, 1, n, l, i->first.second);
    }
    if (j->second) {
      Mul(1, 1, n, j->first.first, r);
    } else {
      Add(1, 1, n, j->first.first, r);
    }
    auto k = i;
    for (++k; k != j; ++k) {
      if (k->second) {
        Mul(1, 1, n, k->first.first, k->first.second);
      } else {
        Add(1, 1, n, k->first.first, k->first.second);
      }
    }
    for (k = i, ++k; k != j; s.erase(k++))
      ;
    int L = i->first.first, R = j->first.second;
    s.insert(make_pair(make_pair(l, r), 1));
    if (l != L) {
      s.insert(make_pair(make_pair(L, l - 1), i->second));
    }
    if (r != R) {
      s.insert(make_pair(make_pair(r + 1, R), j->second));
    }
    s.erase(i), s.erase(j);
  }
}
int main() {
  Read(n), Read(m), Build(1, 1, n);
  for (int i = 1; i <= n; ++i) {
    s[i].insert(make_pair(make_pair(1, n), false));
  }
  for (int i = 1, o, l, r; i <= m; ++i) {
    Read(o), Read(l), Read(r);
    if (o == 1) {
      int x;
      Read(x), Insert(s[x], l, r);
    } else {
      printf("%d\n", Query(1, 1, n, l, r));
    }
  }
  return 0;
}
