Problem:
J: エナジードリンク
問題
ixmel、Pulmn 兄弟は $N$ 種類のエナジードリンクをそれぞれ 1 本ずつ持っています。
現在、ixmel と Pulmn のエネルギーはともに 0 で、時刻は午前 0 時です。
ixmel と Pulmn はエネルギーが 0 以下のまま正午になると「たいへんなこと」になります。
エネルギーが正の数では「たいへんなこと」にはなりません。
ixmel とPulmn は「たいへんなこと」にならないために、
毎日朝 6 時に 1 本のエナジードリンクを 2 人で分けて飲むことにしました。
i 番目のエナジードリンクを ixmel が飲むとエネルギーが $a_i$ 増えますが、副作用として 24 時間後にエネルギーが $b_i$ 減ってしまいます。
一方、Pulmn が飲むとエネルギーが $b_i$ 増え、24 時間後にエネルギーが $a_i$ 減ります。
また、ixmel と Pulmn は日が変わった直後、エネルギーは 0 になります。
ixmel と Pulmn は今持っているエナジードリンクだけで、どちらか一方、または両方が「たいへんなこと」になるまでの日数を少しでも長くしたいと思いました。
ixmel、Pulmn 兄弟のために最初にどちらか片方、または両方が「たいへんなこと」になるまでの日数の最大値を求めてください。なお、エナジードリンクを飲む時間は無視できるものとし、「たいへんなこと」が起こる日は求める日数に含まないものとします。
入力
入力は $1+n$ 行からなります。
1 行目には 1 個の整数 $N$ が与えられます。
続く $N$ 行の内、$i$ 行目は 2 個の整数 $a_i, b_i$ が与えられます。
制約
$1 \le N \le 10^5$
$1 \le a_i, b_i \le 10^9$
出力
考えられる「たいへんなこと」になるまでの日数の最大値を出力しましょう。
また、末尾に改行を出力しましょう。
サンプル
サンプル入力 1
5
3 5
7 4
11 9
3 7
7 8
サンプル出力 1
4
1 日目から 5 日目に飲むドリンクは、それぞれ 1, 2, 5, 3, 4 とするのが最適です。
各日のエナジードリンクを飲んだあとの (ixmel の体力, Pulmn の体力) は、それぞれ $(3, 5), (2, 1), (1, 3), (3, 2), (-6, -4)$ と変化し、
5 日目に「たいへんなこと」になるので答えは 4 です。
サンプル入力 2
2
1 1
1 1
サンプル出力 2
1
異なる種類で成分が同じエナジードリンクもあります。また、「たいへんなこと」が起こるのは、エネルギーの量が 0 以下の時であることに注意してください。
サンプル入力 2
3
5 9
3 2
7 4
サンプル出力 2
3
4 日目に飲むエナジードリンクはありません。

Submitted solutions:

code_snippet: #line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"
using namespace std;

#include<bits/stdc++.h>
#line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp"
namespace noya2 {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
    os << p.first << " " << p.second;
    return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p){
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
    int s = (int)v.size();
    for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
    return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v){
    for (auto &x : v) is >> x;
    return is;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u){
    cin >> t;
    in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u){
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}

template<typename T>
void out(const vector<vector<T>> &vv){
    int s = (int)vv.size();
    for (int i = 0; i < s; i++) out(vv[i]);
}

struct IoSetup {
    IoSetup(){
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(7);
    }
} iosetup_noya2;

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp"
namespace noya2{

const int iinf = 1'000'000'007;
const long long linf = 2'000'000'000'000'000'000LL;
const long long mod998 =  998244353;
const long long mod107 = 1000000007;
const long double pi = 3.14159265358979323;
const vector<int> dx = {0,1,0,-1,1,1,-1,-1};
const vector<int> dy = {1,0,-1,0,1,-1,-1,1};
const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string alp = "abcdefghijklmnopqrstuvwxyz";
const string NUM = "0123456789";

void yes(){ cout << "Yes\n"; }
void no(){ cout << "No\n"; }
void YES(){ cout << "YES\n"; }
void NO(){ cout << "NO\n"; }
void yn(bool t){ t ? yes() : no(); }
void YN(bool t){ t ? YES() : NO(); }

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"
namespace noya2{

unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){
    if (a == 0 || b == 0) return a + b;
    int n = __builtin_ctzll(a); a >>= n;
    int m = __builtin_ctzll(b); b >>= m;
    while (a != b) {
        int mm = __builtin_ctzll(a - b);
        bool f = a > b;
        unsigned long long c = f ? a : b;
        b = f ? b : a;
        a = (c - b) >> mm;
    }
    return a << min(n, m);
}

template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(abs(a),abs(b))); }

long long sqrt_fast(long long n) {
    if (n <= 0) return 0;
    long long x = sqrt(n);
    while ((x + 1) * (x + 1) <= n) x++;
    while (x * x > n) x--;
    return x;
}

template<typename T> T floor_div(const T n, const T d) {
    assert(d != 0);
    return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0);
}

template<typename T> T ceil_div(const T n, const T d) {
    assert(d != 0);
    return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0);
}

template<typename T> void uniq(vector<T> &v){
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}

template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }

template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; }

} // namespace noya2
#line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"

#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define repp(i,m,n) for (int i = (m); i < (int)(n); i++)
#define reb(i,n) for (int i = (int)(n-1); i >= 0; i--)
#define all(v) (v).begin(),(v).end()

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pil = pair<int,ll>;
using pli = pair<ll,int>;

namespace noya2{

/*　~ (. _________ . /)　*/

}

using namespace noya2;


#line 2 "c.cpp"


#line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/compress.hpp"

#line 4 "/Users/noya2/Desktop/Noya2_library/data_structure/compress.hpp"

namespace noya2{

template<typename T> struct compress {
    vector<T> raws;
    compress(const vector<T> &raws_ = {}) : raws(raws_){ build(); }
    int id(const T &raw){ return lb(raw); }
    T raw(const int &id){ return raws[id]; }
    void build(){ uniq(raws); }
    void add(const T &raw){ raws.push_back(raw); }
    size_t size(){ return raws.size(); }
    int lb(const T &raw){ return lower_bound(all(raws),raw) - raws.begin(); }
    int ub(const T &raw){ return upper_bound(all(raws),raw) - raws.begin(); }
    bool contains(const T &raw){
        int jd = lb(raw);
        if (jd < (int)size()) return raws[jd] == raw;
        return false;
    }
    int contains_id(const T &raw){
        int jd = lb(raw);
        if (jd < (int)size() && raws[jd] == raw) return jd;
        return -1;
    }
};

} // namespace noya2
#line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/segment_tree.hpp"

namespace noya2{

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = 0;
        size = 1;
        while (size < _n) size <<= 1, log++;

        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

} // namespace noya2
#line 7 "c.cpp"


namespace noya2 {

template<class S, S(*op)(S, S), S(*e)(), typename Idx = ll>
struct range_tree {
    using DS = segtree<S,op,e>;
    using T = int;
    void join(Idx x, Idx y){ ps.emplace_back(x,y); }
    void build(){
        for (auto &[x, y] : ps) xs.add(x);
        xs.build();
        //siz = bit_ceil(xs.size());
        siz = 1; while (siz < (int)(xs.size())) siz <<= 1;
        ys.resize(siz*2);
        for (auto &[x, y] : ps){
            int xid = xs.id(x) + siz;
            ys[xid].add(y);
            while (xid > 1){
                xid >>= 1;
                ys[xid].add(y);
            }
        }
        for (int i = 0; i < 2*siz; i++){
            ys[i].build();
            ds.emplace_back(ys[i].size());
        }
    }
    void set(Idx p, Idx q, T val){
        int i = xs.id(p) + siz;
        ds[i].set(ys[i].id(q),val);
        while (i > 1){
            i >>= 1;
            T lr = e();
            int i0 = ys[2*i+0].contains_id(q), i1 = ys[2*i+1].contains_id(q);
            if (i0 != -1) lr = op(lr, ds[2*i+0].get(i0));
            if (i1 != -1) lr = op(lr, ds[2*i+1].get(i1));
            ds[i].set(ys[i].id(q),lr);
        }
    }
    T get(Idx p, Idx q){
        int ip = xs.contains_id(p);
        if (ip == -1) return e();
        int i = ip + siz;
        int iq = ys[i].contains_id(q);
        if (iq == -1) return e();
        return ds[i].get(iq);
    }
    T prod(Idx lp, Idx rp, Idx lq, Idx rq){
        T res = e();
        int li = xs.lb(lp), ri = xs.lb(rp);
        for (li += siz, ri += siz; li < ri; li >>= 1, ri >>= 1){
            if (li & 1) res = op(res,ds[li].prod(ys[li].lb(lq),ys[li].lb(rq))), ++li;
            if (ri & 1) --ri, res = op(res,ds[ri].prod(ys[ri].lb(lq),ys[ri].lb(rq)));
        }
        return res;
    }
    int siz;
    vector<pair<Idx,Idx>> ps;
    compress<Idx> xs;
    vector<compress<Idx>> ys;
    vector<DS> ds;
};

} // namespace noya2

int op(int a, int b){
    return max(a,b);
}
int e(){
    return -iinf;
}

void solve(){
    int n; in(n);
    vector<int> a(n), b(n);
    rep(i,n) in(a[i],b[i]);
    vector<int> ids(n); iota(all(ids),0);
    sort(all(ids),[&](int l, int r){
        return a[l]+b[l] < a[r]+b[r];
    });
    range_tree<int,op,e,int> rt;
    rep(i,n){
        rep(tt,2){
            rt.join(a[i],b[i]);
            swap(a[i],b[i]);
        }
    }
    rt.build();
    int ans = 1;
    for (int i : ids){
        // out(i,a[i],b[i]);
        rep(tt,2){
            int d = max(rt.prod(0,a[i],0,b[i]),0);
            rt.set(a[i],b[i],d+1);
            swap(a[i],b[i]);
            chmax(ans,d+1);
        }
    }
    out(ans);
}

int main(){
    int t = 1; //in(t);
    while (t--) { solve(); }
}
accuracy: 0.1891891891891892
time_ms: 500
memory_kb: 61368
final_rank: 14

code_snippet: #line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"
using namespace std;

#include<bits/stdc++.h>
#line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp"
namespace noya2 {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
    os << p.first << " " << p.second;
    return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p){
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
    int s = (int)v.size();
    for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
    return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v){
    for (auto &x : v) is >> x;
    return is;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u){
    cin >> t;
    in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u){
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}

template<typename T>
void out(const vector<vector<T>> &vv){
    int s = (int)vv.size();
    for (int i = 0; i < s; i++) out(vv[i]);
}

struct IoSetup {
    IoSetup(){
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(7);
    }
} iosetup_noya2;

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp"
namespace noya2{

const int iinf = 1'000'000'007;
const long long linf = 2'000'000'000'000'000'000LL;
const long long mod998 =  998244353;
const long long mod107 = 1000000007;
const long double pi = 3.14159265358979323;
const vector<int> dx = {0,1,0,-1,1,1,-1,-1};
const vector<int> dy = {1,0,-1,0,1,-1,-1,1};
const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string alp = "abcdefghijklmnopqrstuvwxyz";
const string NUM = "0123456789";

void yes(){ cout << "Yes\n"; }
void no(){ cout << "No\n"; }
void YES(){ cout << "YES\n"; }
void NO(){ cout << "NO\n"; }
void yn(bool t){ t ? yes() : no(); }
void YN(bool t){ t ? YES() : NO(); }

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"
namespace noya2{

unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){
    if (a == 0 || b == 0) return a + b;
    int n = __builtin_ctzll(a); a >>= n;
    int m = __builtin_ctzll(b); b >>= m;
    while (a != b) {
        int mm = __builtin_ctzll(a - b);
        bool f = a > b;
        unsigned long long c = f ? a : b;
        b = f ? b : a;
        a = (c - b) >> mm;
    }
    return a << min(n, m);
}

template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(abs(a),abs(b))); }

long long sqrt_fast(long long n) {
    if (n <= 0) return 0;
    long long x = sqrt(n);
    while ((x + 1) * (x + 1) <= n) x++;
    while (x * x > n) x--;
    return x;
}

