#include #include using namespace std; using namespace atcoder; #define OVERLOAD_REP(_1, _2, _3, name, ...) name #define REP1(i, n) for (auto i = std::decay_t{}; (i) != (n); ++(i)) #define REP2(i, l, r) for (auto i = (l); (i) != (r); ++(i)) #define rep(...) OVERLOAD_REP(__VA_ARGS__, REP2, REP1)(__VA_ARGS__) #define REP(i, l, r) rep(i, l, r+1) #define all(x) (x).begin(),(x).end() #define rall(x) (x).rbegin(),(x).rend() using ll = long long; using ld = long double; using P = pair; struct Edge { int to; ll w; }; using Graph = vector >; //using Graph = vector >; const ll INF = 2e18; //const int INF = 2e9; template using vc = vector; template using vv = vector >; template using vvv = vector > >; template using pq = priority_queue; template using pq_g = priority_queue, greater >; template istream& operator>>(istream& i, vc& v) { rep(j, 0, v.size()) i>>v[j]; return i; } template ostream& operator<<(ostream& o, vc& v) { rep(j, 0, v.size()) o< bool chmin(T& a, T b) { if(a > b) { a = b; return true; } return false; } template bool chmax(T& a, T b) { if(a < b) { a = b; return true; } return false; } // Interval Set // T: type of range, VAL: data type template struct IntervalSet { struct Node { T l, r; VAL val; Node(const T &l, const T &r, const VAL &val) : l(l), r(r), val(val) {} constexpr bool operator < (const Node &rhs) const { if (l != rhs.l) return l < rhs.l; else return r < rhs.r; } friend ostream& operator << (ostream &s, const Node &e) { return s << "([" << e.l << ", " << e.r << "): " << e.val << ")"; } }; // internal values const VAL identity; set S; // constructor IntervalSet(const VAL &identity = VAL()) : identity(identity) {} IntervalSet(const vector &v, const VAL &identity = VAL()) : identity(identity) { vector vec; for (int l = 0; l < (int)v.size();) { int r = l; while (r < (int)v.size() && v[r] == v[l]) r++; vec.emplace_back(l, r, v[l]); l = r; } S = set(vec.begin(), vec.end()); } // get the basic iterators constexpr typename set::iterator begin() { return S.begin(); } constexpr typename set::iterator end() { return S.end(); } // get the iterator of interval which contains p // not exist -> S.end() constexpr typename set::iterator get(const T &p) { auto it = S.upper_bound(Node(p, numeric_limits::max(), 0)); if (it == S.begin()) return S.end(); it = prev(it); if (it->l <= p && p < it->r) return it; else return S.end(); } // get the leftist iterator of interval which contains value >= p constexpr typename set::iterator lower_bound(const T &p) { auto it = get(p); if (it != S.end()) return it; return S.upper_bound(Node(p, numeric_limits::max(), 0)); } // exist the interval which contains p: true, [l, r): true constexpr bool covered(const T &p) { auto it = get(p); if (it != S.end()) return true; else return false; } constexpr bool covered(const T &l, const T &r) { assert(l <= r); if (l == r) return true; auto it = get(l); if (it != S.end() && r <= it->r) return true; else return false; } // is p, q in same interval? constexpr bool same(const T &p, const T &q) { if (!covered(p) || !covered(q)) return false; return get(p) == get(q); } // get the value of interval which contains p // not exist -> identity constexpr VAL get_val(const T &p) { auto it = get(p); if (it != S.end()) return it->val; else return identity; } VAL operator [] (const T &p) const { return get_val(p); } // get mex (>= p) constexpr T get_mex(const T &p = 0) { auto it = S.upper_bound(Node(p, numeric_limits::max(), 0)); if (it == S.begin()) return p; it = prev(it); if (it->l <= p && p < it->r) return it->r; else return p; } // update [l, r) with value val / insert [l, r) // del: reflect effects of interval-delete // add: reflect effects of interval-add // add and del should be reversed operation each other template void update(T l, T r, const VAL &val, const ADDFUNC &add, const DELFUNC &del) { auto it = S.lower_bound(Node(l, 0, val)); while (it != S.end() && it->l <= r) { if (it->l == r) { if (it->val ==val) { r = it->r; del(it->l, it->r, it->val); it = S.erase(it); } break; } if (it->r <= r) { del(it->l, it->r, it->val); it = S.erase(it); } else { if (it->val == val) { r = it->r; del(it->l, it->r, it->val); it = S.erase(it); } else { Node node = *it; del(it->l, it->r, it->val); it = S.erase(it); it = S.emplace_hint(it, r, node.r, node.val); add(it->l, it->r, it->val); } } } if (it != S.begin()) { it = prev(it); if (it->r == l) { if (it->val == val) { l = it->l; del(it->l, it->r, it->val); it = S.erase(it); } } else if (l < it->r) { if (it->val == val) { l = min(l, it->l); r = max(r, it->r); del(it->l, it->r, it->val); it = S.erase(it); } else { if (r < it->r) { it = S.emplace_hint(next(it), r, it->r, it->val); add(it->l, it->r, it->val); it = prev(it); } Node node = *it; del(it->l, it->r, it->val); it = S.erase(it); it = S.emplace_hint(it, node.l, l, node.val); add(it->l, it->r, it->val); } } } if (it != S.end()) it = next(it); it = S.emplace_hint(it, l, r, val); add(it->l, it->r, it->val); } void update(const T &l, const T &r, const VAL &val) { update(l, r, val, [](T, T, VAL){}, [](T, T, VAL){}); } template void insert(T l, T r, const ADDFUNC &add, const DELFUNC &del) { update(l, r, VAL(), add, del); } void insert(const T &l, const T &r) { update(l, r, VAL(), [](T, T, VAL){}, [](T, T, VAL){}); } // erase [l, r) // del: reflect effects of interval-delete // add: reflect effects of interval-add // add and del should be reversed operation each other template void erase(T l, T r, const ADDFUNC &add, const DELFUNC &del) { auto it = S.lower_bound(Node(l, 0, VAL())); //COUT(*it); while (it != S.end() && it->l <= r) { if (it->l == r) break; if (it->r <= r) { del(it->l, it->r, it->val); it = S.erase(it); } else { Node node = *it; del(it->l, it->r, it->val); it = S.erase(it); it = S.emplace_hint(it, r, node.r, node.val); add(it->l, it->r, it->val); } } if (it != S.begin()) { it = prev(it); if (l < it->r) { if (r < it->r) { it = S.emplace_hint(next(it), r, it->r, it->val); add(it->l, it->r, it->val); it = prev(it); } Node node = *it; //COUT(*it); del(it->l, it->r, it->val); it = S.erase(it); it = S.emplace_hint(it, node.l, l, node.val); add(it->l, it->r, it->val); //COUT(*it); } } } void erase(const T &l, const T &r) { erase(l, r, [](T, T, VAL){}, [](T, T, VAL){}); } // debug friend ostream& operator << (ostream &s, const IntervalSet &ins) { for (auto e : ins.S) { s << "([" << e.l << ", " << e.r << "): " << e.val << ") "; } return s; } }; int main() { // 高速化 ios::sync_with_stdio(false); cin.tie(nullptr); // 小数点の出力桁数を指定 cout << fixed << setprecision(10); // メイン ll D, Q; cin >> D >> Q; IntervalSet ins(0); ll res = 0; while(Q--) { ll L, R; cin >> L >> R; R++; ins.update(L, R, 1); ll l, r; l = ins.get(L)->l; r = ins.get(L)->r; chmax(res, r-l); cout << res << endl; } return 0; }