Problem:
Problem E
Tampered Records
In ancient times, the International Collegiate Puzzle Contest (ICPC) was held annually.
  Each of the annual contests consisted of two rounds: the morning round and the afternoon round.
  In both of the two rounds, the participants posed one puzzle made on their own to all the other participants, and then tried to solve as many puzzles as possible posed by the other participants.
The participants were ranked by the following rules.
The participant who solved more puzzles in the afternoon round is ranked higher.
For participants solving the same number of puzzles in the afternoon round, the one who solved more puzzles in the morning round is ranked higher.
For participants solving completely the same numbers of puzzles in both rounds, the order is decided by lot.
Recently, a historical document was found, which is said to be the standings of some year's ICPC.
  As in other similar documents, this document is assumed to list the number of puzzles solved by participants in each round, in the order of their ranks.
  However, the scholars suspect that someone tampered with the document overwriting some of the numbers.
  Your task is to find at least how many of the numbers were overwritten, assuming that the original document had records consistent with the rules described above.
  No parts of the document other than the numbers of puzzles solved were tampered with; addition and deletion of participants were impossible.
Input
The input consists of multiple datasets, each in the following format.
n
x
1
y
1
⋮
x
n
y
n
n
is the number of participants, an integer between 2 and 6000, inclusive.
x
i
and
y
i
are the numbers currently on the document representing the numbers of the puzzles solved in the morning and the afternoon rounds, respectively, by the participant whose rank was the
i
-th highest.
x
i
and
y
i
are non-negative integers less than
n.
Some of these numbers might differ from the original ones.
The end of the input is indicated by a line consisting of a zero.
  The input consists of at most 100 datasets.
  The sum of
n
's in all the datasets in the input is at most 10
5
.
Output
For each dataset, output in a line at least how many of the 2
n
numbers in the document were overwritten.
  Note that the numbers before the overwriting were all non-negative integers less than
n.
Sample Input
2
1 0
1 1
3
2 2
2 0
0 1
4
0 3
0 2
3 1
2 0
5
0 3
0 3
1 2
4 2
4 2
3
1 1
2 2
2 2
4
0 0
1 1
2 2
3 3
0
Output for the Sample Input
1
1
0
1
2
4

Submitted solutions:

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

#include <atcoder/all>
using namespace atcoder;

bool solve() {
    int N;
    cin >> N;
    if(N == 0) return false;
    using P = pair<int, int>;
    const P MINF = P{0, -1};
    vector<P> dp(N + 1, MINF);
    vector<P> ep(N + 1, MINF);
    dp[0] = P{N - 1, N - 1};
    for(int i = 0; i < N; ++i) {
        int x, y;
        cin >> x >> y;
        swap(x, y);
        for(int j = 0; j <= N; ++j) {
            const auto [p, q] = dp[j];
            // no changes
            if(P{x, y} <= dp[j]) {
                ep[j] = max(ep[j], P{x, y});
            }
            // chenge x
            if(j + 1 <= N) {
                if(P{p, y} <= dp[j]) {
                    ep[j + 1] = max(ep[j + 1], P{p, y});
                }else {
                    ep[j + 1] = max(ep[j + 1], P{p - 1, y});
                }
            }
            // change y
            if(j + 1 <= N && x <= p) {
                if(P{x, N - 1} <= dp[j]) {
                    ep[j + 1] = max(ep[j + 1], P{x, N - 1});
                }else {
                    ep[j + 1] = max(ep[j + 1], P{x, q});
                }
            }
            // change x, y
            if(j + 2 <= N) {
                ep[j + 2] = max(ep[j + 2], P{p, q});
            }
        }
        swap(dp, ep);
        fill(ep.begin(), ep.end(), MINF);
    }
    for(int i = 0; i <= N; ++i) {
        if(dp[i] != MINF) {
            cout << i << endl;
            break;
        }
    }
    return true;
}

int main() {
    while(solve());
}
accuracy: 1
time_ms: 1220
memory_kb: 3712
final_rank: 9

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (ll i = s; i < (ll)(t); i++)
#define rrep(i, s, t) for(ll i = (ll)(t) - 1; i >= (ll)(s); i--)
#define all(x) begin(x), end(x)
#define rall(x) rbegin(x), rend(x)

#define TT template<typename T>
TT using vec = vector<T>;
template<class T1, class T2> bool chmin(T1 &x, T2 y) { return x > y ? (x = y, true) : false; }
template<class T1, class T2> bool chmax(T1 &x, T2 y) { return x < y ? (x = y, true) : false; }

struct io_setup {
    io_setup() {
        ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        cout << fixed << setprecision(15);
    }
} io_setup;

bool check(int N,vector<vector<int>>X,vector<vector<int>>Y){
    vector<pair<int,int>>at(N*N+1);
    rep(i,0,N)rep(j,0,N){
        at[Y[i][j]]={i,j};
    }
    rep(i,0,N)rep(j,0,N)rep(k,0,N)rep(l,0,N){
        if(abs(i-k)+abs(j-l)==1){
            int a=X[i][j],b=X[k][l];
            auto[x,y]=at[a];
            auto[z,w]=at[b];
            if(abs(x-z)+abs(y-w)<N/2)return false;
        }
    }
    return true;
}

void Fmax(pair<int,int>&p,pair<int,int>q){
    if(q.second>p.second)p=q;
    if(q.second==p.second&&q.first>p.first)p=q;
    return;
}

int solve(int N,vector<int>X,vector<int>Y){
    // (Y[i],X[i]) が降順に並ぶ
    vector<pair<int,int>>dp(1);
    dp[0]={N-1,N-1};
    rep(i,0,N){
        vector<pair<int,int>>nxt(2*i+3,{-1,-1});
        rep(j,0,2*i+1){
            auto[x,y]=dp[j];
            if(x==-1)continue;
            // 変更なし
            if(y>Y[i]||(y==Y[i]&&x>=X[i])){
                Fmax(nxt[j],{X[i],Y[i]});
            }
            // xだけ変える
            if(y>Y[i]){
                Fmax(nxt[j+1],{N-1,Y[i]});
            }
            if(y==Y[i]){
                Fmax(nxt[j+1],{x,Y[i]});
            }
            // yだけ変える
            if(x>=X[i]){
                Fmax(nxt[j+1],{X[i],y});
            }
            if(y-1>=0){
                Fmax(nxt[j+1],{X[i],y-1});
            }
            // 両方変更（最大化）
            Fmax(nxt[j+2],{x,y});
        }
        swap(dp,nxt);
    }
    rep(j,0,2*N+1){
        if(dp[j].first!=-1){
            return j;
        }
    }
    return -1;
}

int main() {
    while(1){
        int N;
        cin>>N;
        if(N==0)return 0;
        vector<int>X(N),Y(N);
        rep(i,0,N)cin>>X[i]>>Y[i];
        int ans=solve(N,X,Y);
        assert(ans!=-1);
        cout<<ans<<endl;
    }
}
accuracy: 1
time_ms: 1070
memory_kb: 3940
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;
bool solve();
#define rep(i, a, b) for (int i = a; i < (b); ++i)
typedef pair<int, int> pii;
typedef vector<int> vi;
template <class T>
inline bool chmax(T &a, T b) {
  return ((a < b) ? (a = b, 1) : (0));
}

int main() {
  while (solve());
  return 0;
}