template<typename T> T floor_div(const T n, const T d) {
    assert(d != 0);
    return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0);
}

template<typename T> T ceil_div(const T n, const T d) {
    assert(d != 0);
    return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0);
}

template<typename T> void uniq(vector<T> &v){
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}

template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }

template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; }

} // namespace noya2
#line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"

#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define repp(i,m,n) for (int i = (m); i < (int)(n); i++)
#define reb(i,n) for (int i = (int)(n-1); i >= 0; i--)
#define all(v) (v).begin(),(v).end()

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pil = pair<int,ll>;
using pli = pair<ll,int>;

namespace noya2{

/*　~ (. _________ . /)　*/

}

using namespace noya2;


#line 2 "c.cpp"


#line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/compress.hpp"

#line 4 "/Users/noya2/Desktop/Noya2_library/data_structure/compress.hpp"

namespace noya2{

template<typename T> struct compress {
    vector<T> raws;
    compress(const vector<T> &raws_ = {}) : raws(raws_){ build(); }
    int id(const T &raw){ return lb(raw); }
    T raw(const int &id){ return raws[id]; }
    void build(){ uniq(raws); }
    void add(const T &raw){ raws.push_back(raw); }
    size_t size(){ return raws.size(); }
    int lb(const T &raw){ return lower_bound(all(raws),raw) - raws.begin(); }
    int ub(const T &raw){ return upper_bound(all(raws),raw) - raws.begin(); }
    bool contains(const T &raw){
        int jd = lb(raw);
        if (jd < (int)size()) return raws[jd] == raw;
        return false;
    }
    int contains_id(const T &raw){
        int jd = lb(raw);
        if (jd < (int)size() && raws[jd] == raw) return jd;
        return -1;
    }
};

} // namespace noya2
#line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/segment_tree.hpp"

namespace noya2{

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = 0;
        size = 1;
        while (size < _n) size <<= 1, log++;

        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

} // namespace noya2
#line 7 "c.cpp"


namespace noya2 {

template<class S, S(*op)(S, S), S(*e)(), typename Idx = ll>
struct range_tree {
    using DS = segtree<S,op,e>;
    using T = int;
    void join(Idx x, Idx y){ ps.emplace_back(x,y); }
    void build(){
        for (auto &[x, y] : ps) xs.add(x);
        xs.build();
        //siz = bit_ceil(xs.size());
        siz = 1; while (siz < (int)(xs.size())) siz <<= 1;
        ys.resize(siz*2);
        for (auto &[x, y] : ps){
            int xid = xs.id(x) + siz;
            ys[xid].add(y);
            while (xid > 1){
                xid >>= 1;
                ys[xid].add(y);
            }
        }
        for (int i = 0; i < 2*siz; i++){
            ys[i].build();
            ds.emplace_back(ys[i].size());
        }
    }
    void set(Idx p, Idx q, T val){
        int i = xs.id(p) + siz;
        ds[i].set(ys[i].id(q),val);
        while (i > 1){
            i >>= 1;
            T lr = e();
            int i0 = ys[2*i+0].contains_id(q), i1 = ys[2*i+1].contains_id(q);
            if (i0 != -1) lr = op(lr, ds[2*i+0].get(i0));
            if (i1 != -1) lr = op(lr, ds[2*i+1].get(i1));
            ds[i].set(ys[i].id(q),lr);
        }
    }
    T get(Idx p, Idx q){
        int ip = xs.contains_id(p);
        if (ip == -1) return e();
        int i = ip + siz;
        int iq = ys[i].contains_id(q);
        if (iq == -1) return e();
        return ds[i].get(iq);
    }
    T prod(Idx lp, Idx rp, Idx lq, Idx rq){
        T res = e();
        int li = xs.lb(lp), ri = xs.lb(rp);
        for (li += siz, ri += siz; li < ri; li >>= 1, ri >>= 1){
            if (li & 1) res = op(res,ds[li].prod(ys[li].lb(lq),ys[li].lb(rq))), ++li;
            if (ri & 1) --ri, res = op(res,ds[ri].prod(ys[ri].lb(lq),ys[ri].lb(rq)));
        }
        return res;
    }
    int siz;
    vector<pair<Idx,Idx>> ps;
    compress<Idx> xs;
    vector<compress<Idx>> ys;
    vector<DS> ds;
};

} // namespace noya2

int op(int a, int b){
    return max(a,b);
}
int e(){
    return -iinf;
}

void solve(){
    int n; in(n);
    vector<int> a(n), b(n);
    rep(i,n) in(a[i],b[i]);
    vector<int> ids(n); iota(all(ids),0);
    sort(all(ids),[&](int l, int r){
        return a[l]+b[l] < a[r]+b[r];
    });
    range_tree<int,op,e,int> rt0, rt1;
    rep(i,n){
        rep(tt,2){
            rt0.join(a[i],b[i]);
            rt1.join(a[i],b[i]);
            swap(a[i],b[i]);
        }
    }
    rt0.build();
    rt1.build();
    int ans = 1;
    for (int i : ids){
        // out(i,a[i],b[i]);
        rep(tt,2){
            int d0 = max(rt0.prod(0,a[i],0,b[i]),0);
            int d1 = max(rt1.prod(0,a[i],0,b[i]),0);
            rt1.set(a[i],b[i],d0+1);
            rt0.set(a[i],b[i],d1+1);
            swap(a[i],b[i]);
            chmax(ans,d0+1);
            chmax(ans,d1+1);
        }
    }
    out(ans);
}

int main(){
    int t = 1; //in(t);
    while (t--) { solve(); }
}
accuracy: 0.1891891891891892
time_ms: 1080
memory_kb: 120544
final_rank: 18

code_snippet: #include "bits/stdc++.h"
using namespace std;

#define REP(i, n) for(ll i = 0;i < n;i++)
#define REPR(i, n) for(ll i = n;i >= 0;i--)
#define FOR(i, m, n) for(ll i = m;i < n;i++)
#define FORR(i, m, n) for(ll i = m;i >= n;i--)
#define REPO(i, n) for(ll i = 1;i <= n;i++)
#define ll long long
#define INF (ll)1ll << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(),n.end()
#define MOD (ll)1000000007
#define P pair<ll, ll>

#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
using V = ll;
V comp(V& l, V& r) { return max(l, r); };
struct SegTree { //[l,r)
    int NV;
    vector<V> val;
    void init(int n) {
        NV = 1;
        while (NV < n) NV *= 2;
        val = vector<V>(NV * 2, 0);
    }
    V get(int x, int y, int l, int r, int k) {
        if (r <= x || y <= l) return 0;
        if (x <= l && r <= y) return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2); auto b = get(x, y, (l + r) / 2, r, k * 2 + 1); return comp(a, b);
    }
    V get(int x, int y) { return get(x, y, 0, NV, 1); }
    void update(int i, V v) { i += NV; val[i] = v; while (i>1)i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
 
struct Healthy2DSegTree {
    int NV;
    vector<SegTree> st;
    vector<vector<int>> index;
 
    void init(vector<vector<int>> &v) {
        int n = v.size();
        NV = 1; while (NV < n) NV *= 2;
        index.resize(2 * NV);
        rep(i, 0, n) fore(j, v[i]) index[i + NV].push_back(j);
        rrep(i, NV * 2 - 1, 1) {
            sort(index[i].begin(), index[i].end());
            index[i].erase(unique(index[i].begin(), index[i].end()), index[i].end());
            fore(j, index[i]) index[i / 2].push_back(j);
        }
        st.resize(2 * NV);
        rep(i, 1, NV * 2) st[i].init(index[i].size());
    }
    void update(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].update(yy, v);
            x >>= 1;
        }
    }
    void add(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].add(yy, v);
            x >>= 1;
        }
    }
    V get(int sx, int tx, int sy, int ty, int k, int l, int r) {
        assert(k < NV * 2);
        assert(l < r);
        if (r <= sx or tx <= l) return 0;
        if (sx <= l and r <= tx) {
            int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
            int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
            return st[k].get(syy, tyy);
        }
        int md = (l + r) / 2;
        V le = get(sx, tx, sy, ty, k * 2, l, md);
        V ri = get(sx, tx, sy, ty, k * 2 + 1, md, r);
        return comp(le, ri);
    }
    V get(int sx, int tx, int sy, int ty) {
        return get(sx, tx, sy, ty, 1, 0, NV);
    }
};

map<ll, ll> fr, to;
Healthy2DSegTree st;
vector<P> s, v;
ll n, ans;
int main(){
    cin >> n;
    vector<vector<int>> ind(310000);
    REP(i, n){
        ll a, b;
        cin >> a >> b;
        s.push_back(P(a, b));
    }
    sort(ALL(s));
    s.erase(unique(ALL(s)), s.end());
    n = s.size();
    REP(i, n){
        fr[s[i].first]++;
        fr[ s[i].second]++;
    }
    ll cnt = 0;
    for (auto& i : fr) {
        i.second = cnt;
        to[cnt] = i.first;
        cnt++;
    }
    REP(i, n){
        v.push_back(P(fr[s[i].first] + fr[s[i].second], i));
    }
    sort(ALL(v));
    REP(i, n){
        ind[fr[s[i].first]].push_back(fr[s[i].second]);
        ind[fr[s[i].second]].push_back(fr[s[i].first]);
    }
    st.init(ind);
    REP(i, n){
        //cout << s[v[i].second].first << " " << s[v[i].second].second << " " << fr[s[v[i].second].first] <<" " <<  fr[s[v[i].second].second] << " " << v[i].second << endl;
        ll x = st.get(0, fr[s[v[i].second].first], 0, fr[s[v[i].second].second]) + 1;
        ans = max(ans, x);
        st.add(fr[s[v[i].second].second], fr[s[v[i].second].first], x);
    }
    cout << ans << endl;
}
accuracy: 0.2972972972972973
time_ms: 690
memory_kb: 202276
final_rank: 9

code_snippet: #line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"
using namespace std;

#include<bits/stdc++.h>
#line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp"
namespace noya2 {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
    os << p.first << " " << p.second;
    return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p){
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
    int s = (int)v.size();
    for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
    return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v){
    for (auto &x : v) is >> x;
    return is;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u){
    cin >> t;
    in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u){
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}

template<typename T>
void out(const vector<vector<T>> &vv){
    int s = (int)vv.size();
    for (int i = 0; i < s; i++) out(vv[i]);
}

struct IoSetup {
    IoSetup(){
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(7);
    }
} iosetup_noya2;

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp"
namespace noya2{

const int iinf = 1'000'000'007;
const long long linf = 2'000'000'000'000'000'000LL;
const long long mod998 =  998244353;
const long long mod107 = 1000000007;
const long double pi = 3.14159265358979323;
const vector<int> dx = {0,1,0,-1,1,1,-1,-1};
const vector<int> dy = {1,0,-1,0,1,-1,-1,1};
const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string alp = "abcdefghijklmnopqrstuvwxyz";
const string NUM = "0123456789";

void yes(){ cout << "Yes\n"; }
void no(){ cout << "No\n"; }
void YES(){ cout << "YES\n"; }
void NO(){ cout << "NO\n"; }
void yn(bool t){ t ? yes() : no(); }
void YN(bool t){ t ? YES() : NO(); }

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"
namespace noya2{

unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){
    if (a == 0 || b == 0) return a + b;
    int n = __builtin_ctzll(a); a >>= n;
    int m = __builtin_ctzll(b); b >>= m;
    while (a != b) {
        int mm = __builtin_ctzll(a - b);
        bool f = a > b;
        unsigned long long c = f ? a : b;
        b = f ? b : a;
        a = (c - b) >> mm;
    }
    return a << min(n, m);
}

template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(abs(a),abs(b))); }

long long sqrt_fast(long long n) {
    if (n <= 0) return 0;
    long long x = sqrt(n);
    while ((x + 1) * (x + 1) <= n) x++;
    while (x * x > n) x--;
    return x;
}

template<typename T> T floor_div(const T n, const T d) {
    assert(d != 0);
    return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0);
}

template<typename T> T ceil_div(const T n, const T d) {
    assert(d != 0);
    return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0);
}

template<typename T> void uniq(vector<T> &v){
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}

template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }

template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; }

} // namespace noya2
#line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"

