#include #include using namespace std; using namespace atcoder; struct Fast { Fast() { std::cin.tie(nullptr); ios::sync_with_stdio(false); cout << setprecision(10); } } fast; #define rep(i, a, b) for (int(i) = (a); (i) < (int)(b); (i)++) #define rrep(i, a, b) for (int(i) = (int)(b)-1; (i) >= (int)(a); (i)--) template struct dual_segtree { public: dual_segtree(int n) { while (sz < n) { sz <<= 1; log++; } lz = vector(sz * 2, id()); } F get(int p) { p += sz; for (int i = log; i > 0; i--) push(p >> i); return lz[p]; } void set(int p, const F& f) { p += sz; for (int i = log; i > 0; i--) push(p >> i); lz[p] = f; } void apply(int l, int r, const F& f) { if (l >= r) return; l += sz; r += sz; for (int i = log; i > 0; i--) { if (((l >> i) << i) != l) push(l >> i); if (((r >> i) << i) != r) push((r - 1) >> i); } for (; l < r; l /= 2, r /= 2) { if (l & 1) comp(lz[l++], f); if (r & 1) comp(lz[--r], f); } } private: int sz = 1, log = 0; vector lz; void comp(F& f, const F& g) { f = composition(g, f); } void push(int p) { comp(lz[p * 2], lz[p]); comp(lz[p * 2 + 1], lz[p]); lz[p] = id(); } }; const int LOG = 30; const int MASK = (1 << LOG) - 1; using P = pair; using mint = modint998244353; P composition(P f, P g) { return P((~g.first & f.first) | (g.first & f.second), (~g.second & f.first) | (g.second & f.second)); }; P id() { return P(0, MASK); } int main() { int n, q; cin >> n >> q; vector m(n); rep(i, 0, n) cin >> m[i]; dual_segtree seg(n); while (q--) { char c; int l, r, x; cin >> c >> l >> r >> x; l--; seg.apply(l, r, c == 'o' ? P(x, MASK) : P(x, MASK ^ x)); } vector fact(100), ifact(100); fact[0] = 1; rep(i, 1, fact.size()) fact[i] = fact[i - 1] * i; ifact[99] = fact[99].inv(); rrep(i, 1, ifact.size()) ifact[i - 1] = ifact[i] * i; auto binom = [fact, ifact](int n, int k) -> mint { return k < 0 || k > n ? 0 : fact[n] * ifact[k] * ifact[n - k]; }; vector prod(LOG + 1, 1); auto solve_small = [&prod, binom](int b, int c, int m) -> void { vector f(LOG + 1, 0); auto cnt = array{0, 0, 0}; int a = __builtin_popcount(((m ^ MASK) & b) | (m & c)); rep(i, 0, LOG) { a -= (((m ^ MASK) & b) | (m & c)) & 1; a += b & 1; if (m & 1) { rep(j, 0, LOG + 1) { f[j] += binom(cnt[1], j - a - cnt[2]) * (1 << (cnt[0] + cnt[2])); } } a -= b & 1; cnt[(b & 1) + (c & 1)]++; m >>= 1; b >>= 1; c >>= 1; } rep(i, 0, LOG) f[i + 1] += f[i]; rep(i, 0, LOG + 1) prod[i] *= f[i]; }; rep(i, 0, n) { auto p = seg.get(i); solve_small(p.first, p.second, m[i] + 1); } mint ans = LOG * prod[LOG]; rep(i, 0, LOG) ans -= prod[i]; cout << ans.val() << endl; }