//O(N^2)許されるの...
bool solve() {
  int n;cin>>n;
  if (n==0) return 0;
  vector<pii>yx(n);
  for(auto&[y,x]:yx)cin>>x>>y;

  const int inf = n-1;
  vector<pii> dp(n+1,{-1,-1});
  vector<pii> old(n+1,{-1,-1});
  dp[0]={inf,inf};

  rep(i,0,n){
    rep(j,0,n+1)old[j]=pii(-1,-1);
    swap(old,dp);
    rep(j,0,n+1)if(old[j]!=pii(-1,-1)){
      auto [yi,xi]=yx[i];
      auto [yd,xd]=old[j];
      auto chm=[&](int y,int x)->void{
        int cost=0;
        cost+=y!=yi;
        cost+=x!=xi;
        if(y>yd)return;
        if(y==yd&&x>xd)return;
        if(j+cost<n+1)
          chmax(dp[j+cost],{y,x});
      };

      vi ylist={inf,yi,yd,yd-1};
      vi xlist={inf,xi,xd,xd-1};
      for(auto y:ylist)
        for(auto x:xlist)
          chm(y,x);
    }
  }

  int ans=1010;
  rep(i,0,n+1){
    auto [x,y]=dp[i];
    if(x>=0&&y>=0){
      ans=i;
      break;
    }
  }
  
  cout<<ans<<endl;
  return 1;
}
accuracy: 1
time_ms: 6090
memory_kb: 3712
final_rank: 19

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

using ll = long long;
#define rep(i, a, b) for (int i = a; i < (b); ++i)
#define sz(x) (int)(x).size()
#define all(x) x.begin(), x.end()
typedef pair<int, int> pii;
typedef vector<int> vi;
template <class T>
inline bool chmin(T &a, T b) {
  return ((a > b) ? (a = b, 1) : (0));
}
template <class T>
inline bool chmax(T &a, T b) {
  return ((a < b) ? (a = b, 1) : (0));
}

int main() {
  while (solve());
  return 0;
}