#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define repp(i,m,n) for (int i = (m); i < (int)(n); i++)
#define reb(i,n) for (int i = (int)(n-1); i >= 0; i--)
#define all(v) (v).begin(),(v).end()

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pil = pair<int,ll>;
using pli = pair<ll,int>;

namespace noya2{

/*　~ (. _________ . /)　*/

}

using namespace noya2;


#line 2 "c.cpp"


#line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/compress.hpp"

#line 4 "/Users/noya2/Desktop/Noya2_library/data_structure/compress.hpp"

namespace noya2{

template<typename T> struct compress {
    vector<T> raws;
    compress(const vector<T> &raws_ = {}) : raws(raws_){ build(); }
    int id(const T &raw){ return lb(raw); }
    T raw(const int &id){ return raws[id]; }
    void build(){ uniq(raws); }
    void add(const T &raw){ raws.push_back(raw); }
    size_t size(){ return raws.size(); }
    int lb(const T &raw){ return lower_bound(all(raws),raw) - raws.begin(); }
    int ub(const T &raw){ return upper_bound(all(raws),raw) - raws.begin(); }
    bool contains(const T &raw){
        int jd = lb(raw);
        if (jd < (int)size()) return raws[jd] == raw;
        return false;
    }
    int contains_id(const T &raw){
        int jd = lb(raw);
        if (jd < (int)size() && raws[jd] == raw) return jd;
        return -1;
    }
};

} // namespace noya2
#line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/segment_tree.hpp"

namespace noya2{

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = 0;
        size = 1;
        while (size < _n) size <<= 1, log++;

        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

} // namespace noya2
#line 7 "c.cpp"


namespace noya2 {

template<class S, S(*op)(S, S), S(*e)(), typename Idx = ll>
struct range_tree {
    using DS = segtree<S,op,e>;
    using T = int;
    void join(Idx x, Idx y){ ps.emplace_back(x,y); }
    void build(){
        for (auto &[x, y] : ps) xs.add(x);
        xs.build();
        //siz = bit_ceil(xs.size());
        siz = 1; while (siz < (int)(xs.size())) siz <<= 1;
        ys.resize(siz*2);
        for (auto &[x, y] : ps){
            int xid = xs.id(x) + siz;
            ys[xid].add(y);
            while (xid > 1){
                xid >>= 1;
                ys[xid].add(y);
            }
        }
        for (int i = 0; i < 2*siz; i++){
            ys[i].build();
            ds.emplace_back(ys[i].size());
        }
    }
    void set(Idx p, Idx q, T val){
        int i = xs.id(p) + siz;
        ds[i].set(ys[i].id(q),val);
        while (i > 1){
            i >>= 1;
            T lr = e();
            int i0 = ys[2*i+0].contains_id(q), i1 = ys[2*i+1].contains_id(q);
            if (i0 != -1) lr = op(lr, ds[2*i+0].get(i0));
            if (i1 != -1) lr = op(lr, ds[2*i+1].get(i1));
            ds[i].set(ys[i].id(q),lr);
        }
    }
    T get(Idx p, Idx q){
        int ip = xs.contains_id(p);
        if (ip == -1) return e();
        int i = ip + siz;
        int iq = ys[i].contains_id(q);
        if (iq == -1) return e();
        return ds[i].get(iq);
    }
    T prod(Idx lp, Idx rp, Idx lq, Idx rq){
        T res = e();
        int li = xs.lb(lp), ri = xs.lb(rp);
        for (li += siz, ri += siz; li < ri; li >>= 1, ri >>= 1){
            if (li & 1) res = op(res,ds[li].prod(ys[li].lb(lq),ys[li].lb(rq))), ++li;
            if (ri & 1) --ri, res = op(res,ds[ri].prod(ys[ri].lb(lq),ys[ri].lb(rq)));
        }
        return res;
    }
    int siz;
    vector<pair<Idx,Idx>> ps;
    compress<Idx> xs;
    vector<compress<Idx>> ys;
    vector<DS> ds;
};

} // namespace noya2

int op(int a, int b){
    return max(a,b);
}
int e(){
    return -iinf;
}

void solve(){
    int n; in(n);
    vector<int> a(n), b(n);
    rep(i,n) in(a[i],b[i]);
    vector<int> ids(n); iota(all(ids),0);
    sort(all(ids),[&](int l, int r){
        return a[l]+b[l] < a[r]+b[r];
    });
    range_tree<int,op,e,int> rt0, rt1;
    rep(i,n){
        rep(tt,2){
            rt0.join(a[i],b[i]);
            rt1.join(a[i],b[i]);
            swap(a[i],b[i]);
        }
    }
    rt0.build();
    rt1.build();
    int ans = 1;
    for (int i : ids){
        // out(i,a[i],b[i]);
        rep(tt,2){
            int d0 = max(rt0.prod(0,a[i],0,b[i]),0);
            rt1.set(a[i],b[i],d0+1);
            int d1 = max(rt1.prod(0,a[i],0,b[i]),0);
            rt0.set(a[i],b[i],d1+1);
            swap(a[i],b[i]);
            chmax(ans,d0+1);
            chmax(ans,d1+1);
        }
    }
    out(ans);
}

int main(){
    int t = 1; //in(t);
    while (t--) { solve(); }
}
accuracy: 0.1891891891891892
time_ms: 1150
memory_kb: 120436
final_rank: 20

code_snippet: #line 2 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"
using namespace std;

#include<bits/stdc++.h>
#line 1 "/Users/noya2/Desktop/Noya2_library/template/inout_old.hpp"
namespace noya2 {

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p){
    os << p.first << " " << p.second;
    return os;
}
template <typename T, typename U>
istream &operator>>(istream &is, pair<T, U> &p){
    is >> p.first >> p.second;
    return is;
}

template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v){
    int s = (int)v.size();
    for (int i = 0; i < s; i++) os << (i ? " " : "") << v[i];
    return os;
}
template <typename T>
istream &operator>>(istream &is, vector<T> &v){
    for (auto &x : v) is >> x;
    return is;
}

void in() {}
template <typename T, class... U>
void in(T &t, U &...u){
    cin >> t;
    in(u...);
}

void out() { cout << "\n"; }
template <typename T, class... U, char sep = ' '>
void out(const T &t, const U &...u){
    cout << t;
    if (sizeof...(u)) cout << sep;
    out(u...);
}

template<typename T>
void out(const vector<vector<T>> &vv){
    int s = (int)vv.size();
    for (int i = 0; i < s; i++) out(vv[i]);
}

struct IoSetup {
    IoSetup(){
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
        cout << fixed << setprecision(15);
        cerr << fixed << setprecision(7);
    }
} iosetup_noya2;

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/const.hpp"
namespace noya2{

const int iinf = 1'000'000'007;
const long long linf = 2'000'000'000'000'000'000LL;
const long long mod998 =  998244353;
const long long mod107 = 1000000007;
const long double pi = 3.14159265358979323;
const vector<int> dx = {0,1,0,-1,1,1,-1,-1};
const vector<int> dy = {1,0,-1,0,1,-1,-1,1};
const string ALP = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const string alp = "abcdefghijklmnopqrstuvwxyz";
const string NUM = "0123456789";

void yes(){ cout << "Yes\n"; }
void no(){ cout << "No\n"; }
void YES(){ cout << "YES\n"; }
void NO(){ cout << "NO\n"; }
void yn(bool t){ t ? yes() : no(); }
void YN(bool t){ t ? YES() : NO(); }

} // namespace noya2
#line 1 "/Users/noya2/Desktop/Noya2_library/template/utils.hpp"
namespace noya2{

unsigned long long inner_binary_gcd(unsigned long long a, unsigned long long b){
    if (a == 0 || b == 0) return a + b;
    int n = __builtin_ctzll(a); a >>= n;
    int m = __builtin_ctzll(b); b >>= m;
    while (a != b) {
        int mm = __builtin_ctzll(a - b);
        bool f = a > b;
        unsigned long long c = f ? a : b;
        b = f ? b : a;
        a = (c - b) >> mm;
    }
    return a << min(n, m);
}

template<typename T> T gcd_fast(T a, T b){ return static_cast<T>(inner_binary_gcd(abs(a),abs(b))); }

long long sqrt_fast(long long n) {
    if (n <= 0) return 0;
    long long x = sqrt(n);
    while ((x + 1) * (x + 1) <= n) x++;
    while (x * x > n) x--;
    return x;
}

template<typename T> T floor_div(const T n, const T d) {
    assert(d != 0);
    return n / d - static_cast<T>((n ^ d) < 0 && n % d != 0);
}

template<typename T> T ceil_div(const T n, const T d) {
    assert(d != 0);
    return n / d + static_cast<T>((n ^ d) >= 0 && n % d != 0);
}

template<typename T> void uniq(vector<T> &v){
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
}

template <typename T, typename U> inline bool chmin(T &x, U y) { return (y < x) ? (x = y, true) : false; }

template <typename T, typename U> inline bool chmax(T &x, U y) { return (x < y) ? (x = y, true) : false; }

template<typename T> inline bool range(T l, T x, T r){ return l <= x && x < r; }

} // namespace noya2
#line 8 "/Users/noya2/Desktop/Noya2_library/template/template.hpp"

#define rep(i,n) for (int i = 0; i < (int)(n); i++)
#define repp(i,m,n) for (int i = (m); i < (int)(n); i++)
#define reb(i,n) for (int i = (int)(n-1); i >= 0; i--)
#define all(v) (v).begin(),(v).end()

using ll = long long;
using ld = long double;
using uint = unsigned int;
using ull = unsigned long long;
using pii = pair<int,int>;
using pll = pair<ll,ll>;
using pil = pair<int,ll>;
using pli = pair<ll,int>;

namespace noya2{

/*　~ (. _________ . /)　*/

}

using namespace noya2;


#line 2 "c.cpp"


#line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/compress.hpp"

#line 4 "/Users/noya2/Desktop/Noya2_library/data_structure/compress.hpp"

namespace noya2{

template<typename T> struct compress {
    vector<T> raws;
    compress(const vector<T> &raws_ = {}) : raws(raws_){ build(); }
    int id(const T &raw){ return lb(raw); }
    T raw(const int &id){ return raws[id]; }
    void build(){ uniq(raws); }
    void add(const T &raw){ raws.push_back(raw); }
    size_t size(){ return raws.size(); }
    int lb(const T &raw){ return lower_bound(all(raws),raw) - raws.begin(); }
    int ub(const T &raw){ return upper_bound(all(raws),raw) - raws.begin(); }
    bool contains(const T &raw){
        int jd = lb(raw);
        if (jd < (int)size()) return raws[jd] == raw;
        return false;
    }
    int contains_id(const T &raw){
        int jd = lb(raw);
        if (jd < (int)size() && raws[jd] == raw) return jd;
        return -1;
    }
};

} // namespace noya2
#line 2 "/Users/noya2/Desktop/Noya2_library/data_structure/segment_tree.hpp"

