#include #include using namespace std; using ll = long long; #define rep(i, s, t) for (ll i = s; i < (ll)(t); i++) #define all(x) begin(x), end(x) template bool chmin(T& x, T y) { return x > y ? (x = y, true) : false; } template bool chmax(T& x, T y) { return x < y ? (x = y, true) : false; } struct io_setup { io_setup() { ios::sync_with_stdio(false); cin.tie(nullptr); cout << fixed << setprecision(15); } } io_setup; using mint = atcoder::modint998244353; using ull = unsigned long long; constexpr int mod = 998244353; struct Event { ll pos; ll type; ll idx; bool operator<(const Event& e) const { if (pos != e.pos) return pos < e.pos; return type < e.type; } }; void zobrist_init(vector& a) { mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count()); for (int i = 0; i < (int)(a.size()); i++) a[i] = rng(); } ll naru_solve(ll n, ll m, vector vl, vector vr) { ll two_pow = 748683265; // 4^{-1} mod 998244353 vector events; for (int i = 0; i < m; i++) { // cin >> l >> r; // events.push_back({l, 0, i}); // events.push_back({r + 1, 1, i}); events.push_back({vl[i] + 1, 0, i}); events.push_back({vr[i] + 1, 1, i}); two_pow = (two_pow << 1) % mod; } vector zobrist(m + 1); zobrist_init(zobrist); sort(all(events)); map t; ll last = 1; ull hash = 0; for (auto& e : events) { ll now = e.pos; if (now > last) t[hash] = (t[hash] + (now - last)) % mod; hash ^= zobrist[e.idx]; last = now; } if (last <= n) t[hash] = (t[hash] + (n - last + 1)) % mod; ll n0 = t[0], p = 0; for (auto& [h, w] : t) { if (h) p = (p + w * (w - 1)) % mod; } ll ans = ((n + n0) % mod) % mod; ans = (ans * ((n + n0) % mod)) % mod; ans = (ans + n + p - n0) % mod; ans = (ans * two_pow) % mod; return ans; } ll solve(ll n, ll m, vector l, vector r) { vector cv = {0, n}; rep(i, 0, m) { cv.push_back(l[i]); cv.push_back(r[i]); } sort(cv.begin(), cv.end()); cv.erase(unique(cv.begin(), cv.end()), cv.end()); int k = cv.size(); auto get_ith = [&](ll x) { return lower_bound(cv.begin(), cv.end(), x) - cv.begin(); }; vector im(k); { random_device rd; mt19937_64 mt(rd()); rep(i, 0, m) { int nl = get_ith(l[i]); int nr = get_ith(r[i]); ull hs = mt(); im[nl] ^= hs; im[nr] ^= hs; } } map mp; rep(i, 0, k - 1) { mp[im[i]] += cv[i + 1] - cv[i]; im[i + 1] ^= im[i]; } mint ans = 0; { mint tmp = mp[0] + (n - mp[0]) / 2; ans += tmp * tmp; mp.erase(0); } for (auto [hs, ad] : mp) { ans += ad * ad / 4; } ans *= mint(2).pow(m); return ans.val(); } ll greedy(ll n, ll m, vector l, vector r) { mint ans = 0; rep(bit, 0, 1 << m) { vector f(n + 1); rep(i, 0, m) if ((bit >> i) & 1) { f[l[i]] ^= 1; f[r[i]] ^= 1; } mint tmp = 0; rep(i, 0, n) { if (!f[i]) tmp++; f[i + 1] ^= f[i]; } // cout << bitset<3>(bit) << ' ' << tmp.val() << endl; // rep(i, 0, n) cout << f[i]; // cout << endl; ans += tmp * tmp; } return ans.val(); } void test() { int n = 20; int m = 10; vector l(m), r(m); rep(lp, 0, 1000) { rep(i, 0, m) { l[i] = rand() % n + 1; r[i] = rand() % n + 1; if (r[i] < l[i]) swap(l[i], r[i]); l[i]--; } auto a1 = solve(n, m, l, r); auto a2 = greedy(n, m, l, r); if (a1 != a2) { cout << a1 << endl; cout << a2 << endl; cout << n << ' ' << m << endl; rep(i, 0, m) cout << l[i] + 1 << ' ' << r[i] << endl; assert(0); } } } int main() { // test(); // return 0; ll n, m; cin >> n >> m; vector l(m), r(m); rep(i, 0, m) cin >> l[i] >> r[i], l[i]--; // cout << naru_solve(n, m, l, r) << '\n'; cout << solve(n, m, l, r) << '\n'; // cout << greedy(n, m, l, r) << '\n'; }