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;
mt19937 __MT(chrono::system_clock::now().time_since_epoch().count());
const int maxn = 200000 + 10;
pair<int, int> itvl[maxn];
int n;
int id[maxn];
int ans[maxn];
int inv[maxn];
struct segtree {
  int maxv[maxn << 2];
  int maxid[maxn << 2];
  int n, ql, qr, idx, rm;
  void init(int n) {
    this->n = n;
    build(1, n, 1);
  }
  void maintain(int l, int r, int o) {
    if (l != r) {
      maxv[o] = max(maxv[o << 1], maxv[o << 1 | 1]);
      if (maxv[o << 1] == maxv[o]) maxid[o] = maxid[o << 1];
      if (maxv[o << 1 | 1] == maxv[o]) maxid[o] = maxid[o << 1 | 1];
    }
  }
  void build(int l, int r, int o) {
    if (l == r) {
      maxv[o] = itvl[inv[l]].second;
      maxid[o] = l;
      return;
    }
    int mid = l + r >> 1;
    build(l, mid, o << 1), build(mid + 1, r, o << 1 | 1);
    maintain(l, r, o);
  }
  void update(int o) {
    if (rm < maxv[o]) {
      rm = maxv[o];
      idx = maxid[o];
    }
  }
  void query(int l, int r, int o) {
    if (ql <= l && qr >= r)
      update(o);
    else {
      int mid = l + r >> 1;
      if (ql <= mid) query(l, mid, o << 1);
      if (qr > mid) query(mid + 1, r, o << 1 | 1);
    }
  }
  pair<int, int> Query(int l, int r) {
    rm = -1;
    idx = -1;
    ql = l, qr = r;
    query(1, n, 1);
    return (pair<int, int>){rm, idx};
  }
};
segtree tree;
inline void solve() {
  priority_queue<pair<int, int>, vector<pair<int, int> >,
                 greater<pair<int, int> > >
      q;
  int p = 1;
  for (auto i = (1); i <= (n); ++i) {
    if (p <= n && itvl[id[p]].first == i)
      q.push({itvl[id[p]].second, id[p]}), ++p;
    while (p <= n && itvl[id[p]].first == itvl[id[p - 1]].first) {
      q.push({itvl[id[p]].second, id[p]});
      ++p;
    }
    auto e = q.top();
    q.pop();
    ans[e.second] = i;
  }
  for (auto i = (1); i <= (n); ++i) inv[ans[i]] = i;
  tree.init(n);
  pair<int, int> swp;
  int amb = 0;
  swp.first = swp.second = -1;
  for (auto i = (2); i <= (n); ++i) {
    int j = inv[i];
    assert(itvl[j].first <= i);
    auto e = tree.Query(itvl[j].first, i - 1);
    if (e.first >= i) {
      swp.first = i;
      swp.second = e.second;
      amb = 1;
      break;
    }
  }
  if (!amb) {
    puts("YES");
  } else {
    puts("NO");
  }
  for (auto i = (1); i <= (n); ++i) printf("%d ", ans[i]);
  puts("");
  if (amb) {
    swap(ans[inv[swp.first]], ans[inv[swp.second]]);
    for (auto i = (1); i <= (n); ++i) printf("%d ", ans[i]);
    puts("");
  }
}
int main(void) {
  scanf("%d", &(n));
  for (auto i = (1); i <= (n); ++i)
    scanf("%d%d", &itvl[i].first, &itvl[i].second), id[i] = i;
  sort(id + 1, id + 1 + n,
       [](const int& a, const int& b) { return itvl[a] < itvl[b]; });
  solve();
  return 0;
}