namespace noya2{

template <class S, S (*op)(S, S), S (*e)()> struct segtree {
  public:
    segtree() : segtree(0) {}
    segtree(int n) : segtree(std::vector<S>(n, e())) {}
    segtree(const std::vector<S>& v) : _n(int(v.size())) {
        log = 0;
        size = 1;
        while (size < _n) size <<= 1, log++;

        d = std::vector<S>(2 * size, e());
        for (int i = 0; i < _n; i++) d[size + i] = v[i];
        for (int i = size - 1; i >= 1; i--) {
            update(i);
        }
    }

    void set(int p, S x) {
        assert(0 <= p && p < _n);
        p += size;
        d[p] = x;
        for (int i = 1; i <= log; i++) update(p >> i);
    }

    S get(int p) {
        assert(0 <= p && p < _n);
        return d[p + size];
    }

    S prod(int l, int r) {
        assert(0 <= l && l <= r && r <= _n);
        S sml = e(), smr = e();
        l += size;
        r += size;

        while (l < r) {
            if (l & 1) sml = op(sml, d[l++]);
            if (r & 1) smr = op(d[--r], smr);
            l >>= 1;
            r >>= 1;
        }
        return op(sml, smr);
    }

    S all_prod() { return d[1]; }

    template <bool (*f)(S)> int max_right(int l) {
        return max_right(l, [](S x) { return f(x); });
    }
    template <class F> int max_right(int l, F f) {
        assert(0 <= l && l <= _n);
        assert(f(e()));
        if (l == _n) return _n;
        l += size;
        S sm = e();
        do {
            while (l % 2 == 0) l >>= 1;
            if (!f(op(sm, d[l]))) {
                while (l < size) {
                    l = (2 * l);
                    if (f(op(sm, d[l]))) {
                        sm = op(sm, d[l]);
                        l++;
                    }
                }
                return l - size;
            }
            sm = op(sm, d[l]);
            l++;
        } while ((l & -l) != l);
        return _n;
    }

    template <bool (*f)(S)> int min_left(int r) {
        return min_left(r, [](S x) { return f(x); });
    }
    template <class F> int min_left(int r, F f) {
        assert(0 <= r && r <= _n);
        assert(f(e()));
        if (r == 0) return 0;
        r += size;
        S sm = e();
        do {
            r--;
            while (r > 1 && (r % 2)) r >>= 1;
            if (!f(op(d[r], sm))) {
                while (r < size) {
                    r = (2 * r + 1);
                    if (f(op(d[r], sm))) {
                        sm = op(d[r], sm);
                        r--;
                    }
                }
                return r + 1 - size;
            }
            sm = op(d[r], sm);
        } while ((r & -r) != r);
        return 0;
    }

  private:
    int _n, size, log;
    std::vector<S> d;

    void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }
};

} // namespace noya2
#line 7 "c.cpp"


namespace noya2 {

template<class S, S(*op)(S, S), S(*e)(), typename Idx = ll>
struct range_tree {
    using DS = segtree<S,op,e>;
    using T = int;
    void join(Idx x, Idx y){ ps.emplace_back(x,y); }
    void build(){
        for (auto &[x, y] : ps) xs.add(x);
        xs.build();
        //siz = bit_ceil(xs.size());
        siz = 1; while (siz < (int)(xs.size())) siz <<= 1;
        ys.resize(siz*2);
        for (auto &[x, y] : ps){
            int xid = xs.id(x) + siz;
            ys[xid].add(y);
            while (xid > 1){
                xid >>= 1;
                ys[xid].add(y);
            }
        }
        for (int i = 0; i < 2*siz; i++){
            ys[i].build();
            ds.emplace_back(ys[i].size());
        }
    }
    void set(Idx p, Idx q, T val){
        int i = xs.id(p) + siz;
        ds[i].set(ys[i].id(q),val);
        while (i > 1){
            i >>= 1;
            T lr = e();
            int i0 = ys[2*i+0].contains_id(q), i1 = ys[2*i+1].contains_id(q);
            if (i0 != -1) lr = op(lr, ds[2*i+0].get(i0));
            if (i1 != -1) lr = op(lr, ds[2*i+1].get(i1));
            ds[i].set(ys[i].id(q),lr);
        }
    }
    T get(Idx p, Idx q){
        int ip = xs.contains_id(p);
        if (ip == -1) return e();
        int i = ip + siz;
        int iq = ys[i].contains_id(q);
        if (iq == -1) return e();
        return ds[i].get(iq);
    }
    T prod(Idx lp, Idx rp, Idx lq, Idx rq){
        T res = e();
        int li = xs.lb(lp), ri = xs.lb(rp);
        for (li += siz, ri += siz; li < ri; li >>= 1, ri >>= 1){
            if (li & 1) res = op(res,ds[li].prod(ys[li].lb(lq),ys[li].lb(rq))), ++li;
            if (ri & 1) --ri, res = op(res,ds[ri].prod(ys[ri].lb(lq),ys[ri].lb(rq)));
        }
        return res;
    }
    int siz;
    vector<pair<Idx,Idx>> ps;
    compress<Idx> xs;
    vector<compress<Idx>> ys;
    vector<DS> ds;
};

} // namespace noya2

int op(int a, int b){
    return max(a,b);
}
int e(){
    return -iinf;
}

void solve(){
    int n; in(n);
    vector<int> a(n), b(n);
    rep(i,n) in(a[i],b[i]);
    vector<int> ids(n); iota(all(ids),0);
    sort(all(ids),[&](int l, int r){
        return a[l]+b[l] < a[r]+b[r];
    });
    range_tree<int,op,e,int> rt0, rt1;
    rep(i,n){
        rep(tt,2){
            rt0.join(a[i],b[i]);
            rt1.join(a[i],b[i]);
            swap(a[i],b[i]);
        }
    }
    rt0.build();
    rt1.build();
    int ans = 1;
    for (int i : ids){
        // out(i,a[i],b[i]);
        rep(tt,2){
            int d0 = max(rt0.prod(0,a[i],0,b[i]),0);
            rt1.set(a[i],b[i],d0+1);
            int d1 = max(rt1.prod(0,a[i],0,b[i]),-1);
            rt0.set(a[i],b[i],d1+1);
            swap(a[i],b[i]);
            chmax(ans,d0+1);
            chmax(ans,d1+1);
        }
    }
    out(ans);
}

int main(){
    int t = 1; //in(t);
    while (t--) { solve(); }
}
accuracy: 0.1891891891891892
time_ms: 1140
memory_kb: 120352
final_rank: 19

code_snippet: #include "bits/stdc++.h"
using namespace std;

#define REP(i, n) for(ll i = 0;i < n;i++)
#define REPR(i, n) for(ll i = n;i >= 0;i--)
#define FOR(i, m, n) for(ll i = m;i < n;i++)
#define FORR(i, m, n) for(ll i = m;i >= n;i--)
#define REPO(i, n) for(ll i = 1;i <= n;i++)
#define ll long long
#define INF (ll)1ll << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(),n.end()
#define MOD (ll)1000000007
#define P pair<ll, ll>

#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
using V = ll;
V comp(V& l, V& r) { return max(l, r); };
struct SegTree { //[l,r)
    int NV;
    vector<V> val;
    void init(int n) {
        NV = 1;
        while (NV < n) NV *= 2;
        val = vector<V>(NV * 2, 0);
    }
    V get(int x, int y, int l, int r, int k) {
        if (r <= x || y <= l) return 0;
        if (x <= l && r <= y) return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2); auto b = get(x, y, (l + r) / 2, r, k * 2 + 1); return comp(a, b);
    }
    V get(int x, int y) { return get(x, y, 0, NV, 1); }
    void update(int i, V v) { i += NV; val[i] = v; while (i>1)i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
 
struct Healthy2DSegTree {
    int NV;
    vector<SegTree> st;
    vector<vector<int>> index;
 
    void init(vector<vector<int>> &v) {
        int n = v.size();
        NV = 1; while (NV < n) NV *= 2;
        index.resize(2 * NV);
        rep(i, 0, n) fore(j, v[i]) index[i + NV].push_back(j);
        rrep(i, NV * 2 - 1, 1) {
            sort(index[i].begin(), index[i].end());
            index[i].erase(unique(index[i].begin(), index[i].end()), index[i].end());
            fore(j, index[i]) index[i / 2].push_back(j);
        }
        st.resize(2 * NV);
        rep(i, 1, NV * 2) st[i].init(index[i].size());
    }
    void update(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].update(yy, v);
            x >>= 1;
        }
    }
    void add(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].add(yy, v);
            x >>= 1;
        }
    }
    V get(int sx, int tx, int sy, int ty, int k, int l, int r) {
        assert(k < NV * 2);
        assert(l < r);
        if (r <= sx or tx <= l) return 0;
        if (sx <= l and r <= tx) {
            int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
            int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
            return st[k].get(syy, tyy);
        }
        int md = (l + r) / 2;
        V le = get(sx, tx, sy, ty, k * 2, l, md);
        V ri = get(sx, tx, sy, ty, k * 2 + 1, md, r);
        return comp(le, ri);
    }
    V get(int sx, int tx, int sy, int ty) {
        return get(sx, tx, sy, ty, 1, 0, NV);
    }
};

map<ll, ll> fr, to;
Healthy2DSegTree st;
vector<P> s, v;
ll n, ans;
int main(){
    cin >> n;
    vector<vector<int>> ind(310000);
    REP(i, n){
        ll a, b;
        cin >> a >> b;
        s.push_back(P(a, b));
    }
    sort(ALL(s));
    s.erase(unique(ALL(s)), s.end());
    n = s.size();
    REP(i, n){

        v.push_back(P(s[i].first + s[i].second, i));
        fr[s[i].first]++;
        fr[ s[i].second]++;
    }
    ll cnt = 0;
    for (auto& i : fr) {
        i.second = cnt;
        to[cnt] = i.first;
        cnt++;
    }
    sort(ALL(v));
    REP(i, n){
        ind[fr[s[i].first]].push_back(fr[s[i].second]);
        ind[fr[s[i].second]].push_back(fr[s[i].first]);
    }
    st.init(ind);
    REP(i, n){
        //cout << s[v[i].second].first << " " << s[v[i].second].second << " " << fr[s[v[i].second].first] <<" " <<  fr[s[v[i].second].second] << " " << v[i].second << endl;
        ll x = st.get(0, fr[s[v[i].second].first], 0, fr[s[v[i].second].second]) + 1;
        ans = max(ans, x);
        st.add(fr[s[v[i].second].second], fr[s[v[i].second].first], x);
    }
    cout << ans << endl;
}
accuracy: 0.2972972972972973
time_ms: 680
memory_kb: 201916
final_rank: 8

code_snippet: #include "bits/stdc++.h"
using namespace std;

#define REP(i, n) for(ll i = 0;i < n;i++)
#define REPR(i, n) for(ll i = n;i >= 0;i--)
#define FOR(i, m, n) for(ll i = m;i < n;i++)
#define FORR(i, m, n) for(ll i = m;i >= n;i--)
#define REPO(i, n) for(ll i = 1;i <= n;i++)
#define ll long long
#define INF (ll)1ll << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(),n.end()
#define MOD (ll)1000000007
#define P pair<ll, ll>

#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
using V = ll;
V comp(V& l, V& r) { return max(l, r); };
struct SegTree { //[l,r)
    int NV;
    vector<V> val;
    void init(int n) {
        NV = 1;
        while (NV < n) NV *= 2;
        val = vector<V>(NV * 2, 0);
    }
    V get(int x, int y, int l, int r, int k) {
        if (r <= x || y <= l) return 0;
        if (x <= l && r <= y) return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2); auto b = get(x, y, (l + r) / 2, r, k * 2 + 1); return comp(a, b);
    }
    V get(int x, int y) { return get(x, y, 0, NV, 1); }
    void update(int i, V v) { i += NV; val[i] = v; while (i>1)i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
 
struct Healthy2DSegTree {
    int NV;
    vector<SegTree> st;
    vector<vector<int>> index;
 
    void init(vector<vector<int>> &v) {
        int n = v.size();
        NV = 1; while (NV < n) NV *= 2;
        index.resize(2 * NV);
        rep(i, 0, n) fore(j, v[i]) index[i + NV].push_back(j);
        rrep(i, NV * 2 - 1, 1) {
            sort(index[i].begin(), index[i].end());
            index[i].erase(unique(index[i].begin(), index[i].end()), index[i].end());
            fore(j, index[i]) index[i / 2].push_back(j);
        }
        st.resize(2 * NV);
        rep(i, 1, NV * 2) st[i].init(index[i].size());
    }
    void update(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].update(yy, v);
            x >>= 1;
        }
    }
    void add(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].add(yy, v);
            x >>= 1;
        }
    }
    V get(int sx, int tx, int sy, int ty, int k, int l, int r) {
        assert(k < NV * 2);
        assert(l < r);
        if (r <= sx or tx <= l) return 0;
        if (sx <= l and r <= tx) {
            int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
            int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
            return st[k].get(syy, tyy);
        }
        int md = (l + r) / 2;
        V le = get(sx, tx, sy, ty, k * 2, l, md);
        V ri = get(sx, tx, sy, ty, k * 2 + 1, md, r);
        return comp(le, ri);
    }
    V get(int sx, int tx, int sy, int ty) {
        return get(sx, tx, sy, ty, 1, 0, NV);
    }
};