//O(N^2)許されるの...
bool solve() {
  int n;cin>>n;
  if (n==0) return 0;
  vector<pii>yx(n);
  for(auto&[y,x]:yx)cin>>x>>y;

  const int inf = n-1;
  vector<pii> dp(n+1,{-1,-1});
  vector<pii> old(n+1,{-1,-1});
  dp[0]={inf,inf};

  rep(i,0,n){
    rep(j,0,n+1)old[j]={-1,-1};
    swap(old,dp);
    rep(j,0,n+1)if(old[j]!=pii(-1,-1)){
      auto [yi,xi]=yx[i];
      auto [yd,xd]=old[j];
      auto chm=[&](int y,int x)->void{
        int cost=0;
        cost+=y!=yi;
        cost+=x!=xi;
        if(y>yd)return;
        if(y==yd&&x>xd)return;
        if(j+cost<n+1)
          chmax(dp[j+cost],{y,x});
      };

      vi ylist={inf,yi,yd,yd-1};
      vi xlist={inf,xi,xd,xd-1};
      for(auto y:ylist)if(y<=yd)
        for(auto x:xlist)
          chm(y,x);
      
    }
  }

  int ans=1010;
  rep(i,0,n+1){
    auto [x,y]=dp[i];
    if(x>=0&&y>=0){
      ans=i;
      break;
    }
  }
  cout<<ans<<endl;
  return 1;
}
accuracy: 1
time_ms: 5670
memory_kb: 3840
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll  = long long;
using ull = unsigned long long;
#define rep(i, n) for(ll i = 0; i < n; i++)
constexpr ll INF = ((1LL << 61) + (1LL << 30) - 1);

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

  while(true) {
    ll n;
    cin >> n;
    if(n == 0) break;
    vector<ll> x(n), y(n);
    rep(i, n) cin >> x[i] >> y[i];

    // 答えは高々 N (任意の人の午後を変えればいいだけ)
    // dp[i][j] : i 番目まで見て j 回改変したときの直近の値の最大値 (午後 * N + 午前) とすれば N^2 でできそう?

    // vector<vector<ll>> dp(n + 1, vector<ll>(n + 1, -INF));
    vector<ll> dp(n + 1, -INF), next_dp(n + 1, -INF);
    dp[0] = (n - 1) * n + (n - 1);
    rep(i, n) {
      next_dp.assign(n + 1, -INF);
      rep(j, n) {
        if(dp[j] >= y[i] * n + x[i]) {
          next_dp[j] = max(next_dp[j], y[i] * n + x[i]);
        }

        if(j + 1 <= n) {
          ll cand = (dp[j] / n) * n + x[i];
          if(cand > dp[j]) cand = ((dp[j] / n) - 1) * n + x[i];
          ll cand2 = y[i] * n + (n - 1);
          if(cand2 <= dp[j]) cand = max(cand, cand2);
          ll cand3 = y[i] * n + dp[j] % n;
          if(cand3 <= dp[j]) cand = max(cand, cand3);

          if(cand >= 0) next_dp[j + 1] = max(next_dp[j + 1], cand);
        }

        if(j + 2 <= n) {
          next_dp[j + 2] = max(next_dp[j + 2], dp[j]);
        }
      }
      swap(dp, next_dp);
    }

    // rep(i, n + 1) {
    //   rep(j, n + 1) cerr << dp[i][j] << " ";
    //   cerr << endl;
    // }
    // cerr << "----------------" << endl;

    ll ans = n;
    rep(i, n + 1) {
      if(dp[i] < 0) continue;
      ans = min(ans, i);
    }
    cout << ans << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 3900
memory_kb: 3564
final_rank: 13

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

pair<int, int> comp(pair<int, int> a, pair<int, int> b) {
    return (a.second == b.second ? a.first > b.first : a.second > b.second) ? a : b;
}

bool solve() {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<pair<int, int>> dp(1, {N - 1, N - 1});
    for (int i = 1, x, y; i <= N; i++) {
        cin >> x >> y;
        vector<pair<int, int>> ndp(2 * i + 1, {-1, -1});
        for (int j = 0; j + 2 <= 2 * i; j++) {
            auto [a, b] = dp[j];
            if (dp[j] == make_pair(-1, -1)) continue;
            // 0
            {
                if (comp(dp[j], make_pair(x, y)) == dp[j]) {
                    ndp[j] = comp(ndp[j], make_pair(x, y));
                }
            }
            // 1
            {
                if (comp(dp[j], make_pair(a, y)) == dp[j]) {
                    ndp[j + 1] = comp(ndp[j + 1], make_pair(a, y));
                }
                if (comp(dp[j], make_pair(N - 1, y)) == dp[j]) {
                    ndp[j + 1] = comp(ndp[j + 1], make_pair(N - 1, y));
                }
                if (comp(dp[j], make_pair(x, b)) == dp[j]) {
                    ndp[j + 1] = comp(ndp[j + 1], make_pair(x, b));
                }
                if (b > 0 && comp(dp[j], make_pair(x, b - 1)) == dp[j]) {
                    ndp[j + 1] = comp(ndp[j + 1], make_pair(x, b - 1));
                }
            }
            // 2
            {
                ndp[j + 2] = comp(ndp[j + 2], dp[j]);
            }
        }
        dp = ndp;
    }
    for (int i = 0; i <= 2 * N; i++) {
        if (dp[i] != make_pair(-1, -1)) {
            cout << i << '\n';
            break;
        }
    }
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 4990
memory_kb: 3840
final_rank: 18

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using ull = unsigned long long;
template <class T>
using MaxHeap = std::priority_queue<T>;
template <class T>
using MinHeap = std::priority_queue<T, vector<T>, greater<T>>;
#define rep2(i, n) for (ll i = 0; i < (n); i++)
#define rep3(i, l, r) for (ll i = (l); i < (r); i++)
#define rrep2(i, n) for (ll i = n; i-- > 0;)
#define rrep3(i, r, l) for (ll i = (r); i-- > (l);)
#define overload(a, b, c, d, ...) d
#define rep(...) overload(__VA_ARGS__, rep3, rep2)(__VA_ARGS__)
#define rrep(...) overload(__VA_ARGS__, rrep3, rrep2)(__VA_ARGS__)
#define all(x) begin(x), end(x)
bool chmin(auto& lhs, auto rhs) {
    return lhs > rhs ? lhs = rhs, 1 : 0;
}
bool chmax(auto& lhs, auto rhs) {
    return lhs < rhs ? lhs = rhs, 1 : 0;
}
struct IOIO {
    IOIO() {
        std::cin.tie(0)->sync_with_stdio(0);
    }
} ioio;

void solve() {
    while (true) {
        int n;
        cin >> n;
        if (n == 0) return;
        vector<pair<int, int>> A(n);
        for (auto& [l, r]: A) cin >> r >> l;
        const int N = 2 * n;
        const pair<int, int> none = {-1, -1};
        vector<pair<int, int>> dp(N + 4, none);
        dp[0] = {n - 1, n - 1};
        rep(i, n) {
            auto [c, d] = A[i];
            rrep(j, N + 1) {
                if (dp[j] == none) continue;
                auto [a, b] = dp[j];

                chmax(dp[j + 2], dp[j]);

                if (b >= d) {
                    chmax(dp[j + 1], pair<int, int>{a, d});
                } else if (a - 1 >= 0) {
                    chmax(dp[j + 1], pair<int, int>{a - 1, d});
                }

                if (a > c) {
                    chmax(dp[j + 1], pair<int, int>{c, n - 1});
                } else if (a == c) {
                    chmax(dp[j + 1], pair<int, int>{c, b});
                }
                if (dp[j] >= A[i]) {
                    dp[j] = A[i];
                } else {
                    dp[j] = none;
                }
            }
        }
        rep(i, N + 1) {
            if (dp[i] != none) {
                cout << i << '\n';
                break;
            }
        }
    }
}

int main() {
    int t = 1;

    while (t--) solve();
}
accuracy: 1
time_ms: 1450
memory_kb: 3712
final_rank: 10

code_snippet: #include <iostream>
#include <cassert>
#include <vector>
#include <algorithm>
struct grade {
    int morning = -1, afternoon = -1;
    bool valid() const {
        return morning != -1 and afternoon != -1;
    }
};
bool operator==(const grade& p, const grade& q) {
    return p.morning == q.morning and p.afternoon == q.afternoon;
}
// pがqより成績が良いか？(一緒も許容)
bool compare(grade p, grade q) {
    if (p.afternoon != q.afternoon) return p.afternoon > q.afternoon; // 午後の成績
    else if (p.morning != q.morning) return p.morning > q.morning; // 午前の成績
    else return true; // 一緒の成績
}
void chmax(grade& p, grade q) {
    if (compare(q, p)) p = q;
}
int N;
int solve() {
    // dp[i][j] := 上からi人まで矛盾なく並べる方法であって、j個の要素を変更したときの最下位の最高スコア
    std::vector<grade> dp(1, {N - 1, N - 1});
    for (int i = 1 ; i <= N ; i++) {
        std::vector<grade> next(2 * i + 1);
        int X, Y;
        std::cin >> X >> Y;
        for (int j = 0 ; j < std::ssize(dp) ; j++) {
            if (!dp[j].valid()) continue;
            // 一つも変えないケース
            if (compare(dp[j], {X, Y})) chmax(next[j], {X, Y});
            // 午後を変えるケース
            if (compare(dp[j], {X, dp[j].afternoon - 1})) chmax(next[j + 1], {X, dp[j].afternoon - 1});
            if (compare(dp[j], {X, dp[j].afternoon})) chmax(next[j + 1], {X, dp[j].afternoon});
            // 午前を変えるケース
            if (compare(dp[j], {N - 1, Y})) chmax(next[j + 1], {N - 1, Y});
            else if (compare(dp[j], {dp[j].morning, Y})) chmax(next[j + 1], {dp[j].morning, Y});
            // 両方変えるケース
            if (compare(dp[j], dp[j])) chmax(next[j + 2], dp[j]);
        }
        dp = std::move(next);
    }
    for (int i = 0 ; i < std::ssize(dp) ; i++) if (dp[i].valid()) {
        return i;
    }
    assert(false);
    return -1;
}
int main() {
    while (true) {
        std::cin >> N;
        if (N == 0) break;
        std::cout << solve() << '\n';
    }
}
accuracy: 1
time_ms: 1070
memory_kb: 3820
final_rank: 11

code_snippet: // #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
// #include <atcoder/all>
using namespace std;
// using namespace atcoder;
#define rep(i, a, b) for(long long i = (a); i < (b); i++) // [a, b)を昇順に
#define drep(i, a, b) for(long long i = (b) - 1; i >= a; i--) // [a, b)を降順に
#define all(v) v.begin(), v.end() // 昇順sortに
#define rall(v) v.rbegin(), v.rend() // 降順sortに
#define sz(x) (int)(x).size()
#define decimal(n) cout << fixed << setprecision(n);
#define debug(x) cerr << #x << " = " << x << endl;
#define Yes cout << "Yes" << endl;
#define No cout << "No" << endl;
#define yesno(condition) { if (condition) cout << "Yes" << endl; else cout << "No" << endl; }
using vi = vector<int>; using vvi = vector<vi>; using vs = vector<string>;
using ll = long long; using vl = vector<ll>; using vvl = vector<vl>; using vvvl = vector<vvl>;
using lll = __int128;
// using mint = modint998244353;
const ll MOD = 998244353;
// using mint = modint;
// const ll MOD = 998244353;
// using mint = modint1000000007;
// const ll MOD = 1000000007;
// using vm = vector<mint>; using vvm = vector<vm>; using vvvm = vector<vvm>;
using P = pair<ll, ll>; using T = tuple<ll, ll, ll>;
using vc = vector<char>;
const ll MAX = 5'000'009; const ll llINF = 2e18;
const int intINF = 2e9; const long double pi = acos(-1);
ll di[] = {0, -1, 0, 1, -1, -1, 1, 1};
ll dj[] = {1, 0, -1, 0, 1, -1, -1, 1};
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 (b < a) { a = b; return 1; } return 0; }
template<class T> using pq = priority_queue<T, vector<T>>; //大きい順
template<class T> using pq_g = priority_queue<T, vector<T>, greater<T>>; //小さい順

bool isin(ll i, ll j, ll n, ll m) { return (0 <= i && i < n && 0 <= j && j < m); }
bool is_multipul_overflow(ll a, ll b, ll c) {
    // a * b > cかを判定する
    if (a == 0 || b == 0) return false;
    return (a <= c / b ? false : true);
}



void solve(int &n) {
    vector<int> x(n), y(n);
    rep(i, 0, n) cin >> x[i] >> y[i];
    rep(i, 0, n) {
        swap(x[i], y[i]);
        x[i] = (n - 1) - x[i];
        y[i] = (n - 1) - y[i];
    }

    vector<pair<int, int>> dp(2 * n + 1, {intINF, intINF});
    dp[0] = {0, 0};

    rep(i, 0, n) {

        vector<pair<int, int>> ndp(2 * n + 1, {intINF, intINF});
        rep(j, 0, 2 * n + 1) {
            if(dp[j].first == intINF) continue;
            
            // 書き換えない
            if(pair<int, int>(x[i], y[i]) >= dp[j]) {
                chmin(ndp[j], {x[i], y[i]});
            }
            
            // xを書き換える
            if(j + 1 < sz(ndp)) {
                // dp[j].second <= y[i] -> 前と同じ
                if(dp[j].second <= y[i]) chmin(ndp[j + 1], {dp[j].first, y[i]});
                // dp[j].second > y[i] -> 前 + 1
                else if(dp[j].first + 1 < n) chmin(ndp[j + 1], {dp[j].first + 1, y[i]});
            }
            
            // yを書き換える
            // dp[j].first <= x[i]が前提
            if(j + 1 < sz(ndp) && dp[j].first <= x[i]) {
                if(dp[j].first == x[i]) chmin(ndp[j + 1], {x[i], dp[j].second});
                else chmin(ndp[j + 1], {x[i], 0});
            }

            // x,yを書き換える
            if(j + 2 < sz(ndp)) {
                chmin(ndp[j + 2], dp[j]);
            }
        }

        swap(ndp, dp);
    }

    rep(i, 0, 2 * n + 1) {
        if(dp[i].first != intINF) {
            cout << i << endl;
            return ;
        }
    }
}

int main() {
    int n;
    string s;
    while(true) {
        cin >> n;
        if(n == 0) return 0;
        solve(n);
    }
    return 0;
}
accuracy: 1
time_ms: 1600
memory_kb: 3536
final_rank: 6

code_snippet: #pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pll = pair<ll, ll>;
using pii = pair<int, int>;

int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};

