#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
using ll = long long;
struct Node {
ll value; // Holds the aggregated value for the node
ll lazy; // Lazy propagation value
Node *left, *right;
Node() : value(0), lazy(0), left(nullptr), right(nullptr) {}
};
class ImplicitLazySegmentTree {
private:
Node* root;
int startRange, endRange; // Define the logical range of the segment st1
function<ll(ll, ll)> combine; // Combiner function (e.g., sum, max, min)
// Push lazy updates down to children
void propagate(Node*& node, int l, int r) {
if (!node || node->lazy == 0) return;
node->value += node->lazy * (r - l + 1); // Apply the lazy value
// Propagate to children if not a leaf
if (l != r) {
if (!node->left) node->left = new Node();
if (!node->right) node->right = new Node();
node->left->lazy += node->lazy;
node->right->lazy += node->lazy;
}
node->lazy = 0; // Clear the lazy value for the current node
}
// Update range [q_l, q_r] by adding `val`
void update(Node*& node, int l, int r, int q_l, int q_r, ll val) {
if (!node) node = new Node();
propagate(node, l, r);
if (l > r || q_r < l || q_l > r) return; // No overlap
if (q_l <= l && r <= q_r) { // Total overlap
node->lazy += val;
propagate(node, l, r);
return;
}
// Partial overlap
int mid = (l + r) >> 1;
update(node->left, l, mid, q_l, q_r, val);
update(node->right, mid + 1, r, q_l, q_r, val);
node->value = combine(
node->left ? node->left->value : 0,
node->right ? node->right->value : 0
);
}
// Query the range [q_l, q_r]
ll query(Node* node, int l, int r, int q_l, int q_r) {
if (!node || l > r || q_r < l || q_l > r) return 0; // No overlap
propagate(node, l, r);
if (q_l <= l && r <= q_r) return node->value; // Total overlap
// Partial overlap
int mid = (l + r) >> 1;
ll leftResult = query(node->left, l, mid, q_l, q_r);
ll rightResult = query(node->right, mid + 1, r, q_l, q_r);
return combine(leftResult, rightResult);
}
// Cleanup allocated nodes
void cleanup(Node*& node) {
if (!node) return;
cleanup(node->left);
cleanup(node->right);
delete node;
node = nullptr;
}
public:
// Constructor
ImplicitLazySegmentTree(int startRange, int endRange, function<ll(ll, ll)> combine)
: startRange(startRange), endRange(endRange), combine(combine) {
root = nullptr;
}
// Destructor
~ImplicitLazySegmentTree() {
cleanup(root);
}
// Public update method
void update(int q_l, int q_r, ll val) {
update(root, startRange, endRange, q_l, q_r, val);
}
// Public query method
ll query(int q_l, int q_r) {
return query(root, startRange, endRange, q_l, q_r);
}
};
// Example usage: Range sum segment st1 with range [-1e9, 1e9]
void solve() {
int n;
cin >> n;
ImplicitLazySegmentTree st1(1, 1e9, [](ll a, ll b) { return a + b; });
assert(1 <= n && n <= 200000);
vector<pair<int, int>> v(n);
for(auto &[l, r]: v) {
cin >> l >> r;
assert(1 <= l && l <= 1000000000);
assert(1 <= r && r <= 1000000000);
// cerr << n << endl;
assert(l <= r);
st1.update(l, r, +1);
}
sort(v.begin(), v.end(), [&](auto x, auto y) {
if(x.second == y.second) return x.first <= y.first;
return x.second < y.second;
});
vector<int> ans;
int last = -1;
for(auto &[l, r]: v) {
if(last < l) {
last = l;
}
else {
if(last >= r) {
if(st1.query(l, r) == 0) {
cout << "nO" << endl;
return;
}
int lo = l, hi = r, mid, point = -1;
while(lo <= hi) {
mid = lo + hi >> 1;
if(st1.query(l, mid)) {
point = mid;
hi = mid - 1;
}
else lo = mid + 1;
}
if(point == -1) {
cout << "No" << endl;
return;
}
last = point;
}
else last++;
}
// cout << l << " " << r << " = " << last << endl;
st1.update(last, last, -1);
ans.push_back(last);
}
cout << "YeS" << endl;
for(auto &i: ans) cout << i << " ";
cout << endl;
return;
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
int tc = 1;
cin >> tc;
assert(1 <= tc && tc <= 5000);
for (int t = 1; t <= tc; t++) {
// cout << "Case " << t << ": ";
solve();
}
return 0;
}