#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define REP(i, N) for (int i = 0; i < (int)N; i++) #define FOR(i, a, b) for (int i = a; i < (int)b; i++) #define ALL(x) (x).begin(), (x).end() using namespace std; constexpr int mod = 998244353; template struct ModInt { int x; ModInt() : x(0) {} ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {} ModInt& operator+=(const ModInt& p) { if ((x += p.x) >= mod) x -= mod; return *this; } ModInt& operator-=(const ModInt& p) { if ((x += mod - p.x) >= mod) x -= mod; return *this; } ModInt& operator*=(const ModInt& p) { x = (int)(1LL * x * p.x % mod); return *this; } ModInt& operator/=(const ModInt& p) { *this *= p.inverse(); return *this; } ModInt operator-() const { return ModInt(-x); } ModInt operator+(const ModInt& p) const { return ModInt(*this) += p; } ModInt operator-(const ModInt& p) const { return ModInt(*this) -= p; } ModInt operator*(const ModInt& p) const { return ModInt(*this) *= p; } ModInt operator/(const ModInt& p) const { return ModInt(*this) /= p; } ModInt inverse() const { int a = x, b = mod, u = 1, v = 0, t; while (b > 0) { t = a / b; swap(a -= t * b, b); swap(u -= t * v, v); } return ModInt(u); } ModInt pow(int64_t n) const { ModInt ret(1), mul(x); while (n > 0) { if (n & 1) ret *= mul; mul *= mul; n >>= 1; } return ret; } friend ostream& operator<<(ostream& os, const ModInt& p) { return os << p.x; } friend istream& operator>>(istream& is, ModInt& a) { int64_t t; is >> t; a = ModInt(t); return (is); } static int get_mod() { return mod; } }; using modint = ModInt; template struct BinaryIndexedTree { vector data; BinaryIndexedTree(int sz) { data.assign(++sz, 0); } T sum(int k) { T ret = 0; for (++k; k > 0; k -= k & -k) ret += data[k]; return (ret); } void add(int k, T x) { for (++k; k < data.size(); k += k & -k) data[k] += x; } }; int main() { int N, M; cin >> N >> M; int R = N - M; vector A(N, -1), used(N), cum(N + 1); REP(i, M) { int P, K; cin >> P >> K; A[K - 1] = P - 1; used[P - 1] = 1; } vector rest; REP(i, N) { if (!used[i]) rest.push_back(i); cum[i + 1] = cum[i] + (A[i] == -1); } vector facts(N + 1, 1); FOR(i, 2, N + 1) facts[i] = facts[i - 1] * i; BinaryIndexedTree bit(N + 1); modint ans = facts[R] * R * (R - 1) / 4; int B = 0; REP(i, N) { if (A[i] != -1) { int C = rest.end() - lower_bound(ALL(rest), A[i]); ans += facts[R - 1] * (C * cum[i] + (R - C) * (cum[N] - cum[i + 1])); ans += facts[R] * (i - cum[i] - bit.sum(A[i])); bit.add(A[i], 1); } } cout << ans << endl; return 0; }