Phoenix is trying to take a photo of his n friends with labels 1, 2, ..., n who are lined up in a row in a special order. But before he can take the photo, his friends get distracted by a duck and mess up their order.

Now, Phoenix must restore the order but he doesn't remember completely! He only remembers that the i-th friend from the left had a label between a_i and b_i inclusive. Does there exist a unique way to order his friends based of his memory? 

Input

The first line contains one integer n (1 ≤ n ≤ 2⋅10^5) — the number of friends.

The i-th of the next n lines contain two integers a_i and b_i (1 ≤ a_i ≤ b_i ≤ n) — Phoenix's memory of the i-th position from the left.

It is guaranteed that Phoenix's memory is valid so there is at least one valid ordering.

Output

If Phoenix can reorder his friends in a unique order, print YES followed by n integers — the i-th integer should be the label of the i-th friend from the left.

Otherwise, print NO. Then, print any two distinct valid orderings on the following two lines. If are multiple solutions, print any.

Examples

Input


4
4 4
1 3
2 4
3 4


Output


YES
4 1 2 3 


Input


4
1 3
2 4
3 4
2 3


Output


NO
1 3 4 2 
1 2 4 3 
#include <bits/stdc++.h>
using namespace std;
const int MaxN = 200005;
struct SegmentTree {
  vector<pair<int, int>> IT;
  vector<int> Low, High;
  void InitTree(int x, int Left, int Right) {
    Low[x] = Left;
    High[x] = Right;
    if (Left == Right) {
      IT[x] = make_pair(0, 0);
      return;
    }
    int Mid = (Left + Right) / 2;
    InitTree(x * 2, Left, Mid);
    InitTree(x * 2 + 1, Mid + 1, Right);
    IT[x] = max(IT[x * 2], IT[x * 2 + 1]);
  }
  void Update(int x, int Left, int Right, pair<int, int> Val) {
    if (Low[x] > Right || High[x] < Left) {
      return;
    }
    if (Low[x] >= Left && High[x] <= Right) {
      IT[x] = Val;
      return;
    }
    Update(x * 2, Left, Right, Val);
    Update(x * 2 + 1, Left, Right, Val);
    IT[x] = max(IT[x * 2], IT[x * 2 + 1]);
  }
  pair<int, int> Get(int x, int Left, int Right) {
    if (Low[x] > Right || High[x] < Left) {
      return make_pair(-1, -1);
    }
    if (Low[x] >= Left && High[x] <= Right) {
      return IT[x];
    }
    return max(Get(x * 2, Left, Right), Get(x * 2 + 1, Left, Right));
  }
  void Init(int n) {
    IT.resize(4 * n + 5);
    Low.resize(4 * n + 5);
    High.resize(4 * n + 5);
    InitTree(1, 0, n + 1);
  }
};
int n;
pair<int, int> d[MaxN];
int x[MaxN], a[MaxN], ansA[MaxN], ansB[MaxN];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>>
    pqMin;
SegmentTree SMT;
bool cmp(int x, int y) {
  return (d[x].first != d[y].first ? d[x].first < d[y].first
                                   : d[x].second < d[y].second);
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> d[i].first >> d[i].second;
    x[i] = i;
  }
  sort(x + 1, x + n + 1, cmp);
  int j = 1;
  for (int i = 1; i <= n; i++) {
    while (j <= n && d[x[j]].first <= i) {
      pqMin.push(make_pair(d[x[j]].second, x[j]));
      j++;
    }
    a[i] = pqMin.top().second;
    ansA[a[i]] = i;
    ansB[a[i]] = i;
    pqMin.pop();
  }
  SMT.Init(n);
  bool ok = true;
  for (int i = 1; i <= n; i++) {
    pair<int, int> t = SMT.Get(1, d[a[i]].first, i - 1);
    if (t.first >= i) {
      swap(ansB[t.second], ansB[a[i]]);
      ok = false;
      break;
    }
    SMT.Update(1, i, i, make_pair(d[a[i]].second, a[i]));
  }
  if (ok) {
    cout << "YES\n";
    for (int i = 1; i <= n; i++) {
      cout << ansA[i] << ' ';
    }
  } else {
    cout << "NO\n";
    for (int i = 1; i <= n; i++) {
      cout << ansA[i] << ' ';
    }
    cout << '\n';
    for (int i = 1; i <= n; i++) {
      cout << ansB[i] << ' ';
    }
  }
  return 0;
}
