#include using namespace std; typedef long long ll; #define pb(x) push_back(x) #define mp(a, b) make_pair(a, b) #define all(x) x.begin(), x.end() #define rall(x) x.rbegin(), x.rend() #define lscan(x) scanf("%I64d", &x) #define lprint(x) printf("%I64d", x) #define rep(i, n) for (ll i = 0; i < (n); i++) #define rep2(i, n) for (ll i = (ll)n - 1; i >= 0; i--) #define REP(i, l, r) for (ll i = l; i < (r); i++) #define REP2(i, l, r) for (ll i = (ll)r - 1; i >= (l); i--) #define siz(x) (ll)x.size() template using rque = priority_queue, greater>; const ll mod = 998244353; template bool chmin(T &a, const T &b) { if (b < a) { a = b; return 1; } return 0; } template bool chmax(T &a, const T &b) { if (b > a) { a = b; return 1; } return 0; } ll gcd(ll a, ll b) { if(a == 0) return b; if(b == 0) return a; ll c = a % b; while (c != 0) { a = b; b = c; c = a % b; } return b; } long long extGCD(long long a, long long b, long long &x, long long &y) { if (b == 0) { x = 1; y = 0; return a; } long long d = extGCD(b, a % b, y, x); y -= a / b * x; return d; } struct UnionFind { vector data; int num; UnionFind(int sz) { data.assign(sz, -1); num = sz; } bool unite(int x, int y) { x = find(x), y = find(y); if (x == y) return (false); if (data[x] > data[y]) swap(x, y); data[x] += data[y]; data[y] = x; num--; return (true); } int find(int k) { if (data[k] < 0) return (k); return (data[k] = find(data[k])); } ll size(int k) { return (-data[find(k)]); } }; ll M = 1000000007; 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; } bool operator==(const ModInt &p) const { return x == p.x; } bool operator!=(const ModInt &p) const { return x != p.x; } 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 constexpr uint32_t get_mod() { return mod; } }; using mint = ModInt; mint mpow(mint x, ll n) { mint ans = 1; while (n != 0) { if (n & 1) ans *= x; x *= x; n = n >> 1; } return ans; } ll mpow2(ll x, ll n, ll mod) { ll ans = 1; while (n != 0) { if (n & 1) ans = ans * x % mod; x = x * x % mod; n = n >> 1; } return ans; } vector fac; vector ifac; void setcomb(int sz = 2000010) { fac.assign(sz + 1, 0); ifac.assign(sz + 1, 0); fac[0] = 1; for (ll i = 0; i < sz; i++) { fac[i + 1] = fac[i] * (i + 1); // n!(mod M) } ifac[sz] = fac[sz].inverse(); for (ll i = sz; i > 0; i--) { ifac[i - 1] = ifac[i] * i; } } mint comb(ll a, ll b) { if(fac.size() == 0) setcomb(); if (a == 0 && b == 0) return 1; if (a < b || a < 0) return 0; return ifac[a - b] * ifac[b] * fac[a]; } mint perm(ll a, ll b) { if(fac.size() == 0) setcomb(); if (a == 0 && b == 0) return 1; if (a < b || a < 0) return 0; return fac[a] * ifac[a - b]; } long long modinv(long long a) { long long b = M, u = 1, v = 0; while (b) { long long t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v); } u %= M; if (u < 0) u += M; return u; } ll modinv2(ll a, ll mod) { ll b = mod, u = 1, v = 0; while (b) { ll t = a / b; a -= t * b; swap(a, b); u -= t * v; swap(u, v); } u %= mod; if (u < 0) u += mod; return u; } static constexpr uint32_t get_pr(uint32_t mod) { using u64 = uint64_t; u64 ds[32] = {}; int idx = 0; u64 m = mod - 1; for(u64 i = 2 ; i * i <= m; ++i){ if(m % i == 0){ ds[idx++] = i; while(m % i == 0) m /= i; } } if(m != 1) ds[idx++] = m; uint32_t pr = 2; while(1){ int flg = 1; for(int i = 0 ; i < idx ; i++){ u64 a = pr , b = (mod - 1) / ds[i] , r = 1; while(b){ if(b & 1) r = r * a % mod; a = a * a % mod; b >>= 1; } if(r == 1){ flg = 0; break; } } if(flg == 1) break; ++pr; } return pr; }; template struct NTT { static constexpr uint32_t mod = mint::get_mod(); static constexpr uint32_t pr = get_pr(mod); vector w, y; void setwy(int M) { if ((int)w.size() >= (M >> 1)) return; w.resize(M >> 1); y.resize(M >> 1); mint z = mint(pr).pow((mod - 1) / M); mint x = z.inverse(); int j = M >> 2; while (j) { w[j] = z; z *= z; y[j] = x; x *= x; j >>= 1; } genwy(0, M >> 2, 1, 1); } void genwy(int i, int b, mint z, mint x) { if (b == 0) w[i] = z, y[i] = x; else { genwy(i, b >> 1, z, x); genwy(i | b, b >> 1, w[b] * z, y[b] * x); } } void fft(vector &a, int k) { int u = 1; int v = 1 << (k - 1); while (v) { // jh = 0 , wj = 1 for(int j = 0; j < v; ++j) { mint ajv = a[j + v]; a[j + v] = a[j] - ajv; a[j] += ajv; } // jh >= 1 for (int jh = 1; jh < u; ++jh) { mint wj = w[jh]; int je = jh * v * 2 + v; for (int j = jh * v * 2; j < je; ++j) { mint ajv = wj * a[j + v]; a[j + v] = a[j] - ajv; a[j] += ajv; } } u <<= 1; v >>= 1; } } void ifft(vector &a, int k) { int u = 1 << (k - 1); int v = 1; while (u) { // jh = 0, wj = 1 for(int j = 0; j < v; ++j){ mint ajv = a[j] - a[j + v]; a[j] += a[j + v]; a[j + v] = ajv; } // jh >= 1 for (int jh = 1; jh < u; ++jh) { mint wj = y[jh]; int je = jh * v * 2 + v; for (int j = jh * v * 2; j < je; ++j) { mint ajv = a[j] - a[j + v]; a[j] += a[j + v]; a[j + v] = wj * ajv; } } u >>= 1; v <<= 1; } } vector multiply(vector s, vector t) { int l = s.size() + t.size() - 1; int k = 2, M = 4; while (M < l) M <<= 1, ++k; setwy(M); s.resize(M); t.resize(M); fft(s, k); fft(t, k); for (int i = 0; i < M; ++i) s[i] *= t[i]; ifft(s, k); s.resize(l); mint invm = mint(M).inverse(); for (auto &x : s) x *= invm; return s; } }; int main(){ ios::sync_with_stdio(false); std::cin.tie(nullptr); ll n, q; cin >> n >> q; ll k, a, b, s, t; unordered_map> m; mint cnt = n; NTT ntt; rep(i,q){ cin >> k >> a >> b >> s >> t; s--; if (m[k].size() == 0){ cnt -= 1; m[k].resize(3001, 1); } REP(j, a, b + 1) m[k][j] = 0; vector dp(1, 1); for (auto &e : m){ dp = ntt.multiply(dp, e.second); dp.resize(3001); } mint ans = 0, com = 1; rep2(j, t + 1) ans += dp[j] * com, com *= cnt + t - j + 1, com /= t - j + 1; com = 1; rep2(j, s + 1) ans -= dp[j] * com, com *= cnt + s - j + 1, com /= s - j + 1; cout << ans << endl; } }