use std::collections::BTreeSet;
use std::io::{self, BufRead};
fn main() {
let stdin = io::stdin();
let mut input = stdin.lock().lines();
let t: usize = input.next().unwrap().unwrap().trim().parse().unwrap();
for _ in 0..t {
let n: usize = input.next().unwrap().unwrap().trim().parse().unwrap();
let mut vec = Vec::new();
let mut id = Vec::new();
for _ in 0..n {
let line = input.next().unwrap().unwrap();
let parts: Vec<i32> = line.trim().split_whitespace()
.map(|x| x.parse::<i32>().unwrap())
.collect();
let l = parts[0];
let r = parts[1];
vec.push((r, l)); // Push as (end, start)
id.push(l);
}
vec.sort(); // Sort by end, then start
id.sort(); // Sort by start
let mut cur = 0;
let mut st = BTreeSet::new();
let mut res = Vec::new();
for &id_val in &id {
if id_val > cur {
cur = id_val;
} else {
cur += 1;
}
st.insert(cur);
res.push(cur);
}
let mut valid = true;
for &(cur_r, cur_l) in &vec {
let it = st.range(cur_l..).next().cloned();
if let Some(&val) = it.as_ref() {
if val > cur_r || val < cur_l {
valid = false;
break;
}
st.remove(&val);
} else {
valid = false;
break;
}
}
if !valid {
println!("NO");
} else {
println!("YES");
println!("{}", res.iter().map(|x| x.to_string()).collect::<Vec<String>>().join(" "));
}
}
}