map<ll, ll> fr, to;
Healthy2DSegTree st;
vector<P> s, v;
ll n, ans;
int main(){
    cin >> n;
    vector<vector<int>> ind(310000);
    REP(i, n){
        ll a, b;
        cin >> a >> b;
        s.push_back(P(a, b));
    }
    sort(ALL(s));
    s.erase(unique(ALL(s)), s.end());
    n = s.size();
    REP(i, n){

        v.push_back(P(s[i].first + s[i].second, i));
        fr[s[i].first]++;
        fr[ s[i].second]++;
    }
    fr[0]++;
    ll cnt = 0;
    for (auto& i : fr) {
        i.second = cnt;
        to[cnt] = i.first;
        cnt++;
    }
    sort(ALL(v));
    REP(i, n){
        ind[fr[s[i].first]].push_back(fr[s[i].second]);
        ind[fr[s[i].second]].push_back(fr[s[i].first]);
    }
    st.init(ind);
    REP(i, n){
        //cout << s[v[i].second].first << " " << s[v[i].second].second << " " << fr[s[v[i].second].first] <<" " <<  fr[s[v[i].second].second] << " " << v[i].second << endl;
        ll x = st.get(0, fr[s[v[i].second].first], 0, fr[s[v[i].second].second]) + 1;
        ans = max(ans, x);
        st.add(fr[s[v[i].second].second], fr[s[v[i].second].first], x);
    }
    cout << ans << endl;
}
accuracy: 0.1891891891891892
time_ms: 360
memory_kb: 162168
final_rank: 15

code_snippet: #include "bits/stdc++.h"
using namespace std;

#define REP(i, n) for(ll i = 0;i < n;i++)
#define REPR(i, n) for(ll i = n;i >= 0;i--)
#define FOR(i, m, n) for(ll i = m;i < n;i++)
#define FORR(i, m, n) for(ll i = m;i >= n;i--)
#define REPO(i, n) for(ll i = 1;i <= n;i++)
#define ll long long
#define INF (ll)1ll << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(),n.end()
#define MOD (ll)1000000007
#define P pair<ll, ll>

#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
using V = ll;
V comp(V& l, V& r) { return max(l, r); };
struct SegTree { //[l,r)
    int NV;
    vector<V> val;
    void init(int n) {
        NV = 1;
        while (NV < n) NV *= 2;
        val = vector<V>(NV * 2, 0);
    }
    V get(int x, int y, int l, int r, int k) {
        if (r <= x || y <= l) return 0;
        if (x <= l && r <= y) return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2); auto b = get(x, y, (l + r) / 2, r, k * 2 + 1); return comp(a, b);
    }
    V get(int x, int y) { return get(x, y, 0, NV, 1); }
    void update(int i, V v) { i += NV; val[i] = v; while (i>1)i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
 
struct Healthy2DSegTree {
    int NV;
    vector<SegTree> st;
    vector<vector<int>> index;
 
    void init(vector<vector<int>> &v) {
        int n = v.size();
        NV = 1; while (NV < n) NV *= 2;
        index.resize(2 * NV);
        rep(i, 0, n) fore(j, v[i]) index[i + NV].push_back(j);
        rrep(i, NV * 2 - 1, 1) {
            sort(index[i].begin(), index[i].end());
            index[i].erase(unique(index[i].begin(), index[i].end()), index[i].end());
            fore(j, index[i]) index[i / 2].push_back(j);
        }
        st.resize(2 * NV);
        rep(i, 1, NV * 2) st[i].init(index[i].size());
    }
    void update(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].update(yy, v);
            x >>= 1;
        }
    }
    void add(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].add(yy, v);
            x >>= 1;
        }
    }
    V get(int sx, int tx, int sy, int ty, int k, int l, int r) {
        assert(k < NV * 2);
        assert(l < r);
        if (r <= sx or tx <= l) return 0;
        if (sx <= l and r <= tx) {
            int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
            int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
            return st[k].get(syy, tyy);
        }
        int md = (l + r) / 2;
        V le = get(sx, tx, sy, ty, k * 2, l, md);
        V ri = get(sx, tx, sy, ty, k * 2 + 1, md, r);
        return comp(le, ri);
    }
    V get(int sx, int tx, int sy, int ty) {
        return get(sx, tx, sy, ty, 1, 0, NV);
    }
};

map<ll, ll> fr, to;
Healthy2DSegTree st;
vector<P> s, v;
ll n, ans;
int main(){
    cin >> n;
    vector<vector<int>> ind(310000);
    REP(i, n){
        ll a, b;
        cin >> a >> b;
        s.push_back(P(a, b));
        v.push_back(P(a + b, i));
        fr[a]++;
        fr[b]++;
    }
    ll cnt = 1;
    for (auto& i : fr) {
        i.second = cnt;
        to[cnt] = i.first;
        cnt++;
    }
    sort(ALL(v));
    REP(i, n){
        ind[fr[s[i].first]].push_back(fr[s[i].second]);
        ind[fr[s[i].second]].push_back(fr[s[i].first]);
    }
    st.init(ind);
    REP(i, n){
        //cout << s[v[i].second].first << " " << s[v[i].second].second << " " << fr[s[v[i].second].first] <<" " <<  fr[s[v[i].second].second] << " " << v[i].second << endl;
        ll x = st.get(0, fr[s[v[i].second].first], 0, fr[s[v[i].second].second]) + 1;
        ans = max(ans, x);
        st.add(fr[s[v[i].second].second], fr[s[v[i].second].first], x);
    }
    cout << ans << endl;
}
accuracy: 0.1891891891891892
time_ms: 380
memory_kb: 162136
final_rank: 16

code_snippet: #include "bits/stdc++.h"
using namespace std;

#define REP(i, n) for(ll i = 0;i < n;i++)
#define REPR(i, n) for(ll i = n;i >= 0;i--)
#define FOR(i, m, n) for(ll i = m;i < n;i++)
#define FORR(i, m, n) for(ll i = m;i >= n;i--)
#define REPO(i, n) for(ll i = 1;i <= n;i++)
#define ll long long
#define INF (ll)1ll << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(),n.end()
#define MOD (ll)1000000007
#define P pair<ll, ll>

#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
using V = ll;
V comp(V& l, V& r) { return max(l, r); };
struct SegTree { //[l,r)
    int NV;
    vector<V> val;
    void init(int n) {
        NV = 1;
        while (NV < n) NV *= 2;
        val = vector<V>(NV * 2, 0);
    }
    V get(int x, int y, int l, int r, int k) {
        if (r <= x || y <= l) return 0;
        if (x <= l && r <= y) return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2); auto b = get(x, y, (l + r) / 2, r, k * 2 + 1); return comp(a, b);
    }
    V get(int x, int y) { return get(x, y, 0, NV, 1); }
    void update(int i, V v) { i += NV; val[i] = v; while (i>1)i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
 
struct Healthy2DSegTree {
    int NV;
    vector<SegTree> st;
    vector<vector<int>> index;
 
    void init(vector<vector<int>> &v) {
        int n = v.size();
        NV = 1; while (NV < n) NV *= 2;
        index.resize(2 * NV);
        rep(i, 0, n) fore(j, v[i]) index[i + NV].push_back(j);
        rrep(i, NV * 2 - 1, 1) {
            sort(index[i].begin(), index[i].end());
            index[i].erase(unique(index[i].begin(), index[i].end()), index[i].end());
            fore(j, index[i]) index[i / 2].push_back(j);
        }
        st.resize(2 * NV);
        rep(i, 1, NV * 2) st[i].init(index[i].size());
    }
    void update(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].update(yy, v);
            x >>= 1;
        }
    }
    void add(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].add(yy, v);
            x >>= 1;
        }
    }
    V get(int sx, int tx, int sy, int ty, int k, int l, int r) {
        assert(k < NV * 2);
        assert(l < r);
        if (r <= sx or tx <= l) return 0;
        if (sx <= l and r <= tx) {
            int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
            int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
            return st[k].get(syy, tyy);
        }
        int md = (l + r) / 2;
        V le = get(sx, tx, sy, ty, k * 2, l, md);
        V ri = get(sx, tx, sy, ty, k * 2 + 1, md, r);
        return comp(le, ri);
    }
    V get(int sx, int tx, int sy, int ty) {
        return get(sx, tx, sy, ty, 1, 0, NV);
    }
};

map<ll, ll> fr, to;
Healthy2DSegTree st;
vector<P> s, v;
ll n, ans;
int main(){
    cin >> n;
    vector<vector<int>> ind(410000);
    REP(i, n){
        ll a, b;
        cin >> a >> b;
        s.push_back(P(a, b));
        v.push_back(P(a + b, i));
        fr[a]++;
        fr[b]++;
    }
    ll cnt = 1;
    for (auto& i : fr) {
        i.second = cnt;
        to[cnt] = i.first;
        cnt++;
    }
    sort(ALL(v));
    REP(i, n){
        ind[fr[s[i].first]].push_back(fr[s[i].second]);
        ind[fr[s[i].second]].push_back(fr[s[i].first]);
    }
    st.init(ind);
    REP(i, n){
        //cout << s[v[i].second].first << " " << s[v[i].second].second << " " << fr[s[v[i].second].first] <<" " <<  fr[s[v[i].second].second] << " " << v[i].second << endl;
        ll x = st.get(0, fr[s[v[i].second].first], 0, fr[s[v[i].second].second]) + 1;
        ans = max(ans, x);
        st.add(fr[s[v[i].second].second], fr[s[v[i].second].first], x);
    }
    cout << ans << endl;
}
accuracy: 0.1891891891891892
time_ms: 370
memory_kb: 164508
final_rank: 17

code_snippet: #include "bits/stdc++.h"
using namespace std;

#define REP(i, n) for(ll i = 0;i < n;i++)
#define REPR(i, n) for(ll i = n;i >= 0;i--)
#define FOR(i, m, n) for(ll i = m;i < n;i++)
#define FORR(i, m, n) for(ll i = m;i >= n;i--)
#define REPO(i, n) for(ll i = 1;i <= n;i++)
#define ll long long
#define INF (ll)1ll << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(),n.end()
#define MOD (ll)1000000007
#define P pair<ll, ll>

#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
using V = ll;
V comp(V& l, V& r) { return max(l, r); };
struct SegTree { //[l,r)
    int NV;
    vector<V> val;
    void init(int n) {
        NV = 1;
        while (NV < n) NV *= 2;
        val = vector<V>(NV * 2, 0);
    }
    V get(int x, int y, int l, int r, int k) {
        if (r <= x || y <= l) return 0;
        if (x <= l && r <= y) return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2); auto b = get(x, y, (l + r) / 2, r, k * 2 + 1); return comp(a, b);
    }
    V get(int x, int y) { return get(x, y, 0, NV, 1); }
    void update(int i, V v) { i += NV; val[i] = v; while (i>1)i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
 
struct Healthy2DSegTree {
    int NV;
    vector<SegTree> st;
    vector<vector<int>> index;
 
    void init(vector<vector<int>> &v) {
        int n = v.size();
        NV = 1; while (NV < n) NV *= 2;
        index.resize(2 * NV);
        rep(i, 0, n) fore(j, v[i]) index[i + NV].push_back(j);
        rrep(i, NV * 2 - 1, 1) {
            sort(index[i].begin(), index[i].end());
            index[i].erase(unique(index[i].begin(), index[i].end()), index[i].end());
            fore(j, index[i]) index[i / 2].push_back(j);
        }
        st.resize(2 * NV);
        rep(i, 1, NV * 2) st[i].init(index[i].size());
    }
    void update(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].update(yy, v);
            x >>= 1;
        }
    }
    void add(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].add(yy, v);
            x >>= 1;
        }
    }
    V get(int sx, int tx, int sy, int ty, int k, int l, int r) {
        assert(k < NV * 2);
        assert(l < r);
        if (r <= sx or tx <= l) return 0;
        if (sx <= l and r <= tx) {
            int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
            int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
            return st[k].get(syy, tyy);
        }
        int md = (l + r) / 2;
        V le = get(sx, tx, sy, ty, k * 2, l, md);
        V ri = get(sx, tx, sy, ty, k * 2 + 1, md, r);
        return comp(le, ri);
    }
    V get(int sx, int tx, int sy, int ty) {
        return get(sx, tx, sy, ty, 1, 0, NV);
    }
};