template <typename T> void print(vector<T> A);

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while (true) {
        auto comp = [](pii a, pii b) {
            if (a.second < b.second) {
                return true;
            } else if (a.second > b.second) {
                return false;
            }
            if (a.first <= b.first) {
                return true;
            }
            return false;
        };
        int N;
        cin >> N;
        if (N == 0) {
            break;
        }
        vector<pii> XY(N);
        for (auto &[x, y] : XY) {
            cin >> x >> y;
        }
        pii nul = {-1, -1}, max = {N - 1, N - 1};

        
        vector<pii> dp_1(2 * N + 3, nul);
        vector<pii> dp_2(2 * N + 3, nul);

        dp_1[0] = max;
        for (int i = 0; i < N; i++) {
            dp_2.assign(2*N+3,nul);
            for (int j = 0; j < 2 * N + 1; j++) {
                if (dp_1[j] == nul) {
                    continue;
                }
                // if (j<4 && i==2)cout<<j<<' '<<dp_1[j].first<<' '<<dp_1[j].second<<endl;

                pii now = dp_1[j], nex = XY[i];
                // k=0
                if (comp(nex, now) && comp(dp_2[j], nex)) {
                    dp_2[j] = nex;
                }

                // k=1
                nex.second = now.second;
                if (comp(nex, now) && comp(dp_2[j + 1], nex)) {
                    dp_2[j + 1] = nex;
                }
                pii nex_2 = nex;
                nex_2.second -= 1;
                if (nex_2.second >= 0 && comp(nex_2, now) &&
                    comp(dp_2[j + 1], nex_2)) {
                    dp_2[j + 1] = nex_2;
                }

                pii nex_3 = XY[i];
                if (nex_3.second == now.second) {
                    nex_3.first = now.first;
                } else if (nex_3.second < now.second) {
                    nex_3.first = N - 1;
                }
                if (comp(nex_3, now) && comp(dp_2[j + 1], nex_3)) {
                    dp_2[j + 1] = nex_3;
                }

                // k=2
                nex.first = now.first;
                if (comp(nex, now) && comp(dp_2[j + 2], nex)) {
                    dp_2[j + 2] = nex;
                }
            }
            swap(dp_1,dp_2);
        }
        for (int j = 0; j < 2 * N + 1; j++) {
            if (dp_1[j] != nul) {
                cout << j << endl;
                break;
            }
        }
    }
}

