Problem: 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 

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
template <class T>
bool ckmin(T& a, const T& b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T& a, const T& b) {
  return a < b ? a = b, 1 : 0;
}
struct I {
  int i, l, r;
  I(int i, int l, int r) : i(i), l(l), r(r) {}
};
const int INF = 1e9;
template <class T>
struct MinSegmentTree {
  const T ID = {INF, INF};
  T comb(T a, T b) { return min(a, b); }
  int n;
  std::vector<T> seg;
  void init(int _n) {
    n = _n;
    seg.assign(2 * n, ID);
  }
  void pull(int p) { seg[p] = comb(seg[2 * p], seg[2 * p + 1]); }
  void upd(int p, T val) {
    seg[p += n] = val;
    for (p /= 2; p; p /= 2) pull(p);
  }
  void add(int p, T val) {
    seg[p += n] += val;
    for (p /= 2; p; p /= 2) pull(p);
  }
  T query(int l, int r) {
    if (l > r) return ID;
    T ra = ID, rb = ID;
    for (l += n, r += n + 1; l < r; l /= 2, r /= 2) {
      if (l & 1) ra = comb(ra, seg[l++]);
      if (r & 1) rb = comb(seg[--r], rb);
    }
    return comb(ra, rb);
  }
};
template <class T>
struct MaxSegmentTree {
  const T ID = {-INF, -INF};
  T comb(T a, T b) { return min(a, b); }
  int n;
  std::vector<T> seg;
  void init(int _n) {
    n = _n;
    seg.assign(2 * n, ID);
  }
  void pull(int p) { seg[p] = comb(seg[2 * p], seg[2 * p + 1]); }
  void upd(int p, T val) {
    seg[p += n] = val;
    for (p /= 2; p; p /= 2) pull(p);
  }
  void add(int p, T val) {
    seg[p += n] += val;
    for (p /= 2; p; p /= 2) pull(p);
  }
  T query(int l, int r) {
    if (l > r) return ID;
    T ra = ID, rb = ID;
    for (l += n, r += n + 1; l < r; l /= 2, r /= 2) {
      if (l & 1) ra = comb(ra, seg[l++]);
      if (r & 1) rb = comb(seg[--r], rb);
    }
    return comb(ra, rb);
  }
};
int main() {
  ios_base::sync_with_stdio(0);
  int n;
  cin >> n;
  vector<I> ivals;
  for (int i = 0; i < n; ++i) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    ivals.push_back(I(i, a, b));
  }
  vector<vector<I>> beg(n);
  for (int i = 0; i < n; ++i) {
    beg[ivals[i].l].push_back(ivals[i]);
  }
  set<pair<int, int>> match;
  vector<int> m1(n);
  for (int i = 0; i < n; ++i) {
    for (auto& e : beg[i]) {
      match.emplace(e.r, e.i);
    }
    auto x = *match.begin();
    match.erase(match.begin());
    m1[x.second] = i;
  }
  vector<int> m2(n);
  auto double_finish = [&]() {
    cout << "NO\n";
    for (auto& e : m1) cout << e + 1 << " ";
    cout << '\n';
    for (auto& e : m2) cout << e + 1 << " ";
    cout << '\n';
    exit(0);
  };
  m2 = m1;
  auto contains = [&](int l, int r, int i) -> int { return l <= i && i <= r; };
  vector<int> segs(n);
  MaxSegmentTree<pair<int, int>> Left;
  MinSegmentTree<pair<int, int>> Right;
  Left.init(n);
  Right.init(n);
  for (int i = 0; i < n; ++i) {
    segs[m1[i]] = i;
  }
  for (int i = 0; i < n; ++i) {
    int id = segs[i];
    Right.upd(i, {ivals[id].l, i});
    Left.upd(i, {ivals[id].r, i});
  }
  for (int i = 0; i < n; ++i) {
    int id = segs[i];
    int l = ivals[id].l;
    int r = ivals[id].r;
    auto qq = Right.query(i + 1, r);
    if (qq.first <= i) {
      int j = qq.second;
      swap(m2[segs[i]], m2[segs[j]]);
      double_finish();
    }
    qq = Left.query(l, i - 1);
    if (qq.first >= i) {
      int j = qq.second;
      swap(m2[segs[i]], m2[segs[j]]);
      double_finish();
    }
  }
  cout << "YES" << '\n';
  for (auto& e : m1) cout << e + 1 << " ";
  cout << '\n';
  return 0;
}