map<ll, ll> fr, to;
Healthy2DSegTree st;
vector<P> s, v;
ll n, ans;
int main(){
    cin >> n;
    vector<vector<int>> ind(310000);
    REP(i, n){
        ll a, b;
        cin >> a >> b;
        s.push_back(P(a, b));
        v.push_back(P(a + b, i));
        fr[a]++;
        fr[b]++;
    }
    ll cnt = 0;
    for (auto& i : fr) {
        i.second = cnt;
        to[cnt] = i.first;
        cnt++;
    }
    sort(ALL(v));
    REP(i, n){
        ind[fr[s[i].first]].push_back(fr[s[i].second]);
        ind[fr[s[i].second]].push_back(fr[s[i].first]);
    }
    st.init(ind);
    REP(i, n){
        //cout << s[v[i].second].first << " " << s[v[i].second].second << " " << fr[s[v[i].second].first] <<" " <<  fr[s[v[i].second].second] << " " << v[i].second << endl;
        ll x = st.get(0, fr[s[v[i].second].first], 0, fr[s[v[i].second].second]) + 1;
        ans = max(ans, x);
        st.add(fr[s[v[i].second].second], fr[s[v[i].second].first], x);
    }
    cout << ans << endl;
}
accuracy: 0.2972972972972973
time_ms: 700
memory_kb: 201960
final_rank: 10

code_snippet: #include "bits/stdc++.h"
using namespace std;

#define REP(i, n) for(ll i = 0;i < n;i++)
#define REPR(i, n) for(ll i = n;i >= 0;i--)
#define FOR(i, m, n) for(ll i = m;i < n;i++)
#define FORR(i, m, n) for(ll i = m;i >= n;i--)
#define REPO(i, n) for(ll i = 1;i <= n;i++)
#define ll long long
#define INF (ll)1ll << 60
#define MINF (-1 * INF)
#define ALL(n) n.begin(),n.end()
#define MOD (ll)1000000007
#define P pair<ll, ll>

#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,a,b) for(int i=a;i>=b;i--)
#define fore(i,a) for(auto &i:a)
using V = ll;
V comp(V& l, V& r) { return max(l, r); };
struct SegTree { //[l,r)
    int NV;
    vector<V> val;
    void init(int n) {
        NV = 1;
        while (NV < n) NV *= 2;
        val = vector<V>(NV * 2, 0);
    }
    V get(int x, int y, int l, int r, int k) {
        if (r <= x || y <= l) return 0;
        if (x <= l && r <= y) return val[k];
        auto a = get(x, y, l, (l + r) / 2, k * 2); auto b = get(x, y, (l + r) / 2, r, k * 2 + 1); return comp(a, b);
    }
    V get(int x, int y) { return get(x, y, 0, NV, 1); }
    void update(int i, V v) { i += NV; val[i] = v; while (i>1)i >>= 1, val[i] = comp(val[i * 2], val[i * 2 + 1]); }
    void add(int i, V v) { update(i, val[i + NV] + v); }
    V operator[](int x) { return get(x, x + 1); }
};
 
struct Healthy2DSegTree {
    int NV;
    vector<SegTree> st;
    vector<vector<int>> index;
 
    void init(vector<vector<int>> &v) {
        int n = v.size();
        NV = 1; while (NV < n) NV *= 2;
        index.resize(2 * NV);
        rep(i, 0, n) fore(j, v[i]) index[i + NV].push_back(j);
        rrep(i, NV * 2 - 1, 1) {
            sort(index[i].begin(), index[i].end());
            index[i].erase(unique(index[i].begin(), index[i].end()), index[i].end());
            fore(j, index[i]) index[i / 2].push_back(j);
        }
        st.resize(2 * NV);
        rep(i, 1, NV * 2) st[i].init(index[i].size());
    }
    void update(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].update(yy, v);
            x >>= 1;
        }
    }
    void add(int x, int y, V v) {
        assert(x < NV);
        x += NV;
        while (x) {
            int yy = lower_bound(index[x].begin(), index[x].end(), y) - index[x].begin();
            assert(yy != index[x].size());
            assert(y == index[x][yy]);
            st[x].add(yy, v);
            x >>= 1;
        }
    }
    V get(int sx, int tx, int sy, int ty, int k, int l, int r) {
        assert(k < NV * 2);
        assert(l < r);
        if (r <= sx or tx <= l) return 0;
        if (sx <= l and r <= tx) {
            int syy = lower_bound(index[k].begin(), index[k].end(), sy) - index[k].begin();
            int tyy = lower_bound(index[k].begin(), index[k].end(), ty) - index[k].begin();
            return st[k].get(syy, tyy);
        }
        int md = (l + r) / 2;
        V le = get(sx, tx, sy, ty, k * 2, l, md);
        V ri = get(sx, tx, sy, ty, k * 2 + 1, md, r);
        return comp(le, ri);
    }
    V get(int sx, int tx, int sy, int ty) {
        return get(sx, tx, sy, ty, 1, 0, NV);
    }
};

map<ll, ll> fr, to;
Healthy2DSegTree st;
vector<P> s, v;
ll n, ans;
int main(){
    cin >> n;
    vector<vector<int>> ind(110000);
    REP(i, n){
        ll a, b;
        cin >> a >> b;
        s.push_back(P(a, b));
        v.push_back(P(a + b, i));
        fr[a]++;
        fr[b]++;
    }
    ll cnt = 0;
    for (auto& i : fr) {
        i.second = cnt;
        to[cnt] = i.first;
        cnt++;
    }
    sort(ALL(v));
    REP(i, n){
        ind[fr[s[i].first]].push_back(fr[s[i].second]);
        ind[fr[s[i].second]].push_back(fr[s[i].first]);
    }
    st.init(ind);
    REP(i, n){
        //cout << s[v[i].second].first << " " << s[v[i].second].second << " " << fr[s[v[i].second].first] <<" " <<  fr[s[v[i].second].second] << " " << v[i].second << endl;
        ll x = st.get(0, fr[s[v[i].second].first], 0, fr[s[v[i].second].second]) + 1;
        ans = max(ans, x);
        st.add(fr[s[v[i].second].second], fr[s[v[i].second].first], x);
    }
    cout << ans << endl;
}
accuracy: 0.2972972972972973
time_ms: 310
memory_kb: 84912
final_rank: 7

code_snippet: #pragma GCC optimize("O3")
#include<bits/stdc++.h> 
using namespace std;
using ll=long long;
using P=pair<ll,ll>;
template<class T> using V=vector<T>; 
#define fi first
#define se second
#define all(v) (v).begin(),(v).end()
const ll inf=(1e18);
//const ll mod=998244353;
const ll mod=1000000007;
const vector<int> dy={-1,0,1,0},dx={0,-1,0,1};
ll GCD(ll a,ll b) {return b ? GCD(b,a%b):a;}
ll LCM(ll c,ll d){return c/GCD(c,d)*d;}
struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(20);}} __init;
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T>void debag(const vector<T> &a){cerr<<"debag :";for(auto v:a)cerr<<v<<" ";cerr<<"\n";}
template<class T>void print(const vector<T> &a){for(auto v:a)cout<<v<<" ";cout<<"\n";}
template <typename T>
struct ST{//1index query l,r lが開区間
  using F = function<T(T,T)>;
  int n;
  F f;
  T ti;
  vector<T> dat;
  ST(){};
  ST(F f,T ti):f(f),ti(ti){}
  void init(int n_){    
    n=1;
    while(n<n_) n<<=1;
    dat.assign(n<<1,ti);
  }
  void build(const vector<T> &v){
    int n_=v.size();
    init(n_);
    for(int i=0;i<n_;i++) dat[n+i]=v[i];
    for(int i=n-1;i;i--)
      dat[i]=f(dat[(i<<1)|0],dat[(i<<1)|1]);
  }
  void set_val(int k,T x){//kは0-index
    dat[k+=n]=x;
    while(k>>=1)
      dat[k]=f(dat[(k<<1)|0],dat[(k<<1)|1]);    
  }
  T query(int a,int b){
    T vl=ti,vr=ti;
    for(int l=a+n,r=b+n;l<r;l>>=1,r>>=1) {
      if(l&1) vl=f(vl,dat[l++]);
      if(r&1) vr=f(dat[--r],vr);
    }
    return f(vl,vr);
  }
};
struct dat{
      ll a,b,id;
      dat(ll a,ll b,ll id):a(a),b(b),id(id){}
};
int main(){
    int n;
    cin >> n;
    V<int> A(n),B(n);
    map<int,int> mp;
    V<dat> d;
    for(int i=0;i<n;i++){
          cin >> A[i] >> B[i];
          mp[A[i]];mp[B[i]];
          d.emplace_back(A[i],B[i],0ll);
          d.emplace_back(B[i],A[i],1ll);
    }
      sort(all(d),[](auto a,auto b){
            if(a.a!=b.a)return a.a<b.a;
            return a.b<b.b;
      });
    int num=0;
    for(auto &p:mp){
          p.se=num++;
    }
    auto f=[&](ll a,ll b){
          return max(a,b);
    };
      ST<ll> dp1(f,0),dp2(f,0);
      dp1.init(num+5);
      dp2.init(num+5);
      V<dat> tmp;
      int bfo=-1;
      for(int i=0;i<2*n;i++){
          auto [a,b,id]=d[i];
          if(bfo!=a){
                for(auto [ind,v,id]:tmp){
                      if(id==0){
                        dp2.set_val(ind,v);
                      }else{
                        dp1.set_val(ind,v); 
                      }
                }
                tmp.clear();
                bfo=a;
          }
          if(id==0){
                ll v=dp1.query(0,mp[b])+1;
                ll u=dp2.query(mp[b],mp[b]+1);
                tmp.emplace_back(mp[b],max(v,u),0);
          }else{
                ll v=dp2.query(0,mp[b])+1;
                ll u=dp1.query(mp[b],mp[b]+1);
                tmp.emplace_back(mp[b],max(v,u),1);              
          }
      }
      for(auto [ind,v,id]:tmp){
            if(id==0){
            dp2.set_val(ind,v);
            }else{
            dp1.set_val(ind,v); 
            }
      }
      cout<<max(dp1.query(0,num+5),dp2.query(0,num+5))<<"\n";
}
accuracy: 1
time_ms: 210
memory_kb: 27368
final_rank: 6

code_snippet: #pragma GCC optimize("O3")
#include<bits/stdc++.h> 
using namespace std;
using ll=long long;
using P=pair<ll,ll>;
template<class T> using V=vector<T>; 
#define fi first
#define se second
#define all(v) (v).begin(),(v).end()
const ll inf=(1e18);
//const ll mod=998244353;
const ll mod=1000000007;
const vector<int> dy={-1,0,1,0},dx={0,-1,0,1};
ll GCD(ll a,ll b) {return b ? GCD(b,a%b):a;}
ll LCM(ll c,ll d){return c/GCD(c,d)*d;}
struct __INIT{__INIT(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(20);}} __init;
template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T>void debag(const vector<T> &a){cerr<<"debag :";for(auto v:a)cerr<<v<<" ";cerr<<"\n";}
template<class T>void print(const vector<T> &a){for(auto v:a)cout<<v<<" ";cout<<"\n";}
template <typename T>
struct ST{//1index query l,r lが開区間
  using F = function<T(T,T)>;
  int n;
  F f;
  T ti;
  vector<T> dat;
  ST(){};
  ST(F f,T ti):f(f),ti(ti){}
  void init(int n_){    
    n=1;
    while(n<n_) n<<=1;
    dat.assign(n<<1,ti);
  }
  void build(const vector<T> &v){
    int n_=v.size();
    init(n_);
    for(int i=0;i<n_;i++) dat[n+i]=v[i];
    for(int i=n-1;i;i--)
      dat[i]=f(dat[(i<<1)|0],dat[(i<<1)|1]);
  }
  void set_val(int k,T x){//kは0-index
    dat[k+=n]=x;
    while(k>>=1)
      dat[k]=f(dat[(k<<1)|0],dat[(k<<1)|1]);    
  }
  T query(int a,int b){
    T vl=ti,vr=ti;
    for(int l=a+n,r=b+n;l<r;l>>=1,r>>=1) {
      if(l&1) vl=f(vl,dat[l++]);
      if(r&1) vr=f(dat[--r],vr);
    }
    return f(vl,vr);
  }
};
struct dat{
      ll a,b,id;
      dat(ll a,ll b,ll id):a(a),b(b),id(id){}
};
int main(){
    int n;
    cin >> n;
    V<int> A(n),B(n);
    map<int,int> mp;
    V<dat> d;
    for(int i=0;i<n;i++){
          cin >> A[i] >> B[i];
          mp[A[i]];mp[B[i]];
          d.emplace_back(A[i],B[i],0ll);
          d.emplace_back(B[i],A[i],1ll);
    }
      sort(all(d),[](auto a,auto b){
            if(a.a!=b.a)return a.a<b.a;
            return a.b<b.b;
      });
    int num=0;
    for(auto &p:mp){
          p.se=num++;
    }
    auto f=[&](ll a,ll b){
          return max(a,b);
    };
      ST<ll> dp1(f,0),dp2(f,0);
      dp1.init(num+5);
      dp2.init(num+5);
      for(int i=0;i<2*n;i++){
          auto [a,b,id]=d[i];
          if(id==0){
                ll v=dp1.query(0,mp[b])+1;
                ll u=dp2.query(mp[b],mp[b]+1);
                dp2.set_val(mp[b],max(v,u));
          }else{
                ll v=dp2.query(0,mp[b])+1;
                ll u=dp1.query(mp[b],mp[b]+1);
                dp1.set_val(mp[b],max(v,u));                
          }
      }
      cout<<max(dp1.query(0,num+5),dp2.query(0,num+5))<<"\n";
}
accuracy: 0.1891891891891892
time_ms: 100
memory_kb: 18624
final_rank: 13