template <typename T> void print(vector<T> A) {
    for (int i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}
accuracy: 1
time_ms: 1410
memory_kb: 3472
final_rank: 3

code_snippet: // AOJ 1668 Tampered Records
// 2025.5.3

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

#define gc() getchar_unlocked()
#define pc(c) putchar_unlocked(c)

int Cin() {
	int n = 0; int c = gc();
	do n = 10*n + (c & 0xf), c = gc(); while (c >= '0');
	return n;
}

void Cout(int n) {
	int i; char b[30];
	if (!n) pc('0');
	else {
		i = 0; while (n) b[i++] = n % 10 + '0', n /= 10;
		while (i--) pc(b[i]);
	}
	pc('\n');
}

const int MAXN = 6000;
int dpA[2*MAXN+5], dpM[2*MAXN+5];
int nxtA[2*MAXN+5], nxtM[2*MAXN+5];

inline void try_update(int j, int na, int nm) {
    int &a = nxtA[j], &m = nxtM[j];
    if (a < na || (a == na && m < nm)) a = na, m = nm;
}

int main(){
    while (true) {
        int n = Cin();
        if (n == 0) break;
        vector<int> x(n), y(n);
        for (int i = 0; i < n; i++) x[i] = Cin(), y[i] = Cin();

        int dsz = 3;
        dpA[0] = y[0], dpM[0] = x[0];
        dpA[1] = n-1, dpM[1] = x[0];
        dpA[2] = n-1, dpM[2] = n-1;

        for (int i = 1; i < n; i++) {
            int yi = y[i], xi = x[i];
            int mi = min(dsz, 2*i + 1);
            int nsz = min(n + 1, 2*i + 3);

            for (int j = 0; j < nsz; j++) nxtA[j] = nxtM[j] = -1;
            for (int j = 0; j < mi; j++) {
                int a_last = dpA[j], m_last = dpM[j];
                if (a_last < 0) continue;

                if (a_last > yi || (a_last == yi && m_last >= xi))
                    try_update(j, yi, xi);

                if (j + 1 <= n) {
                    if (a_last >= yi) try_update(j+1, yi, m_last);
                    if (a_last >  yi) try_update(j+1, yi, n-1);
                    if (m_last >= xi) try_update(j+1, a_last, xi);
                    if (a_last >  0)  try_update(j+1, a_last-1, xi);
                }

                if (j + 2 <= n) {
                    try_update(j+2, a_last, m_last);
                    if (a_last > 0) try_update(j+2, a_last-1, n-1);
                }
            }
            dsz = nsz;
            for (int j = 0; j < dsz; j++) {
                dpA[j] = nxtA[j];
                dpM[j] = nxtM[j];
            }
        }
        int ans = 2*n;
        for (int j = 0; j < dsz; j++) if (dpA[j] >= 0) { ans = j; break; }
        Cout(ans);
    }
    return 0;
}
accuracy: 1
time_ms: 1030
memory_kb: 3356
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
// using mint = modint998244353;
// using mint = modint1000000007;
using ll  = long long;
using ull = unsigned long long;
#define rep(i, n) for(ll i = 0; i < n; i++)
constexpr ll INF = ((1LL << 61) + (1LL << 30) - 1);

struct Point {
  ll x, y;
  Point() {}
  Point(ll _x, ll _y): x(_x), y(_y) {}
  bool operator<(const Point& p) const {
    return (x == p.x ? y < p.y : x < p.x);
  }
  bool operator>(const Point& p) const {
    return (x == p.x ? y > p.y : x > p.x);
  }
  bool operator<=(const Point& p) const {
    return (x == p.x ? y <= p.y : x <= p.x);
  }
  bool operator>=(const Point& p) const {
    return (x == p.x ? y >= p.y : x >= p.x);
  }
  bool operator==(const Point& p) const {
    return (x == p.x && y == p.y);
  }
};

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

  while(true) {
    ll n;
    cin >> n;
    if(n == 0) break;
    vector<Point> points(n);
    rep(i, n) cin >> points[i].y >> points[i].x;

    // 答えは高々 N 以下
    // 基本的に上位から見て貪欲？
    // ただ、順位が 1 個上の午後に合わせたときに 1 個上を超す場合は午前も修正する必要あり
    // これがボトルネックになる場合は、最初から午後を操作していた方が良さそう

    // 上位から見て過去に x 回改ざんした時の、1 個上の値として存在する最大のスコアで DP ?
    // vector<vector<Point>> dp(n + 1, vector<Point>(n + 1, Point(-1, -1)));
    vector<Point> dp(n + 1, Point(-1, -1));
    dp[0] = Point(n - 1, n - 1);
    rep(i, n) {
      vector<Point> next(n + 1, Point(-1, -1));
      rep(j, n + 1) {
        if(dp[j] == Point(-1, -1)) continue;
        // 改竄をしない時
        if(dp[j] >= points[i]) {
          next[j] = max(next[j], points[i]);
        }

        // 1 つだけ改竄する時
        Point cand1 = points[i], cand2 = points[i];
        cand1.x = dp[j].x;
        if(cand1 > dp[j]) cand1.x--;
        if(cand1.x < 0) cand1 = Point(-1, -1);

        cand2.y = (cand2.x == dp[j].x ? dp[j].y : n - 1);
        if(cand2 > dp[j]) cand2 = Point(-1, -1);

        if(j + 1 < n + 1) next[j + 1] = max(next[j + 1], max(cand1, cand2));

        // 2 つ改竄する時
        if(j + 2 < n + 1) next[j + 2] = max(next[j + 2], dp[j]);
      }
      swap(dp, next);
    }

    // rep(i, n + 1) {
    //   rep(j, n + 1) cerr << "(" << dp[i][j].x << ", " << dp[i][j].y << ") ";
    //   cerr << endl;
    // }
    rep(i, n + 1) {
      if(dp[i] == Point(-1, -1)) continue;
      cout << i << endl;
      break;
    }
  }

  return 0;
}
accuracy: 1
time_ms: 1290
memory_kb: 3308
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define OVERLOAD_REP(_1, _2, _3, _4, name, ...) name
#define REP1(n) for(ll i=0;i<n;i++)
#define REP2(i, n) for (ll i=0;i<n;i++)
#define REP3(i, a, n) for (ll i=a;i<n;i++)
#define REP4(i, a, b, n) for(ll i=a;i<n;i+=b)
#define rep(...) OVERLOAD_REP(__VA_ARGS__, REP4, REP3, REP2, REP1)(__VA_ARGS__)
#define OVERLOAD_RREP(_1, _2, _3, _4, name, ...) name
#define RREP1(n) for(ll i=n;i>=0;i--)
#define RREP2(i, n) for(ll i=n;i>=0;i--)
#define RREP3(i, a, n) for(ll i=n;i>=a;i--)
#define RREP4(i, a, b, n) for(ll i=n;i>=a;i-=b)
#define rrep(...) OVERLOAD_RREP(__VA_ARGS__, RREP4, RREP3, RREP2, RREP1)(__VA_ARGS__)
#define foa(a,v)  (auto& a : (v))
#define uniq(a) sort(all(a));a.erase(unique(all(a)),end(a))
#define len(n) (long long)(n).size()
#define pb push_back
using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vs = vector<string>;
using vvs = vector<vs>;
using vvvs = vector<vvs>;
using vld = vector<ld>;
using vvld = vector<vld>;
using vvvld = vector<vvld>;
using vc = vector<char>;
using vvc = vector<vc>;
using vvvc = vector<vvc>;
using pll = pair<ll,ll>;
using vpll = vector<pll>;
template<class... T>
constexpr auto min(T... a){
    return min(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
constexpr auto max(T... a){
    return max(initializer_list<common_type_t<T...>>{a...});
}
template<class... T>
void input(T&... a){
    (cin >> ... >> a);
}
ll modpow(ll a,ll b,ll c){
    ll ans = 1;
    while (b){
        if (b & 1){
            ans *= a;
            ans %= c;
        }
        a *= a;
        a %= c;
        b /= 2;
    }
    return ans;
}
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define ULL(...) ull __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHA(...) char __VA_ARGS__; input(__VA_ARGS__)
#define VLL(name,length) vll name(length);rep(i,length){cin >> name[i];}
#define VVLL(name,h,w) vvll name(h,vll(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLL(name,a,b,c) vvvll name(a,vvll(b,vll(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VI(name,length) vi name(length);rep(i,length){cin >> name[i];}
#define VVI(name,h,w) vvi name(h,vi(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVI(name,a,b,c) vvvi name(a,vvll(b,vi(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VLD(name,length) vld name(length);rep(i,length){cin >> name[i];}
#define VVLD(name,h,w) vvld name(h,vld(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVLD(name,a,b,c) vvvld name(a,vvld(b,vld(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VC(name,length) vc name(length);rep(i,length){cin >> name[i];}
#define VVC(name,h,w) vvc name(h,vc(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVC(name,a,b,c) vvvc name(a,vvc(b,vc(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define VS(name,length) vs name(length);rep(i,length){cin >> name[i];}
#define VVS(name,h,w) vvs name(h,vs(w));rep(i,h)rep(j,w){cin >> name[i][j];}
#define VVVS(name,a,b,c) vvvs name(a,vvs(b,vs(c)));rep(i,a)rep(j,b)rep(k,c){cin >> name[i][j][k];}
#define PLL(name) pll name;cin>>name.first>>name.second;
#define VPLL(name,length) vpll name(length);rep(i,length){cin>>name[i].first>>name[i].second;}

void print(){cout << "\n";}
template<class T, class... Ts>
void print(const T& a, const Ts&... b){cout << a;(cout << ... << (cout << ' ', b));cout << '\n';}
void print(vll x){rep(i,len(x)){cout << x[i];if(i!=len(x)-1){cout << " ";}else{cout << '\n';}}}
void print(vvll x){rep(i,len(x))rep(j,len(x[i])){cout << x[i][j];if(j!=len(x[i])-1){cout << " ";}else{cout << '\n';}}}

void solve(ll n,vpll a){
    vll dp(2*n+1,-1LL<<60);
    dp[0] = n*n-1;
    rep(i,n){
        vll ndp(2*n+1,-1LL<<60);
        rep(j,2*n+1){
            if(dp[j] == (-1LL<<60)){continue;}
            if(dp[j] >= a[i].first + a[i].second * n){
                ndp[j] = max(ndp[j],a[i].first + a[i].second * n);
            }
            if(j+2 < 2*n+1){
                ndp[j+2] = max(ndp[j+2],dp[j]);
            }
            if(j+1 < 2*n+1){
                if(dp[j] % n >= a[i].first){
                    ndp[j+1] = max(ndp[j+1],dp[j] / n * n + a[i].first);
                    //print(i,j,dp[i][j] / n * n + a[i].first);
                }
                else if((dp[j] / n - 1) >= 0){
                    ndp[j+1] = max(ndp[j+1],(dp[j] / n - 1) * n + a[i].first);
                    //print(i,j,(dp[i][j] / n - 1) * n + a[i].first);
                }
                if(dp[j] / n > a[i].second){
                    ndp[j+1] = max(ndp[j+1],a[i].second * n + n - 1);
                    //print(i,j,a[i].second * n + n - 1);
                }
                else if(dp[j] / n == a[i].second){
                    ndp[j+1] = max(ndp[j+1],dp[j]);
                    //print(i,j,dp[i][j]);
                }
                else{
                    ;
                }
            }
        }
        swap(dp,ndp);
    }
    //print(dp);
    rep(i,2*n+1){
        if(dp[i] != (-1LL<<60)){
            print(i);
            return;
        }
    }
}

int main(){
    while(1){
        LL(n);
        if(n == 0){break;}
        VPLL(a,n);
        solve(n,a);
    }
}
accuracy: 1
time_ms: 1590
memory_kb: 3968
final_rank: 16

code_snippet: #include <iostream>
#include <vector>
#include <utility>

using namespace std;

constexpr int iINF = 1'000'000'000;

int cmp (const pair<int, int>& x, const pair<int, int>& y) {
    if (x.second == y.second) {
        if (x.first == y.first) return 0;
        return x.first < y.first ? -1 : 1;
    }
    return x.second < y.second ? -1 : 1;
}

int main () {
    while (true) {
        int n; cin >> n;
        if (n == 0) break;

        vector<int> x(n), y(n);
        for (int i = 0; i < n; i++) {
            cin >> x[i] >> y[i];
        }

        // dp[i][j] := 昇順にi個処理して、変更j回をしたとき、作れる最も小さいスコア
        vector<pair<int, int>> dp(n + 1), ndp(n + 1);
        for (int i = 0; i < n + 1; i++) {
            dp[i] = make_pair(iINF, iINF);
        }
        dp[0] = make_pair(0, 0);

        for (int i = n - 1; 0 <= i; i--) {
            for (int j = 0; j < n + 1; j++) {
                ndp[j] = make_pair(iINF, iINF);
            }

            for (int j = 0; j < n + 1; j++) {
                if (dp[j] == make_pair(iINF, iINF)) continue;

                auto cur = make_pair(x[i], y[i]);
                // 変更0回
                if (cmp(dp[j], cur) <= 0) {
                    if (cmp(cur, ndp[j]) <= 0) {
                        ndp[j] = cur;
                    }
                }

                if (j == n) continue;
                // 変更1回
                // どちらを変更するかで分ける。

                // 午前の部
                if (x[i] != 0
                        && cmp(dp[j], make_pair(0, y[i])) <= 0
                        && cmp(make_pair(0, y[i]), ndp[j + 1]) <= 0) {
                    ndp[j + 1] = make_pair(0, y[i]);
                }
                if (x[i] != dp[j].first
                        && cmp(dp[j], make_pair(dp[j].first, y[i])) <= 0
                        && cmp(make_pair(dp[j].first, y[i]), ndp[j + 1]) <= 0) {
                    ndp[j + 1] = make_pair(dp[j].first, y[i]);
                }

                // 午後の部
                if (y[i] != dp[j].second
                        && cmp(dp[j], make_pair(x[i], dp[j].second)) <= 0
                        && cmp(make_pair(x[i], dp[j].second), ndp[j + 1]) <= 0) {
                    ndp[j + 1] = make_pair(x[i], dp[j].second);
                }
                if (y[i] != dp[j].second + 1
                        && dp[j].second + 1 < n
                        && cmp(dp[j], make_pair(x[i], dp[j].second + 1)) <= 0
                        && cmp(make_pair(x[i], dp[j].second + 1), ndp[j + 1]) <= 0) {
                    ndp[j + 1] = make_pair(x[i], dp[j].second + 1);
                }

                if (j == n - 1) continue;
                // 変更2回
                // この場合は前とピッタリ合わせればok
                if (dp[j].first != x[i] && dp[j].second != y[i]) {
                    if (cmp(dp[j], ndp[j + 2]) <= 0) {
                        ndp[j + 2] = dp[j];
                    }
                }
            }

            swap(dp, ndp);
        }

        int ans = -1;
        for (int i = 0; i < n + 1; i++) {
            if (dp[i] != make_pair(iINF, iINF)) {
                ans = i;
                break;
            }
        }

        cout << ans << "\n";
    }
}
accuracy: 1
time_ms: 800
memory_kb: 3712
final_rank: 8

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

#define rep2(i, m, n) for (int i = (m); i < (n); ++i)
#define rep(i, n) rep2(i, 0, n)
#define drep2(i, m, n) for (int i = (m)-1; i >= (n); --i)
#define drep(i, n) drep2(i, n, 0)
#define all(...) std::begin(__VA_ARGS__), std::end(__VA_ARGS__)
#define rall(...) std::rbegin(__VA_ARGS__), std::rend(__VA_ARGS__)
#define FOR(i, a, b) for (int i = (a), i##_len = (b); i <= i##_len; ++i)
#define REV(i, a, b) for (int i = (a); i >= (b); --i)
#define CLR(a, b) memset((a), (b), sizeof(a))
#define DUMP(x) cout << #x << " = " << (x) << endl;
#define INF 1001001001001001001ll
#define inf (int)1001001000
#define MOD 998244353
#define MOD1 1000000007
#define PI 3.14159265358979
#define Dval 1e-12
#define fcout cout << fixed << setprecision(12)
#define MP make_pair
#define PB push_back
#define fi first
#define se second
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())

using ll = long long;
using ld = long double;
using vi = vector<int>;
using vl = vector<long long>;
using vs = vector<string>;
using vd = vector<double>;
using vld = vector<long double>;
using vc = vector<char>;
using vb = vector<bool>;
using vpii = vector<pair<int, int>>;
using vpil = vector<pair<int, long long>>;
using vpll = vector<pair<long long, long long>>;
using vvi = vector<vector<int>>;
using vvl = vector<vector<long long>>;
using vvd = vector<vector<double>>;
using vvld = vector<vector<long double>>;
using vvc = vector<vector<char>>;
using vvb = vector<vector<bool>>;
using vvpii = vector<vector<pair<int,int>>>;
using vvpll = vector<vector<pair<long long,long long>>>;
using vvvi = vector<vector<vector<int>>>;
using vvvl = vector<vector<vector<long long>>>;
using pii = pair<int, int>;
using pll = pair<long long, long long>;

ll gcd(ll x, ll y) {	if (x == 0) return y;	return gcd(y%x, x);} 
template<typename T>
T POW(T x, ll n){T ret=1;	while(n>0){		if(n&1) ret=ret*x;		x=x*x;		n>>=1;	}	return ret;}
template<typename T>
T modpow(T a, ll n, T p) {	if(n==0) return (T)1;  if (n == 1) return a % p;  if (n % 2 == 1) return (a * modpow(a, n - 1, p)) % p;  T t = modpow(a, n / 2, p);  return (t * t) % p;}
template<typename T>
T modinv(T a, T m) {	if(m==0)return (T)1;	T b = m, u = 1, v = 0;	while (b) {		T t = a / b;		a -= t * b; swap(a, b);		u -= t * v; swap(u, v);	}	u %= m;	if (u < 0) u += m;	return u;}
template<typename T>
T REM(T a, T b){ return (a % b + b) % b;}
template<typename T>
T QUO(T a, T b){ return (a - REM(a, b)) / b;}
/* 
const int MAXCOMB=510000;
ll MODCOMB = 998244353;
ll fac[MAXCOMB], finv[MAXCOMB], inv[MAXCOMB]; 
void COMinit() {	fac[0] = fac[1] = 1;	finv[0] = finv[1] = 1;	inv[1] = 1;	for (int i = 2; i < MAXCOMB; i++) {		fac[i] = fac[i - 1] * i % MODCOMB;		inv[i] = MODCOMB - inv[MODCOMB%i] * (MODCOMB / i) % MODCOMB;		finv[i] = finv[i - 1] * inv[i] % MODCOMB;	}}
ll COM(ll n, ll k) {	if (n < k) return 0;	if (n < 0 || k < 0) return 0;	return fac[n] * (finv[k] * finv[n - k] % MODCOMB) % MODCOMB;}
ll com(ll n,ll m){   if(n<m || n<=0 ||m<0){		return 0;	}	if( m==0 || n==m){		return 1;	}	ll k=1;	for(ll i=1;i<=m;i++){       k*=(n-i+1); 	   k%=MODCOMB;	   k*=modinv(i,MODCOMB);	   k%=MODCOMB;	}	return k;}
*/
/*
const int MAXCOMB=510000;
std::vector<mint> fac(MAXCOMB), finv(MAXCOMB), inv(MAXCOMB);
void COMinit() {fac[0] = fac[1] = 1;finv[0] = finv[1] = 1;inv[1] = 1;for (int i = 2; i < MAXCOMB; i++) {fac[i] = fac[i - 1] * i;inv[i] = mint(0) - inv[mint::mod() % i] * (mint::mod() / i);finv[i] = finv[i - 1] * inv[i];}}
mint COM(int n, int k) {if (n < k) return 0;if (n < 0 || k < 0) return 0;return fac[n] * finv[k] * finv[n - k];}
*/
template <typename T> inline bool chmax(T &a, T b) { return ((a < b) ? (a = b, true) : (false));}
template <typename T> inline bool chmin(T &a, T b) { return ((a > b) ? (a = b, true) : (false));}
template <class T> T BS(vector<T> &vec, T key) { auto itr = lower_bound(vec.begin(), vec.end(), key); return distance(vec.begin(), itr); }
template<class T> pair<T,T> RangeBS(vector<T> &vec, T lowv, T highv){auto itr_l = lower_bound(vec.begin(), vec.end(), lowv); auto itr_r = upper_bound(vec.begin(), vec.end(), highv); return make_pair(distance(vec.begin(), itr_l), distance(vec.begin(), itr_r)-1);}
void fail() { cout << "-1\n"; exit(0); } void no() { cout << "No\n"; exit(0); } void yes() { cout << "Yes\n"; exit(0); }
template<class T> void er(T a) { cout << a << '\n'; exit(0); }
int dx[] = { 1,0,-1,0,1,1,-1,-1 }; int dy[] = { 0,1,0,-1,1,-1,1,-1};
bool range_in(int i, int j, int h, int w){ if(i<0 || j<0 || i>=h || j>=w) return false; return true;} 
int bitcount(int n){n=(n&0x55555555)+(n>>1&0x55555555); n=(n&0x33333333)+(n>>2&0x33333333); n=(n&0x0f0f0f0f)+(n>>4&0x0f0f0f0f); n=(n&0x00ff00ff)+(n>>8&0x00ff00ff); n=(n&0x0000ffff)+(n>>16&0x0000ffff); return n;}

template<typename T>
struct Edge{
    int from, to, index;
    T cost;
    Edge(int _to) : from(-1), to(_to), index(-1), cost(0) {}
    Edge(int _to, T _cost) : from(-1), to(_to), index(-1), cost(_cost) {}
    Edge(int _from, int _to, int _index) : from(_from), to(_to), index(_index), cost(0) {}
    Edge(int _from, int _to, int _index, T _cost) 
        : from(_from), to(_to), index(_index), cost(_cost) {}
    bool operator<(const Edge<T>& other) const {
        return cost < other.cost; 
    }
    Edge &operator=(const int &x) {
        to = x;
        return *this;
    }
    operator int() const { return to; }
};
using Graph = vector<vector<int>>; 
template <typename T>
using WGraph = vector<vector<Edge<T>>>; 

 int TESTFIN = 0;

void solve(){
    int n;
    cin>>n;
    if(n==0){TESTFIN = 1; return;}
    vpii pr(n);
    rep(i,n)cin>>pr[i].se>>pr[i].fi;
    vvpii dp(2,vpii(n*2+1,{-1,-1}));
    for(int i=0;i<n;i++){
        if(i==0){
            dp[0][0] = pr[i];
            if(pr[i].fi==n-1 || pr[i].se==n-1) dp[0][1] = {n-1,n-1};
            else dp[0][1] = {n-1,pr[i].se};
            dp[0][2]= {n-1,n-1};
            continue;
        }
        for(int j=0;j<=n*2;j++){
            for(int k=0;k<=2;k++){
                if(j-k<0)continue;
                if(k==2){
                    if(dp[0][j-k].fi!=-1){
                        chmax(dp[1][j],dp[0][j-k]);
                    }
                }
                if(k==1){
                    if(dp[0][j-k].fi==-1)continue;
                    int a = (dp[0][j-1].fi>=pr[i].fi);
                    int b = (dp[0][j-1].se>=pr[i].se);
                    if(a==1 && b==1){
                        if(dp[0][j-1].fi==pr[i].fi){
                            chmax(dp[1][j],dp[0][j-1]);
                        }
                        else chmax(dp[1][j],{dp[0][j-1].fi,pr[i].se});
                    }
                    if(a==1 && b==0){
                        if(pr[i].fi<dp[0][j-1].fi-1)chmax(dp[1][j],{dp[0][j-1].fi-1,pr[i].se});
                        else if(pr[i].fi==dp[0][j-1].fi)chmax(dp[1][j],dp[0][j-1]);
                        else chmax(dp[1][j],{dp[0][j-1].fi-1,n-1});
                    }
                    if(a==0 && b==1){
                        chmax(dp[1][j],{dp[0][j-1].fi,pr[i].se});
                    }
                    if(a==0 && b==0){ chmax(dp[1][j],{dp[0][j-1].fi-1,pr[i].se});}
                }
                if(k==0){
                    if(dp[0][j-k].fi==-1)continue;
                    
                    if(dp[0][j]>=pr[i])chmax(dp[1][j],pr[i]);
                }
            }
            
        }
        rep(j,2*n+1)dp[0][j]=dp[1][j];
        rep(j,2*n+1)dp[1][j]={-1,-1};
    }
    for(int i=0;i<=n*2;i++){
        if(dp[0][i].fi!=-1){
            cout<<i<<endl;
            return;
        }
    }
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	while(TESTFIN==0) solve();
}
accuracy: 1
time_ms: 5260
memory_kb: 3584
final_rank: 17

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int main() {
while(1) {
    int N;
    cin >> N;
    if (N == 0) return 0;
    vector<int> A(N), B(N), C(N);
    rep(i,0,N) {
        int X, Y;
        cin >> X >> Y;
        X = N - 1 - X, Y = N - 1 - Y;
        swap(X,Y);
        A[i] = X, B[i] = Y, C[i] = A[i]*N+B[i];
    }
    int MAXS = N*2+1;
    vector<int> DP(MAXS,inf);
    DP[0] = 0;
    rep(i,0,N) {
        vector<int> NewDP(MAXS,inf);
        rep(j,0,MAXS) {
            if (DP[j] == inf) continue;
            if (DP[j] <= C[i]) chmin(NewDP[j],C[i]);
            if (DP[j] < N*(A[i]+1)) chmin(NewDP[j+1],max(DP[j],N*A[i]));
            if (DP[j] <= N*(N-1)+B[i]) chmin(NewDP[j+1],((DP[j]-B[i]+N-1)/N)*N+B[i]);
            chmin(NewDP[j+2],DP[j]);
        }
        rep(j,0,MAXS) DP[j] = NewDP[j];
    }
    rep(i,0,MAXS) {
        if (DP[i] < inf) {
            cout << i << endl;
            break;
        }
    }
}
}
accuracy: 1
time_ms: 1840
memory_kb: 3492
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<vvvb> vvvvb;
typedef pair<ll,ll> pi;
typedef pair<ll,pi> ppi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
#define sz(A) (ll)(A.size())
#define ALL(A) A.begin(),A.end()
#define LB(A,x) (ll)(lower_bound(ALL(A),x)-A.begin())
#define UB(A,x) (ll)(upper_bound(ALL(A),x)-A.begin())
#define COU(A,x) (UB(A,x)-LB(A,x))
#define F first
#define S second
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
template<typename T1,typename T2>ostream&operator<<(ostream&os,pair<T1,T2>&p){os<<p.F<<" "<<p.S;return os;}
template<typename T1,typename T2>istream&operator>>(istream&is,pair<T1,T2>&p){is>>p.F>>p.S;return is;}
template<typename T>ostream&operator<<(ostream&os,vector<T>&v){REP(i,sz(v))os<<v[i]<<(i+1!=sz(v)?" ":"");return os;}
template<typename T>istream&operator>>(istream&is,vector<T>&v){for(T&in:v)is>>in;return is;}
template<class T>bool chmax(T&a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T&a,T b){if(b<a){a=b;return 1;}return 0;}
const ll mod=998244353;
int main(){
    while(1){
        int N;cin>>N;
        if(!N)return 0;
        vector<pair<int,int>>A(N);
        cin>>A;
        REP(i,N)swap(A[i].F,A[i].S);
        vector<pair<int,int>>DP(N+1,make_pair(-1,-1));
        DP[0]=make_pair(N-1,N-1);
        REP(i,N){
            vector<pair<int,int>>EP(N+1,make_pair(-1,-1));
            REP(j,N+1){
                if(DP[j]>=A[i])chmax(EP[j],A[i]);
                if(j+2<=N)chmax(EP[j+2],DP[j]);
                if(j+1<=N){
                    if(A[i].S<=DP[j].S)chmax(EP[j+1],make_pair(DP[j].F,A[i].S));
                    else chmax(EP[j+1],make_pair(DP[j].F-1,A[i].S));
                    if(DP[j].F==A[i].F)chmax(EP[j+1],DP[j]);
                    else if(DP[j].F>A[i].F)chmax(EP[j+1],make_pair(A[i].F,N-1));
                }
            }
            DP=EP;
        }
        ll ans=N;
        REP(i,N+1)if(DP[i].F>=0)chmin(ans,i);
        cout<<ans<<endl;
    }
    return 0;
}
accuracy: 1
time_ms: 1660
memory_kb: 3528
final_rank: 5

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)
 