code_snippet: //#pragma GCC optimize("Ofast")
//#pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>

//#include <atcoder/modint>
using namespace std;
//using namespace atcoder;

using ll = long long;
using ull = unsigned long long;
using pii = pair<int, int>;
template <class T>
using V = vector<T>;
template <class T>
using VV = V<V<T>>;
template <class T>
V<T> make_vec(size_t a) {
    return V<T>(a);
}
template <class T, class... Ts>
auto make_vec(size_t a, Ts... ts) {
    return V<decltype(make_vec<T>(ts...))>(a, make_vec<T>(ts...));
}

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fi first
#define se second
#define rep(i, n) rep2(i, 0, n)
#define rep2(i, m, n) for (int i = m; i < (n); i++)
#define per(i, b) per2(i, 0, b)
#define per2(i, a, b) for (int i = int(b) - 1; i >= int(a); i--)
#define ALL(c) (c).begin(), (c).end()
#define SZ(x) ((int)(x).size())
#define all(x) x.begin(),x.end()

constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }

template <class T, class U>
void chmin(T& t, const U& u) {
    if (t > u) t = u;
}
template <class T, class U>
void chmax(T& t, const U& u) {
    if (t < u) t = u;
}

template <class T, class U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << "," << p.second << ")";
    return os;
}

template <class T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    os << "{";
    rep(i, v.size()) {
        if (i) os << ",";
        os << v[i];
    }
    os << "}";
    return os;
}

#ifdef LOCAL
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << H;
    debug_out(T...);
}
#define debug(...) \
    cerr << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

constexpr int INF = TEN(9);

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int N;
    cin >> N;
    int M=2*N;
    int A[N],B[N];
    rep(i,N) cin >> A[i] >> B[i];
    set<int> apr;
    rep(i,N) apr.insert(A[i]),apr.insert(B[i]);
    vector<int> res;
    for(auto e:apr) res.push_back(e);
    rep(i,N){
        A[i]=lower_bound(all(res),A[i])-res.begin();
        B[i]=lower_bound(all(res),B[i])-res.begin();
        A[i]++;
        B[i]++;
    }
    V<pii> vec;
    rep(i, N) {
        vec.push_back(mp(A[i], -B[i]));
        vec.push_back(mp(B[i],-A[i]));
    }
    sort(ALL(vec));
    V<int> dp(M + 1, INF);
    dp[0] = 0;

    for (auto& [a, b] : vec) {
        auto it = lower_bound(ALL(dp), -b);
        *it = -b;
    }
    cout << lower_bound(ALL(dp), INF) - dp.begin() - 1 << endl;

    return 0;
}
accuracy: 0.1891891891891892
time_ms: 40
memory_kb: 11276
final_rank: 11

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
using PII = pair<ll, ll>;
#define FOR(i,a,n) for(ll i=(ll)a; i<(ll)n; ++i)
#define REP(i,n) FOR(i,0,n)
const ll INF = 1LL << 60;
template<typename T> void chmin(T &a, T b) { a = min(a, b); }

int main() {
	int N;
	cin >> N;
	vector<pair<int, int>>v(N);
	vector<pair<int, int>>w(N);
	for (auto &i : v)cin >> i.first >> i.second;
	for (int i = 0; i < N; i++) {
		w[i] = { v[i].second,v[i].first };
	}
	sort(v.begin(), v.end());
	sort(w.begin(), w.end());
	int vindex = 0, windex = 0;
	vector<int>vused(N + 2);
	vector<int>wused(N + 2);
	set<pair<int, pair<int, int>>>vyoyaku;
	set<pair<int, pair<int, int>>>wyoyaku;
	set<pair<int, int>>vkouho;
	set<pair<int, int>>wkouho;
	vkouho.insert({ 0,1 });
	int ans = 0;
	while (vindex < N || windex < N) {
		//cout << vindex << " " << windex << endl;
		int nx = 0;
		if (vindex == N)nx = 1;
		else if (windex<N&&v[vindex].first>w[windex].first)nx = 1;
		//cout << vindex << " " << windex << " " << nx << endl;
		if (nx == 0) {// use v
					  //	cout << "vvvvvv" << endl;
			while (!vyoyaku.empty() && vyoyaku.begin()->first <= v[vindex].first) {
				auto box = vyoyaku.begin()->second;
				vyoyaku.erase(vyoyaku.begin());

				if (vused[box.second]) {
					if (vused[box.second]>box.first) {
						vkouho.insert(box);
						vkouho.erase({ vused[box.second],box.second });
						vused[box.second] = box.first;
					}
					auto it = vkouho.find(box);
					while (it != vkouho.begin() && prev(it)->first >= box.first) {
						vused[prev(it)->second] = 0;
						vkouho.erase(prev(it));
					}
				}
				else {
					auto nx = vkouho.lower_bound(box);
					if (nx != vkouho.begin() && prev(nx)->second >= box.second)continue;
					vkouho.insert(box);
					auto it = vkouho.find(box);
					while (next(it) != vkouho.end() && next(it)->second <= box.second) {
						vused[next(it)->second] = 0;
						vkouho.erase(next(it));
					}
				}

			}

			auto it = vkouho.lower_bound({ v[vindex].second,MOD });
			if (it == vkouho.begin()) {
				vindex++;
				continue;
			}
			it = prev(it);
			int score = it->second;
			//	cout << v[vindex].first << " " << v[vindex].second << " " << score << endl;
			ans = max(ans, score);
			wyoyaku.insert({ v[vindex].first+1,{ v[vindex].second + 1,score + 1 } });
			vindex++;
		}
		else {//use w
			  //cout << w[windex].first << " " << wyoyaku.size() << endl;
			while (!wyoyaku.empty() && wyoyaku.begin()->first <= w[windex].first) {
				auto box = wyoyaku.begin()->second;
				wyoyaku.erase(wyoyaku.begin());

				if (wused[box.second]) {
					if (wused[box.second]>box.first) {
						wkouho.insert(box);
						wkouho.erase({ wused[box.second],box.second });
						wused[box.second] = box.first;
					}
					auto it = wkouho.find(box);
					while (it != wkouho.begin() && prev(it)->first >= box.first) {
						wused[prev(it)->second] = 0;
						wkouho.erase(prev(it));
					}
				}
				else {
					auto nx = wkouho.lower_bound(box);
					if (nx != wkouho.begin() && prev(nx)->second >= box.second)continue;
					wkouho.insert(box);
					auto it = wkouho.find(box);
					while (next(it) != wkouho.end() && next(it)->second <= box.second) {
						wused[next(it)->second] = 0;
						wkouho.erase(next(it));
					}
				}

			}
			//	cout << "hihihh" << endl;
			//	cout <<"wwwwww "<< w[windex].first << " " << w[windex].second << " " << wkouho.size() << endl;
			auto it = wkouho.lower_bound({ w[windex].second,MOD });
			if (it == wkouho.begin()) {
				windex++;
				continue;
			}
			it = prev(it);
			int score = it->second;
			//	cout << w[windex].first << " " << w[windex].second << " " << score << endl;
			ans = max(ans, score);
			vyoyaku.insert({ w[windex].first+1,{ w[windex].second + 1,score + 1 } });
			windex++;
		}


	}
	cout << ans << endl;
	//cin >> N;
}
accuracy: 1
time_ms: 100
memory_kb: 9876
final_rank: 4

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
using PII = pair<ll, ll>;
#define FOR(i,a,n) for(ll i=(ll)a; i<(ll)n; ++i)
#define REP(i,n) FOR(i,0,n)
const ll INF = 1LL << 60;
template<typename T> void chmin(T &a, T b) { a = min(a, b); }

int main() {
	int N;
	cin >> N;
	vector<pair<int, int>>v(N);
	vector<pair<int, int>>w(N);
	for (auto &i : v)cin >> i.first >> i.second;
	for (int i = 0; i < N; i++) {
		w[i] = { v[i].second,v[i].first };
	}
	sort(v.begin(), v.end());
	sort(w.begin(), w.end());
	int vindex = 0, windex = 0;
	vector<int>vused(N + 2);
	vector<int>wused(N + 2);
	set<pair<int, pair<int, int>>>vyoyaku;
	set<pair<int, pair<int, int>>>wyoyaku;
	set<pair<int, int>>vkouho;
	set<pair<int, int>>wkouho;
	vkouho.insert({ 0,1 });
	int ans = 0;
	while (vindex < N || windex < N) {
		//cout << vindex << " " << windex << endl;
		int nx = 0;
		if (vindex == N)nx = 1;
		else if (windex<N&&v[vindex].first>w[windex].first)nx = 1;
		//cout << vindex << " " << windex << " " << nx << endl;
		if (nx == 0) {// use v
					  //	cout << "vvvvvv" << endl;
			while (!vyoyaku.empty() && vyoyaku.begin()->first <= v[vindex].first) {
				auto box = vyoyaku.begin()->second;
				vyoyaku.erase(vyoyaku.begin());

				if (vused[box.second]) {
					if (vused[box.second]>box.first) {
						vkouho.insert(box);
						vkouho.erase({ vused[box.second],box.second });
						vused[box.second] = box.first;
					}
					auto it = vkouho.find(box);
					while (it != vkouho.begin() && prev(it)->first >= box.first) {
						vused[prev(it)->second] = 0;
						vkouho.erase(prev(it));
					}
				}
				else {
					auto nx = vkouho.lower_bound(box);
					if (nx != vkouho.begin() && prev(nx)->second >= box.second)continue;
					vkouho.insert(box);
					auto it = vkouho.find(box);
					while (next(it) != vkouho.end() && next(it)->second <= box.second) {
						vused[next(it)->second] = 0;
						vkouho.erase(next(it));
					}
				}

			}

			auto it = vkouho.lower_bound({ v[vindex].second,MOD });
			if (it == vkouho.begin()) {
				vindex++;
				continue;
			}
			it = prev(it);
			int score = it->second;
			//	cout << v[vindex].first << " " << v[vindex].second << " " << score << endl;
			ans = max(ans, score);
			wyoyaku.insert({ v[vindex].first+1,{ v[vindex].second + 1,score + 1 } });
			vindex++;
		}
		else {//use w
			  //cout << w[windex].first << " " << wyoyaku.size() << endl;
			while (!wyoyaku.empty() && wyoyaku.begin()->first <= w[windex].first) {
				auto box = wyoyaku.begin()->second;
				wyoyaku.erase(wyoyaku.begin());

				if (wused[box.second]) {
					if (wused[box.second]>box.first) {
						wkouho.insert(box);
						wkouho.erase({ wused[box.second],box.second });
						wused[box.second] = box.first;
					}
					auto it = wkouho.find(box);
					while (it != wkouho.begin() && prev(it)->first >= box.first) {
						wused[prev(it)->second] = 0;
						wkouho.erase(prev(it));
					}
				}
				else {
					auto nx = wkouho.lower_bound(box);
					if (nx != wkouho.begin() && prev(nx)->second >= box.second)continue;
					wkouho.insert(box);
					auto it = wkouho.find(box);
					while (next(it) != wkouho.end() && next(it)->second <= box.second) {
						wused[next(it)->second] = 0;
						wkouho.erase(next(it));
					}
				}

			}
			//	cout << "hihihh" << endl;
			//	cout <<"wwwwww "<< w[windex].first << " " << w[windex].second << " " << wkouho.size() << endl;
			auto it = wkouho.lower_bound({ w[windex].second,MOD });
			if (it == wkouho.begin()) {
				windex++;
				continue;
			}
			it = prev(it);
			int score = it->second;
			//	cout << w[windex].first << " " << w[windex].second << " " << score << endl;
			ans = max(ans, score);
			vyoyaku.insert({ w[windex].first+1,{ w[windex].second + 1,score + 1 } });
			windex++;
		}


	}
	cout << ans << endl;
	//cin >> N;
}
accuracy: 1
time_ms: 100
memory_kb: 9872
final_rank: 3