#include <bits/stdc++.h>
// #include <atcoder/all>
// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vc<vv<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const double pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(long long y, long long x, long long H, long long W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}
template<typename T> void view(const vv<T>& vv){ for(const auto& v : vv){ view(v); } }
template<typename T> void view(const set<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}

int solve(int N){
    vi x(N), y(N); rep(i, N) cin >> x[i] >> y[i];
    pair<int, int> e = {-1, -1};
    vv<pair<int, int>> dp(2, vc<pair<int, int>>(2 * N + 1, e));
    int nw = 0, nxt = 1;
    dp[nw][0] = {N - 1, N - 1};
    rep(i, N){
        rep(j, 2 * N + 1) dp[nxt][j] = e;
        rep(j, 2 * N + 1){
            auto [ny, nx] = dp[nw][j];
            if (ny > y[i] || (ny == y[i] && nx >= x[i])) dp[nxt][j] = max(dp[nxt][j], {y[i], x[i]});
            if (j < 2 * N && ny == y[i]) dp[nxt][j + 1] = max(dp[nxt][j + 1], {y[i], nx});
            if (j < 2 * N && ny > y[i]) dp[nxt][j + 1] = max(dp[nxt][j + 1], {y[i], N - 1});
            if (j < 2 * N && nx >= x[i]) dp[nxt][j + 1] = max(dp[nxt][j + 1], {ny, x[i]});
            if (j < 2 * N && ny > 0) dp[nxt][j + 1] = max(dp[nxt][j + 1], {ny - 1, x[i]});
            if (j < 2 * N - 1) dp[nxt][j + 2] = max(dp[nxt][j + 2], dp[nw][j]);
        }
        swap(nw, nxt);
    }
    rep(j, 2 * N + 1) if (dp[nw][j] != e) return j;
    return -1;
}