code_snippet: #include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll MOD = 1e9 + 7;
using PII = pair<ll, ll>;
#define FOR(i,a,n) for(ll i=(ll)a; i<(ll)n; ++i)
#define REP(i,n) FOR(i,0,n)
const ll INF = 1LL << 60;
template<typename T> void chmin(T &a, T b) { a = min(a, b); }

int main() {
	int N;
	cin >> N;
	vector<pair<int, int>>v(N);
	vector<pair<int, int>>w(N);
	for (auto &i : v)cin >> i.first >> i.second;
	for (int i = 0; i < N; i++) {
		w[i] = { v[i].second,v[i].first };
	}
	sort(v.begin(), v.end());
	sort(w.begin(), w.end());
	int vindex = 0, windex = 0;
	vector<int>vused(N + 2);
	vector<int>wused(N + 2);
	set<pair<int, pair<int, int>>>vyoyaku;
	set<pair<int, pair<int, int>>>wyoyaku;
	set<pair<int, int>>vkouho;
	set<pair<int, int>>wkouho;
	vkouho.insert({ 0,1 });
	int ans = 0;
	while (vindex < N || windex < N) {
		//cout << vindex << " " << windex << endl;
		int nx = 0;
		if (vindex == N)nx = 1;
		else if (windex<N&&v[vindex].first>w[windex].first)nx = 1;
		//cout << vindex << " " << windex << " " << nx << endl;
		if (nx == 0) {// use v
		//	cout << "vvvvvv" << endl;
			while (!vyoyaku.empty() && vyoyaku.begin()->first <= v[vindex].first) {
				auto box = vyoyaku.begin()->second;
				vyoyaku.erase(vyoyaku.begin());

				if (vused[box.second]) {
					if (vused[box.second]>box.first) {
						vkouho.insert(box);
						vkouho.erase({ vused[box.second],box.second });
						vused[box.second] = box.first;
					}
					auto it = vkouho.find(box);
					while (it != vkouho.begin() && prev(it)->first >= box.first) {
						vused[prev(it)->second] = 0;
						vkouho.erase(prev(it));
					}
				}
				else {
					auto nx = vkouho.lower_bound(box);
					if (nx != vkouho.begin() && prev(nx)->second >= box.second)continue;
					vkouho.insert(box);
					auto it = vkouho.find(box);
					while (next(it) != vkouho.end() && next(it)->second <= box.second) {
						vused[next(it) -> second] = 0;
						vkouho.erase(next(it));
					}
				}

			}

			auto it = vkouho.lower_bound({ v[vindex].second,MOD });
			if (it == vkouho.begin()) {
				vindex++;
				continue;
			}
			it = prev(it);
			int score = it->second;
		//	cout << v[vindex].first << " " << v[vindex].second << " " << score << endl;
			ans = max(ans, score);
			wyoyaku.insert({ v[vindex].first,{v[vindex].second + 1,score + 1} });
			vindex++;
		}
		else {//use w
			//cout << w[windex].first << " " << wyoyaku.size() << endl;
			while (!wyoyaku.empty() && wyoyaku.begin()->first <= w[windex].first) {
				auto box = wyoyaku.begin()->second;
				wyoyaku.erase(wyoyaku.begin());

				if (wused[box.second]) {
					if (wused[box.second]>box.first) {
						wkouho.insert(box);
						wkouho.erase({ wused[box.second],box.second });
						wused[box.second] = box.first;
					}
					auto it = wkouho.find(box);
					while (it != wkouho.begin() && prev(it)->first >= box.first) {
						wused[prev(it)->second] = 0;
						wkouho.erase(prev(it));
					}
				}
				else {
					auto nx = wkouho.lower_bound(box);
					if (nx != wkouho.begin() && prev(nx)->second >= box.second)continue;
					wkouho.insert(box);
					auto it = wkouho.find(box);
					while (next(it) != wkouho.end() && next(it)->second <= box.second) {
						wused[next(it)->second] = 0;
						wkouho.erase(next(it));
					}
				}

			}
		//	cout << "hihihh" << endl;
		//	cout <<"wwwwww "<< w[windex].first << " " << w[windex].second << " " << wkouho.size() << endl;
			auto it = wkouho.lower_bound({ w[windex].second,MOD });
			if (it == wkouho.begin()) {
				windex++;
				continue;
			}
			it = prev(it);
			int score = it->second;
		//	cout << w[windex].first << " " << w[windex].second << " " << score << endl;
			ans = max(ans, score);
			vyoyaku.insert({ w[windex].first,{ w[windex].second + 1,score + 1 } });
			windex++;
		}


	}
	cout << ans << endl;
	//cin >> N;
}
accuracy: 0.1891891891891892
time_ms: 80
memory_kb: 9884
final_rank: 12

code_snippet: #include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	Info(int arg_a,int arg_b,bool arg_is_reverse){
		a = arg_a;
		b = arg_b;
		is_reverse = arg_is_reverse;
	}
	bool operator<(const struct Info &arg) const{
		if(a != arg.a){
			return a < arg.a;
		}else{
			return b > arg.b;
		}
	}
	int a,b;
	bool is_reverse;
};

int dp[200001];

int main(){

	int N;
	scanf("%d",&N);

	int a,b;
	vector<Info> V;

	for(int i = 0; i < N; i++){
		scanf("%d %d",&a,&b);
		V.push_back(Info(a,b,false));
		V.push_back(Info(b,a,true));
	}

	sort(V.begin(),V.end());

	for(int i = 0; i < 2*N; i++)dp[i] = BIG_NUM;
	int left,right,m,loc;

	for(int i = 0; i < 2*N; i++){
		left = 0,right = i,m = (left+right)/2;
		loc = BIG_NUM;
		while(left <= right){
			if(dp[m] >= V[i].b){
				loc = m;
				right = m-1;
			}else{
				left = m+1;
			}
			m = (left+right)/2;
		}
		if(loc == BIG_NUM)continue;
		if(V[i].is_reverse == true && loc%2 == 0){
			dp[loc] = V[i].b;
		}else if(V[i].is_reverse == false && loc%2 == 1){
			dp[loc] = V[i].b;
		}
	}

	int ans = 0;
	left = 0,right = 2*N-1,m = (left+right)/2;

	while(left <= right){
		if(dp[m] == BIG_NUM){
			ans = m;
			right = m-1;
		}else{
			left = m+1;
		}
		m = (left+right)/2;
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 6200
final_rank: 2

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){return o<<"("<<p.fs<<","<<p.sc<<")";}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){o<<"sz = "<<vc.size()<<endl<<"[";for(const T& v:vc) o<<v<<",";o<<"]";return o;}

int inf=1e9;
struct segtree{
	static const int N=1<<18;
	int seg[N*2];
	segtree(){
		rep(i,N*2) seg[i]=0;
	}
	segtree(vector<int>& vi){
		rep(i,N*2) seg[i]=0;
		rep(i,vi.size()) seg[N+i]=vi[i];
		for(int i=N-1;i>0;i--) seg[i]=max(seg[i*2],seg[i*2+1]);
	}


	void update(int x,int v){
		x+=N;
		chmax(seg[x],v);
		x/=2;
		while(x){
			seg[x]=max(seg[x*2],seg[x*2+1]);
			x/=2;
		}
	}
	int getmax(int a,int b,int l=0,int r=N,int k=1){
		if(b<=l||r<=a) return 0;
		if(a<=l&&r<=b) return seg[k];
		return max(getmax(a,b,l,(l+r)/2,k*2),getmax(a,b,(l+r)/2,r,k*2+1));
	}
}seg[2];

vector<int> xs;
const int MN=100000;
typedef pair<int,int> P;
typedef pair<P,int> PP;
int a[MN],b[MN],c[MN];
int main(){
	int N;
	cin>>N;
	vector<PP> vp;
	rep(i,N) cin>>a[i]>>b[i];
	rep(i,N) xs.pb(a[i]),xs.pb(b[i]);
	sort(all(xs));
	xs.erase(unique(xs.begin(),xs.end()),xs.end());
	rep(i,N) a[i]=lower_bound(all(xs),a[i])-xs.begin(),b[i]=lower_bound(all(xs),b[i])-xs.begin();
	rep(i,N){
		vp.pb(PP(P(a[i],-b[i]),0));
		vp.pb(PP(P(b[i],-a[i]),1));
	}
	sort(all(vp));

	int K = xs.size();
	int ans=0;

	vector<P> upd[2];
	rep(i,N*2){
		PP pp=vp[i];
		int x = pp.fs.fs,y=-pp.fs.sc,c=pp.sc;
		int mx = seg[c].getmax(0,y)+1;
		chmax(ans,mx);
//		seg[1-c].update(y,mx);
		upd[1-c].pb(P(y,mx));
		if(i==N*2-1 || x!=vp[i+1].fs.fs){
			rep(t,2){
				for(P p:upd[t]) seg[t].update(p.fs,p.sc);
				upd[t].clear();
			}
		}
	}
	cout<<ans<<endl;
}
accuracy: 1
time_ms: 130
memory_kb: 13520
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;

using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;
using LL = long long;
using VL = vector<LL>;
using VVL = vector<VL>;
using PLL = pair<LL, LL>;
using VS = vector<string>;

#define ALL(a)  begin((a)),end((a))
#define RALL(a) (a).rbegin(), (a).rend()
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define SZ(a) int((a).size())
#define SORT(c) sort(ALL((c)))
#define RSORT(c) sort(RALL((c)))

#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)

#define FF first
#define SS second
template<class S, class T>
istream& operator>>(istream& is, pair<S,T>& p){
  return is >> p.FF >> p.SS;
}
template<class S, class T>
ostream& operator<<(ostream& os, const pair<S,T>& p){
  return os << p.FF << " " << p.SS;
}
template<class T>
void maxi(T& x, T y){
  if(x < y) x = y;
}
template<class T>
void mini(T& x, T y){
  if(x > y) x = y;
}


const double EPS = 1e-10;
const double PI  = acos(-1.0);
const LL MOD = 1e9+7;
const int INF = 1e9+100;

int main(){
  cin.tie(0);
  ios_base::sync_with_stdio(false);

  int N; cin >> N;
  using MA = pair<PII,int>;
  vector<MA> xs(N*2);
  REP(i,N){
	cin >> xs[i].FF;
	xs[N+i] = MP(MP(xs[i].FF.SS, xs[i].FF.FF), 1);
  }
  sort(ALL(xs), [](const MA& l, const MA& r){
	  return
		l.FF.FF != r.FF.FF ?
		l.FF.FF < r.FF.FF :
		l.FF.SS > r.FF.SS;
	});

  VI dp(N*2, INF);
  REP(i,N*2){
	int ix = lower_bound(ALL(dp), xs[i].FF.SS) - begin(dp);
	if(xs[i].SS != ix%2){
	  if(ix == 0)
		continue;
	  --ix;
	}
	mini(dp[ix], xs[i].FF.SS);
  }

  cout << (lower_bound(ALL(dp), INF) - begin(dp)) << endl;

  return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 5976
final_rank: 1