int main(){
    vi ans;
    while (true){
        int N; cin >> N;
        if (N == 0) break;
        ans.push_back(solve(N));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 3280
memory_kb: 3712
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;

int main(void) {
    while(1) {
        int n;
        cin >> n;

        if(n == 0) break;

        vector<P> a(n);
        rep(i, 0, n) {
            cin >> a[i].second;
            cin >> a[i].first;
        }

        vector<P> dp(2*n+1, {-1, -1});
        dp[0] = {n-1, n-1};

        rep(i, 0, n) {
            vector<P> ndp(2*n+1, {-1, -1});
            rep(j, 0, 2*n+1) {
                if(j-2 >= 0) ndp[j] = max(ndp[j], dp[j-2]);
                if(j-1 >= 0) {
                    if(dp[j-1] >= P{dp[j-1].first, a[i].second}) ndp[j] = max(ndp[j], P{dp[j-1].first, a[i].second});
                    if(dp[j-1] >= P{a[i].first, dp[j-1].second}) ndp[j] = max(ndp[j], P{a[i].first, dp[j-1].second});
                    if(dp[j-1] >= P{a[i].first, n}) ndp[j] = max(ndp[j], P{a[i].first, n});
                    if(dp[j-1].first-1>=0 and dp[j-1] >= P{dp[j-1].first-1, a[i].second}) ndp[j] = max(ndp[j], P{dp[j-1].first-1, a[i].second});
                }
                if(dp[j] >= a[i]) ndp[j] = max(ndp[j], a[i]);
                // cout << i << ' ' << j  << ' ' << ndp[j].first << ' ' << ndp[j].second << '\n';
            }
            swap(dp, ndp);
        }
        rep(i, 0, 2*n+1) if(dp[i] != P{-1, -1}) {
            cout << i << '\n';
            break;
        }
    }
}
accuracy: 1
time_ms: 3280
memory_kb: 3640
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
int main(void) {
    while(1) {
        int n;
        cin >> n;
        if(n == 0) break;
        vector<pair<int, int>> p(n);
        rep(i, 0, n) {
            cin >> p[i].first >> p[i].second;
            swap(p[i].first, p[i].second);
        }
        vector<pair<int, int>> dp(2 * n + 1, {-1, -1});
        dp[0] = {n - 1, n - 1};
        rep(i, 1, n + 1) {
            vector<pair<int, int>> ndp(2 * n + 1, {-1, -1});
            rep(j, 0, 2 * n + 1) {
                if(p[i - 1] <= dp[j]) {
                    ndp[j] = max(ndp[j], p[i - 1]);
                }
                if(j - 1 >= 0 and (dp[j - 1].first != -1 and dp[j - 1].second != -1)) {
                    if(p[i - 1].second <= dp[j - 1].second) {
                        if(p[i - 1].first == dp[j - 1].first) {
                            ndp[j] = max(ndp[j], dp[j - 1]);
                        } else {
                            ndp[j] = max(ndp[j], {dp[j - 1].first, p[i - 1].second});
                        }
                    } else {
                        if(p[i - 1].first == dp[j - 1].first) {
                            ndp[j] = max(ndp[j], dp[j - 1]);
                        } else {
                            if(p[i - 1].first == dp[j - 1].first - 1) {
                                ndp[j] = max(ndp[j], {p[i - 1].first, n - 1});
                            } else {
                                ndp[j] = max(ndp[j], {dp[j - 1].first - 1, p[i - 1].second});
                            }
                        }
                    }
                }
                if(j - 2 >= 0 and (dp[j - 2].first != -1 and dp[j - 2].second != -1)) {
                    ndp[j] = max(ndp[j], dp[j - 2]);
                }
            }
            swap(dp, ndp);
        }
        // rep(i, 0, n + 1) {
        //     rep(j, 0, 2 * n + 1) {
        //         cout << i << ' ' << j << ' ' << dp[i][j].first << ' ' << dp[i][j].second << '\n';
        //     }
        // }
        int ans = 2 * n + 1;
        rep(i, 0, 2 * n + 1) {
            if(dp[i].first != -1 and dp[i].second != -1) {
                ans = i;
                break;
            }
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 1890
memory_kb: 3516
final_rank: 7