'use strict'

const getLine = () => readline().split(' ')
const getInts = () => getLine().map(n => parseInt(n))
const getInt = () => getInts()[0]
const D = (...args) => { // D({name})
  [...args].forEach(cur => print.apply(print, [JSON.stringify(cur)]))
}

main()

function main() {
  const n = getInt()
  const inc = new Array(n + 1).fill(0)
  const G = []
  const ans = {}
  const out = []
  for (let i = 1; i < n; ++i) {
    const ab = getInts()
    const a = ab[0]
    const b = ab[1]
    out.push(make_pair(a, b))

    inc[a] ++
    inc[b] ++
    if (!G[a]) G[a] = []
    if (!G[b]) G[b] = []

    G[a].push(b)
    G[b].push(a)
    ans[make_pair(a, b)] = -1
  }

  let node = -1
  let mx = 0
  for (let i = 1; i <= n; ++i) {
    if (inc[i] > mx) {
      mx = inc[i]
      node = i
    }
  }

  let cnt = 0
  for (let i = 0; i < G[node].length; ++i) {
    const other = G[node][i]
    ans[make_pair(node, other)] = cnt ++
  }

  for (let i in ans) {
    if (ans[i] === -1) ans[i] = cnt ++
  }

  for (let i in out) {
    print(ans[out[i]])
  }
}

function make_pair (a, b) {
  const arr = [a, b]
  arr.sort()
  return arr[0] + '-' + arr[1]
}

process.stdin.resume()
process.stdin.setEncoding('utf-8')

let input = ''
let ptr = 0
process.stdin.on('data', (i) => {
  input += i
})

process.stdin.on('end', () => {
  input = input.split('\n').map(a => a.replace(/(\r\n|\n|\r)/gm, ''))
  main()
})

function wr(...x) {
  console.log(...x)
}

function sort(a, inc = true) {
  if(inc) a.sort((a, b) => a - b)
  else a.sort((a, b) => b - a)
}

function readInt() {
  return parseInt(input[ptr++])
}

function readString() {
  return input[ptr++]
}

function readStrings() {
  return input[ptr++].split(' ')
}

function readInts() {
  return input[ptr++].split(' ').map(a => parseInt(a))
}

function main() {
  const n = readInt()
  let tree = {}
  for(let i = 0; i < n - 1; i++) {
    const [u, v] = readInts()
    if(!tree[u]) tree[u] = [[v, i]]
    else tree[u].push([v, i])
    if(!tree[v]) tree[v] = [[u, i]]
    else tree[v].push([u, i])
  }
  let ans = new Array(n - 1).fill(-1)
  let c = 0

  // console.log(tree)

  for(let k in tree) {
    if(tree[k].length === 1) {
      if(ans[tree[k][0][1]] === -1) ans[tree[k][0][1]] = c++
    }
  }

  // console.log(ans)
  for(let k in tree) {
    let x = tree[k]
    for(let i = 0, len = x.length; i < len; i++) {
      let el = x[i]
      if(ans[el[1]] === -1) ans[el[1]] = c++
    }
  }
  // console.log(ans)
  wr(ans.join('\n'))
}

process.stdin.resume()
process.stdin.setEncoding('utf-8')

let input = ''
let ptr = 0
process.stdin.on('data', (i) => {
  input += i
})

process.stdin.on('end', () => {
  input = input.split('\n').map(a => a.replace(/(\r\n|\n|\r)/gm, ''))
  main()
})

function wr(...x) {
  console.log(...x)
}

function sort(a, inc = true) {
  if(inc) a.sort((a, b) => a - b)
  else a.sort((a, b) => b - a)
}

function readInt() {
  return parseInt(input[ptr++])
}

function readString() {
  return input[ptr++]
}

function readStrings() {
  return input[ptr++].split(' ')
}

function readInts() {
  return input[ptr++].split(' ').map(a => parseInt(a))
}

function main() {
  const n = readInt()
  let tree = {}
  for(let i = 0; i < n - 1; i++) {
    const [u, v] = readInts()
    if(!tree[u]) tree[u] = [[v, i]]
    else tree[u].push([v, i])
    if(!tree[v]) tree[v] = [[u, i]]
    else tree[v].push([u, i])
  }
  let ans = new Array(n - 1).fill(-1)
  let c = 0

  // console.log(tree)

  for(let k in tree) {
    if(tree[k].length === 1) {
      ans[tree[k][0][1]] = c++
    }
  }
  for(let k in tree) {
    let x = tree[k]
    for(let i = 0, len = x.length; i < len; i++) {
      let el = x[i]
      if(ans[el[1]] === -1) ans[el[1]] = c++
    }
  }
  // console.log(ans)
  wr(ans.join('\n'))
}


process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readLine() {
    return inputString[currentLine++];
}

function main() {
  const t = Number(readLine())
  for (let _ = 0; _ < t; _++) {
	const n = Number(readLine())
    let as = readLine()
    let allSame = true
    for (let i = 1; i < n; i++) {
      if (as[i] !== as[0]) {
        as = as.substr(i) + as.substr(0, i)
        allSame = false
        break
      }
    }
    let result = 0
    if (allSame) {
      as = (as[0] === 'L' ? 'R' : 'L') + as.substr(1)
      result = 1
    }
    let currentChar = as[0]
    let currentLength = 1
    for (let i = 1; i < n; i++) {
      if (as[i] !== currentChar) {
        result += (currentLength - (currentLength % 3)) / 3
        currentChar = as[i]
        currentLength = 1
      } else {
        currentLength++
      }
    }
    result += (currentLength - (currentLength % 3)) / 3
    console.log(result)
  }
}

var readline=require('readline');
const { Console } = require('console');
var rl=readline.createInterface({
    input:process.stdin,
    output:process.stdout
});
var arr=[];
rl.on('line',function(inp){
    arr.push(inp);
    var len=arr.length;
    if(len%2===1&&len>1){
        var n=parseInt(arr[len-2]),s=arr[len-1],k=-1;
        s+=s;
        for(var i=0;i<n;i++){
            if(s[i]!=s[i+n-1]){
                k=i;
                break;
            }
        }
        if(k===-1) console.log(Math.floor(n/3)+(n%3>0));
        else{
            var pos=k,ans=1,sum=0;
            while(pos<k+n){
                if(s[pos]===s[pos+1]) ans++;
                else{
                    sum+=Math.floor(ans/3);
                    ans=1;
                }
                pos++;
            }
            sum+=Math.floor(ans/3);
            console.log(sum);
        }
    }
    if(len===parseInt(arr[0])*2+1) process.exit(0);
});

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readLine() {
    return inputString[currentLine++];
}

function main() {
  const t = Number(readLine())
  for (let _ = 0; _ < t; _++) {
	const n = Number(readLine())
    let as = readLine()
    for (let i = 1; i < n; i++) {
      if (as[i] !== as[0]) {
        as = as.substr(i) + as.substr(0, i)
        break
      }
    }
    let result = 0
    let currentChar = as[0]
    let currentLength = 1
    for (let i = 1; i < n; i++) {
      if (as[i] !== currentChar) {
        result += ((currentLength + (currentLength % 2)) / 2) - 1
        currentChar = as[i]
        currentLength = 1
      } else {
        currentLength++
      }
    }
    result += ((currentLength + (currentLength % 2)) / 2) - 1
    console.log(result)
  }
}

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readLine() {
    return inputString[currentLine++];
}

function main() {
  const t = Number(readLine())
  for (let _ = 0; _ < t; _++) {
	const n = Number(readLine())
    let as = readLine()
    let allSame = true
    for (let i = 1; i < n; i++) {
      if (as[i] !== as[0]) {
        as = as.substr(i) + as.substr(0, i)
        allSame = false
        break
      }
    }
    let result = 0
    if (allSame) {
      as = (as[0] === 'L' ? 'R' : 'L') + as.substr(1)
      result = 1
    }
    let currentChar = as[0]
    let currentLength = 1
    for (let i = 1; i < n; i++) {
      if (as[i] !== currentChar) {
        result += ((currentLength + (currentLength % 2)) / 2) - 1
        currentChar = as[i]
        currentLength = 1
      } else {
        currentLength++
      }
    }
    result += ((currentLength + (currentLength % 2)) / 2) - 1
    console.log(result)
  }
}

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readLine() {
    return inputString[currentLine++];
}

function main() {
  const t = Number(readLine())
  for (let _ = 0; _ < t; _++) {
	const n = Number(readLine())
    let as = readLine()
    let allSame = true
    for (let i = 1; i < n; i++) {
      if (as[i] !== as[0]) {
        as = as.substr(i) + as.substr(0, i)
        allSame = false
        break
      }
    }
    if (allSame) {
      console.log(((n - (n % 2)) / 2))
      continue
    }
    let result = 0
    let currentChar = as[0]
    let currentLength = 1
    for (let i = 1; i < n; i++) {
      if (as[i] !== currentChar) {
        result += ((currentLength + (currentLength % 2)) / 2) - 1
        currentChar = as[i]
        currentLength = 1
      } else {
        currentLength++
      }
    }
    result += ((currentLength + (currentLength % 2)) / 2) - 1
    console.log(result)
  }
}


t = +readline();
res = '';
while (t-->0){
    n = +readline();
    ar = readline().split(' ').map(Number).sort((a,b)=>a-b);
    teams = [];
    for (i=0;i<n;i++){
        found = false;
        for (j=0;j<teams.length;j++){
            if (teams[j] + 1 !== ar[i]){
                teams[j] = ar[i];
                found = true;
                break;
            }
        }

        if (!found){
            teams.push(ar[i]);
        }
    }
    res += teams.length+'\n';
}
print(res);

 var _tmp = [];
            var _front = 0;
            var readOne = function() {
                if(_front >= _tmp.length) {
                    _tmp = readline().split(' ');
                    _front = 0;
                    return readOne();
                } else {
                    return _tmp[_front++];
                }
            };
            var readInt = function() {
                return parseInt(readOne());
            };
            var readStr = function() {
                return readOne();
            };

            var q = readInt();
            while(q--) {
                var n = readInt();
                var t = [];
                for(var i = 0; i < n; i++) {
                    t[i] = readInt();
                }
                t.sort(function(a, b){return a - b});
                var res = [];
                for(var i = 0; i < n; i++) {
                    for(var j = 0; j < res.length; j++) {
                        if(res[j] + 2 <= t[i]) {
                            res[j] = t[i];
                            break;
                        }
                    }
                    if(j === res.length) {
                        res.push(t[i]);
                    }
                }
                print(res.length);
            }

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    solveWrap(inputString);
});

function solve(arr){
    return arr.sort((a, b) => a-b).some((el, idx, arr) => idx>0&&el==arr[idx-1]+1?true:false)?2:1;
}

function solveWrap(input) {
    let inputAr = input.trim().split('\n');
    let t = inputAr.shift();
    for (let i = 0; i < t; i++) {
        inputAr.shift();
        console.log(solve(inputAr[i].split(' ').map((el) => +el)));
    }
}

'use strict';

const nQueues = this.readline().split(" ");

for (let i = 0; i < nQueues; i++) {
  const nStds = this.readline();
  let scoresL = this.readline();

  if(scoresL){
  let scores = [];
  scoresL.split(" ").forEach(el => scores.push(parseInt(el)));

  scores = scores.sort((a, b) => a - b);
  let has = false;
  for (let j = 1; j < nStds; j++) {
    if (Math.abs(scores[j - 1] - scores[j]) === 1) {
      has = true;
      break;
    }
  }
  if (has) {
    this.print(2);
  } else {
    this.print(1);
  }
  }

}

//Don't have to see. start------------------------------------------
var read = require('readline').createInterface({
  input: process.stdin, output: process.stdout
});
var obj; var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
  obj = init(inLine);
  console.error('\n');
  var start = Date.now();
  Main();
  var end = Date.now() - start;
  myerr('time : ' + end + 'ms');
  myerr('memory : ' + Math.round(process.memoryUsage().heapTotal / 1024) + 'KB');
});
function makeClone(obj){return (obj instanceof Set) ? new Set(Array.from(obj)) : JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
  return {
    list : input, index : 0, max : input.length,
    hasNext : function(){return (this.index < this.max);},
    next : function(){if(this.hasNext()){return this.list[this.index++];}else{throw 'ArrayIndexOutOfBoundsException ‚There is no more input';}}
  };
}
function myout(s){console.log(s);}
function myerr(s){console.error('debug:' + require('util').inspect(s,false,null));}
//param "no" is
//unknown or outlier : return i. 1: parseInt.
//2: split space. 4: split space and parseInt.
//6: split 1 character. 7: split 1 character and parseInt.
//8: join space. 9: join nextline. 0: join no character.
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(' ');case 4:return i.split(' ').map(Number);case 6:return i.split('');case 7:return i.split('').map(Number);case 8:return i.join(' ');case 9:return i.join('\n');case 0:return i.join('');default:return i;}}catch(e){return i;}}

//Don't have to see. end------------------------------------------
function Main(){
  var t = nextInt();
  var output = new Array(t);
  for(var i = 0; i < t; i++){
    var N = nextInt();
    var list = nextIntArray();
    list.sort(function(a,b){
    	return a - b;
    });
    var map = {0:[list[0]]}
    for(var j = 1; j < N; j++){
      var keys = Object.keys(map);
      var isOK = false;
      for(var k = 0; k < keys.length; k++){
        if(map[keys[k]][map[keys[k]].length - 1] + 1 < list[j]){
          isOK = true;
          map[keys[k]].push(list[j]);
          break;
        }
      }
      if(!isOK){
        map[keys.length] = [list[j]];
      }
    }
    var keys = Object.keys(map);
    output[i] = keys.length;
  }
  myout(myconv(output, 9));
}

let i = ''
process.stdin.on('data', c => i += c)
process.stdin.on('end', () => {
    const {EOL} = require('os')
    const lines = i.split(EOL);

    function foo (data, n) {
        data.sort((a, b) => a - b);

        let result = 1;
        let index = 0;

        while (index < data.length) {
            if (data[index] + 1 === data[index + 1]) {
                result = 2;
                break;
            }
            index++;
        }
        return result;
    }

    let testCount = 1;
    let answer = '';
    while(testCount <= +lines[0]) {
        let data = lines[testCount * 2].split(" ").map(Number);
        let n = lines[testCount * 2 - 1].split(" ").map(Number);

        let result = foo(data, n);
        answer += result +"\n";
        testCount++;
    }
    console.log(answer);
})

'use strict'
let input = readline()
let i = 1
let flag = true;
let gp = 1
while(i <= input){
    let int = readline()
    let data = readline().split(' ').map(Number);
    let j = 0;
    while(j < data.length){
        let k =j+1
        while(k <data.length){
           if(Math.abs(data[j]-data[k]) == 1 && flag){
                gp++
                flag = false
           }
           k++
        }
        j++
    }
    i++
    print(gp)
    gp = 1
    flag = true
}

'use strict'

const problem = (a) => {
    for (let i = 1; i < a.length; i++) if (a[i] === a[i-1] + 1) return 2;
    return 1;
}

let q = +readline();
while(q--) {
    readline(); print(problem(readline().split(' ').map(Number).sort((a, b) => a - b)));
}

var tc = parseInt(readline());
while(tc--){
    var n = parseInt(readline());
    var arr = readline().split(" ").map(x => parseInt(x));
    var aux = {};
    var dos=false;
    for(var i=0;i<arr.length;i++){
        aux[arr[i]] = i;
        if(aux[arr[i]-1]!==undefined || aux[arr[i]+1]!==undefined)
            dos=true;
    }
    if(dos)
        print(2);
    else
        print(1);
}

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});
let c = 0;

rl.on('line', (d) => {
  if (c === 0) {
    c++;
    return;
  }

  if (c % 2 === 1) {
    c++;
    return;
  }

  const arr = d.split(' ').map(Number);
  arr.sort((a, b) => a - b);

  let ans = 1;

  for (let i = 1; i < arr.length; i++) {
    if (Math.abs(arr[i - 1] - arr[i]) === 1) {
      ans = 2;
    }
  }

  console.log(ans);
  c++;
});

q=readline()
while(q-->0){
    n=readline()
    a=readline().split(' ')
    hoga=false
    a.sort(function(a,b){return a-b})
    for(i=0;i<a.length-1;i++){
        if(Math.abs(a[i]-a[i+1])==1)
            hoga=true;
    }
    if(hoga)
        print(2)
    else
        print(1)
}

"use strict";

process.stdin.resume();
process.stdin.setEncoding('utf8');

let input_stdin = '';

process.stdin.on('data', function (data) {
    input_stdin += data;
});

process.stdin.on('end', function () {
    let chunks = '';
    chunks = input_stdin.split('\n');
    start(chunks);
});

function start(input) {
    let queries = +input.shift();

    while(queries--) {
        input.shift();
        const array = input.shift().split(' ').map(Number);
        const hash = {};
        let answer = 1;
        for(const element of array) {
            if((element && hash[element - 1]) || hash[element + 1]) {
                answer = 2;
                break;
            }
            hash[element] = true;
        }
        console.log(answer);
    }
}

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

let countSets = 0;
const dataSets = [];

let step = 0;
let peopleCount;
rl.on('line', (line) => {

  if (!countSets) {
    countSets = Number(line);
    return;
  }

  step++;

  if (!peopleCount) {
    peopleCount = Number(line);
    return;
  }

  let arr = [];
  line.split(' ').map((i) => {
    const n = Number(i);
    arr.push(n);
  });

  function sortNumber(a, b) {
    return a - b;
  }

  arr.sort(sortNumber);
  peopleCount = undefined;
  dataSets.push(arr);

  if (step === countSets * 2) {
    start();
  }
});

function start() {

  for (let i = 0; i < countSets; i++) {
    const groups = [],
          people = dataSets[i];

    for (let item of people) {

      let flag = false;
      for (let a = 0; a < groups.length; a++) {
        if (Math.abs(groups[a] - item) === 1) continue;

        flag = true;
        groups[a] = item;
        break;
      }

      if (!flag) {
        groups.push(item);
      }
    }

    console.log(groups.length);
  }

  rl.close();
}

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readLine() {
    return inputString[currentLine++];
}

var gcd = (a, b) => a ? gcd(b % a, a) : b;
var lcm = (a, b) => a * b / gcd(a, b);

function main(){
	let t= +(readLine());
	while(t--){
		let n = +(readLine())
		let a = readLine().split(" ").map(Number);

		a.sort((x,y)=> x-y);
		// console.log(a)
		let f=0;
		for(let i = 0; i <n ;i++){
			if(a[i]+1 == a[i+1]){
				console.log(2);
				f=1;
				break;
			}
		}

		if(!f){
			console.log(1);
		}
	}

}

let data = '';
process.stdin.on('data', c => data += c);

const sol = () =>{
    let ans = [];
    let line = data.trim().split(/\n/g);
    let n = Number(line.shift());
    for(let i = 0; i < n; i++) {
        let num = line[2*i];
        let nums = line[2*i + 1].trim().split(/\s/g).map(Number);
        nums.sort((a, b) => a - b);
        let flag = true;
        for(let j = 0 ; j < num-1; j++){
            if (Math.abs(nums[j] - nums[j+1]) === 1) {
                flag = false;
                break;
            }
        }
        ans.push(flag?1:2);
    }
    console.log(ans.join('\n'));
};

process.stdin.on('end', sol);

//var input = readline()
var Test = parseInt(readline());
while(Test -- > 0) {
    var n = parseInt(readline());
    var ar = readline().split(' ').map(x => parseInt(x));
    ar.sort((a, b) => (a - b));
    var check = false;
    for(var i=0; i<n; i++){
        if(ar[i]+1 === ar[i+1]) {
            //print(ar[i]+1 +' '+ ar[i+1]);
            check = true; break;
        }
    }
    print(check ? 2 : 1);
}

//Don't have to see. start------------------------------------------
var read = require('readline').createInterface({
  input: process.stdin, output: process.stdout
});
var obj; var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
  obj = init(inLine);
  console.error('\n');
  var start = Date.now();
  Main();
  var end = Date.now() - start;
  myerr('time : ' + end + 'ms');
  myerr('memory : ' + Math.round(process.memoryUsage().heapTotal / 1024) + 'KB');
});
function makeClone(obj){return (obj instanceof Set) ? new Set(Array.from(obj)) : JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
  return {
    list : input, index : 0, max : input.length,
    hasNext : function(){return (this.index < this.max);},
    next : function(){if(this.hasNext()){return this.list[this.index++];}else{throw 'ArrayIndexOutOfBoundsException ‚There is no more input';}}
  };
}
function myout(s){console.log(s);}
function myerr(s){console.error('debug:' + require('util').inspect(s,false,null));}
//param "no" is
//unknown or outlier : return i. 1: parseInt.
//2: split space. 4: split space and parseInt.
//6: split 1 character. 7: split 1 character and parseInt.
//8: join space. 9: join nextline. 0: join no character.
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(' ');case 4:return i.split(' ').map(Number);case 6:return i.split('');case 7:return i.split('').map(Number);case 8:return i.join(' ');case 9:return i.join('\n');case 0:return i.join('');default:return i;}}catch(e){return i;}}

//Don't have to see. end------------------------------------------
function Main(){
  var t = nextInt();
  var output = new Array(t);
  for(var i = 0; i < t; i++){
    var N = nextInt();
    var list = nextIntArray();
    var count = 0;
    list.sort(function(a,b){
    	return a - b;
    });
    while(list.length > 1){
      var L = list.shift();
      var R = list.pop();
      if(Math.abs(L - R) != 0){
        count++;
      }
    }
    if(count > 0){
      output[i] = count;
    }else if(N == 1){
      output[i] = 1;
    }else{
      output[i] = 0;
    }
  }
  myout(myconv(output, 9));
}

//Don't have to see. start------------------------------------------
var read = require('readline').createInterface({
  input: process.stdin, output: process.stdout
});
var obj; var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
  obj = init(inLine);
  console.error('\n');
  var start = Date.now();
  Main();
  var end = Date.now() - start;
  myerr('time : ' + end + 'ms');
  myerr('memory : ' + Math.round(process.memoryUsage().heapTotal / 1024) + 'KB');
});
function makeClone(obj){return (obj instanceof Set) ? new Set(Array.from(obj)) : JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
  return {
    list : input, index : 0, max : input.length,
    hasNext : function(){return (this.index < this.max);},
    next : function(){if(this.hasNext()){return this.list[this.index++];}else{throw 'ArrayIndexOutOfBoundsException ‚There is no more input';}}
  };
}
function myout(s){console.log(s);}
function myerr(s){console.error('debug:' + require('util').inspect(s,false,null));}
//param "no" is
//unknown or outlier : return i. 1: parseInt.
//2: split space. 4: split space and parseInt.
//6: split 1 character. 7: split 1 character and parseInt.
//8: join space. 9: join nextline. 0: join no character.
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(' ');case 4:return i.split(' ').map(Number);case 6:return i.split('');case 7:return i.split('').map(Number);case 8:return i.join(' ');case 9:return i.join('\n');case 0:return i.join('');default:return i;}}catch(e){return i;}}

//Don't have to see. end------------------------------------------
function Main(){
  var t = nextInt();
  var output = new Array(t);
  for(var i = 0; i < t; i++){
    var N = nextInt();
    var list = nextIntArray();
    var count = 0;
    list.sort(function(a,b){
    	return a - b;
    });
    while(list.length > 1){
      var L = list.shift();
      var R = list.pop();
      if(Math.abs(L - R) != 0){
        count++;
      }
    }
    if(count > 0){
      output[i] = count;
    }else{
      output[i] = 1;
    }
  }
  myout(myconv(output, 9));
}

//Don't have to see. start------------------------------------------
var read = require('readline').createInterface({
  input: process.stdin, output: process.stdout
});
var obj; var inLine = [];
read.on('line', function(input){inLine.push(input);});
read.on('close', function(){
  obj = init(inLine);
  console.error('\n');
  var start = Date.now();
  Main();
  var end = Date.now() - start;
  myerr('time : ' + end + 'ms');
  myerr('memory : ' + Math.round(process.memoryUsage().heapTotal / 1024) + 'KB');
});
function makeClone(obj){return (obj instanceof Set) ? new Set(Array.from(obj)) : JSON.parse(JSON.stringify(obj));}
function nextInt(){return myconv(next(),1);} function nextStrArray(){return myconv(next(),2);}
function nextIntArray(){return myconv(next(),4);} function nextCharArray(){return myconv(next(),6);}
function next(){return obj.next();} function hasNext(){return obj.hasNext();}
function init(input){
  return {
    list : input, index : 0, max : input.length,
    hasNext : function(){return (this.index < this.max);},
    next : function(){if(this.hasNext()){return this.list[this.index++];}else{throw 'ArrayIndexOutOfBoundsException ‚There is no more input';}}
  };
}
function myout(s){console.log(s);}
function myerr(s){console.error('debug:' + require('util').inspect(s,false,null));}
//param "no" is
//unknown or outlier : return i. 1: parseInt.
//2: split space. 4: split space and parseInt.
//6: split 1 character. 7: split 1 character and parseInt.
//8: join space. 9: join nextline. 0: join no character.
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(' ');case 4:return i.split(' ').map(Number);case 6:return i.split('');case 7:return i.split('').map(Number);case 8:return i.join(' ');case 9:return i.join('\n');case 0:return i.join('');default:return i;}}catch(e){return i;}}

//Don't have to see. end------------------------------------------
function Main(){
  var t = nextInt();
  var output = new Array(t);
  for(var i = 0; i < t; i++){
    var N = nextInt();
    var list = nextIntArray();
    var count = 0;
    list.sort(function(a,b){
    	return a - b;
    });
    while(list.length > 1){
      var L = list.shift();
      var R = list.pop();
      if(Math.abs(L - R) != 1){
        count++;
      }
    }
    if(count > 0){
      output[i] = count;
    }else if(N == 1){
      output[i] = 1;
    }else{
      output[i] = 0;
    }
  }
  myout(myconv(output, 9));
}

let i = ''
process.stdin.on('data', c => i += c)
process.stdin.on('end', () => {
    const {EOL} = require('os')
    const lines = i.split(EOL);

    function foo (data, n) {
        data.sort((a, b) => a - b);

        let result = 0;
        let index = 0;

        while (index < data.length) {
            if (data[index] + 1 === data[index + 1]) {
                result++;
                index++;
            }
            index++;
        }
        return result ? result : 1;
    }

    let testCount = 1;
    let answer = '';
    while(testCount <= +lines[0]) {
        let data = lines[testCount * 2].split(" ").map(Number);
        let n = lines[testCount * 2 - 1].split(" ").map(Number);

        let result = foo(data, n);
        answer += result +"\n";
        testCount++;
    }
    console.log(answer);
})

let i = ''
process.stdin.on('data', c => i += c)
process.stdin.on('end', () => {
    const {EOL} = require('os')
    const lines = i.split(EOL);

    function foo (data, n) {
        data.sort((a, b) => a - b);

        let result = 1;
        let index = 0;

        while (index < data.length) {
            if (data[index] + 1 === data[index + 1]) {
                result = 2;
            }
            index++;
            break;
        }
        return result;
    }

    let testCount = 1;
    let answer = '';
    while(testCount <= +lines[0]) {
        let data = lines[testCount * 2].split(" ").map(Number);
        let n = lines[testCount * 2 - 1].split(" ").map(Number);

        let result = foo(data, n);
        answer += result +"\n";
        testCount++;
    }
    console.log(answer);
})

const readline = require('readline');
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});
let c = 0;

rl.on('line', (d) => {
  if (c === 0) {
    c++;
    return;
  }

  if (c % 2 === 1) {
    c++;
    return;
  }

  const arr = d.split(' ').map(Number);

  console.log(Math.max(1, Math.floor(arr.length / 2)));

  c++;
});

"use strict";

process.stdin.resume();
process.stdin.setEncoding('utf8');

let input_stdin = '';

process.stdin.on('data', function (data) {
    input_stdin += data;
});

process.stdin.on('end', function () {
    let chunks = '';
    chunks = input_stdin.split('\n');
    start(chunks);
});

function start(input) {
    let queries = +input.shift();

    while(queries--) {
        input.shift();
        const array = input.shift().split(' ').map(Number);
        const hash = {};
        let answer = 1;
        for(const element of array) {
            if((element && hash[element - 1]) || hash[element + 1]) {
                answer = 2;
                break;
            }
        }
        console.log(answer);
    }
}

'use strict';

const nQueues = this.readline().split(" ");

for (let i = 0; i < nQueues; i++) {
  const nStds = this.readline();
  let scoresL = this.readline();
  this.print(scoresL)
  if(scoresL){
  let scores = [];
  scoresL.split(" ").forEach(el => scores.push(parseInt(el)));

  scores = scores.sort((a, b) => a - b);
  let has = false;
  for (let j = 1; j < nStds; j++) {
    if (Math.abs(scores[j - 1] - scores[j]) === 1) {
      has = true;
      break;
    }
  }
  if (has) {
    this.print(2);
  } else {
    this.print(1);
  }
  }

}

var tc = parseInt(readline());
while(tc--){
    var n = parseInt(readline());
    var arr = readline().split(" ").map(x => parseInt(x));
    var aux = [{}];
    //arr.forEach(x => write(x+" "));
    for(var i=0;i<arr.length;i++){
        var cabe=false;
        //print("n = "+arr[i]);
        aux.forEach(function(element){
            if(element[arr[i]+1]===undefined && element[arr[i]-1]===undefined && !cabe) {
                cabe=true;
                element[arr[i]]=i;
            }
        });
        if(!cabe){
            aux.push([]);
            aux[aux.length-1][arr[i]] = i;
        }
    }
    /*aux.forEach(function(element){
        Object.keys(element).forEach(function(key){
            write(key+" ");
        });
        print();
    });*/
    print(aux.length);
}

var tc = parseInt(readline());
while(tc--){
    var n = parseInt(readline());
    var arr = readline().split(" ").map(x => parseInt(x));
    var aux = [{}];
    //arr.forEach(x => write(x+" "));
    for(var i=0;i<arr.length;i++){
        var cabe=false;
        //print("n = "+arr[i]);
        aux.forEach(function(element){
            if(cabe) return;
            if(element[arr[i]+1]===undefined && element[arr[i]-1]===undefined && !cabe) {
                cabe=true;
                element[arr[i]]=i;
            }
        });
        if(!cabe){
            aux.push([]);
            aux[aux.length-1][arr[i]] = i;
        }
    }
    /*aux.forEach(function(element){
        Object.keys(element).forEach(function(key){
            write(key+" ");
        });
        print();
    });*/
    print(aux.length);
}

q=readline()

while(q-->0){
    n=readline()
    a=readline().split(' ')
    hoga=false
    for(i=0;i<a.length-1;i++){
        if(Math.abs(a[i]-a[i+1])==1)
            hoga=true;
    }
    if(hoga)
        print(2)
    else
        print(1)
}

//var input = readline()
var Test = parseInt(readline());
while(Test -- > 0) {
    var n = parseInt(readline());
    var ar = readline().split(' ').map(x => parseInt(x));
    var s = ar.sort((a, b) => (a - b));
    var check = false;
    if(n > 1) {
        if(s[1]-s[0] === 1) check = true;
        else check = false;
    }
    else check = false;
    print(check ? 2 : 1);
}


var dataitr;
var stdin_input = "";
process.stdin.resume();
process.stdin.setEncoding("ascii");
process.stdin.on("data", function (input) { stdin_input += input; });
process.stdin.on("end", function () { dataitr = stdin_input.split('\n').values(); main(); });

const rl = () => dataitr.next().value.trim();
const rn = () => Number(rl());
const ra = () => rl().split(' ');
const rna = () => ra().map(x => Number(x));

const INF = 1e9;

function main () {
	let T = rn();
	while (T--) {
		const n = rn();
		const d = [];
		for (let i = 0; i < n; i++) {
			let [h, w] = rna();
			if (h < w) {
				[h, w] = [w, h];
			}
			d[i] = [h, w, i];
		}

		d.sort((x, y) => x[0] - y[0]);

		const ans = [];
		let mnw, mni;
		let curmnw = INF, curmni;
		let prvh = 0;
		for (const [h, w, indx] of d) {
			if (h > prvh) {
				mnw = curmnw;
				mni = curmni;
			}

			ans[indx] = (w > mnw ? mni + 1 : -1);

			if (w < curmnw) {
				curmnw = w;
				curmni = indx;
			}

			prvh = h;
		}

		console.log(ans.join(' '));
	}
}

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
  inputString += inputStdin;
});

process.stdin.on('end', _ => {
  inputString = inputString.trim().split('\n').map(string => {
    return string.trim();
  });

  main();
});

function readline() {
  return inputString[currentLine++];
}

// Make a Snippet for the code above this and then write your logic in main();
var mod = 998244353n
var maxN = 10e6 + 1

function main() {
  var x = parseInt(readline())
  //

  Array(parseInt(x)).fill(1).map((t, iii) => {
    var n = readline().split(' ').map((x, iii) => {
      return parseInt(x)
    });
    var tree = new RBTree((a, b) => {
      // console.log(a)
      if(a.x === b.x) return a.y - b.y
      return a.x - b.x
    })
    var array = new Array(n)
    for (let i = 0; i < n; i++) {
      var [x, y] = readline().split(' ').map((x, iii) => {
        return parseInt(x)
      });
      array[i] = {x, y, index: i}
      tree.insert({x, y, index: i})
    }
    var ans1 = solve(tree, array, n)

    var tree1 = new RBTree((a, b) => {
      if(a.x === b.x) return a.y - b.y
      return a.x - b.x
    })

    for (let i = 0; i < n; i++) {
      tree1.insert({x: array[i].y, y: array[i].x, index: i})
    }
    var ans2 = solve(tree1, array, n)

    var res = new Array(n)
    for (let i = 0; i < n; i++) {
      res[i] = -1
      if (ans1[i] !== -1) res[i] = ans1[i]+1
      if (ans2[i] !== -1) res[i] = ans2[i]+1
    }
    // console.log(ans1.join(' '))
    // console.log(ans2.join(' '))
    console.log(res.join(' '))

    // console.log(ans.map(x => x !== -1 ? x + 1 : -1).join(' '))
  })
}

function solve(tree, array, n) {

  var min = Number.MAX_SAFE_INTEGER
  var minIndex = 0
  var pref = new Array(n)
  var index = new Array(n)
  var i = 0
  tree.each((next) => {
    if (min > next.y) {
      min = next.y
      minIndex = next.index
    }
    next.pref = min
    next.index = minIndex
    i++
  })

  var ans = []
  for (let j = 0; j < array.length; j++) {

    var find = tree.upperBound({x: array[j].x - 1, y:array[j].y - 1}).prev()
    // console.log(array[j],  find)
    if (find !== null && find.pref < array[j].y && find.x < array[j].x) {
      ans.push(find.index)
      continue
    }
    ans.push(-1)
  }
  return ans
}

//start end red black tree
function TreeBase() {
}

// removes all nodes from the tree
TreeBase.prototype.clear = function () {
  this._root = null;
  this.size = 0;
};

// returns node data if found, null otherwise
TreeBase.prototype.find = function (data) {
  var res = this._root;

  while (res !== null) {
    var c = this._comparator(data, res.data);
    if (c === 0) {
      return res.data;
    } else {
      res = res.get_child(c > 0);
    }
  }

  return null;
};

// returns iterator to node if found, null otherwise
TreeBase.prototype.findIter = function (data) {
  var res = this._root;
  var iter = this.iterator();

  while (res !== null) {
    var c = this._comparator(data, res.data);
    if (c === 0) {
      iter._cursor = res;
      return iter;
    } else {
      iter._ancestors.push(res);
      res = res.get_child(c > 0);
    }
  }

  return null;
};

// Returns an iterator to the tree node at or immediately after the item
TreeBase.prototype.lowerBound = function (item) {
  var cur = this._root;
  var iter = this.iterator();
  var cmp = this._comparator;

  while (cur !== null) {
    var c = cmp(item, cur.data);
    if (c === 0) {
      iter._cursor = cur;
      return iter;
    }
    iter._ancestors.push(cur);
    cur = cur.get_child(c > 0);
  }

  for (var i = iter._ancestors.length - 1; i >= 0; --i) {
    cur = iter._ancestors[i];
    if (cmp(item, cur.data) < 0) {
      iter._cursor = cur;
      iter._ancestors.length = i;
      return iter;
    }
  }

  iter._ancestors.length = 0;
  return iter;
};

// Returns an iterator to the tree node immediately after the item
TreeBase.prototype.upperBound = function (item) {
  var iter = this.lowerBound(item);
  var cmp = this._comparator;

  while (iter.data() !== null && cmp(iter.data(), item) === 0) {
    iter.next();
  }

  return iter;
};

// returns null if tree is empty
TreeBase.prototype.min = function () {
  var res = this._root;
  if (res === null) {
    return null;
  }

  while (res.left !== null) {
    res = res.left;
  }

  return res.data;
};

// returns null if tree is empty
TreeBase.prototype.max = function () {
  var res = this._root;
  if (res === null) {
    return null;
  }

  while (res.right !== null) {
    res = res.right;
  }

  return res.data;
};

// returns a null iterator
// call next() or prev() to point to an element
TreeBase.prototype.iterator = function () {
  return new Iterator(this);
};

// calls cb on each node's data, in order
TreeBase.prototype.each = function (cb) {
  var it = this.iterator(), data;
  while ((data = it.next()) !== null) {
    if (cb(data) === false) {
      return;
    }
  }
};

// calls cb on each node's data, in reverse order
TreeBase.prototype.reach = function (cb) {
  var it = this.iterator(), data;
  while ((data = it.prev()) !== null) {
    if (cb(data) === false) {
      return;
    }
  }
};

function Iterator(tree) {
  this._tree = tree;
  this._ancestors = [];
  this._cursor = null;
}

Iterator.prototype.data = function () {
  return this._cursor !== null ? this._cursor.data : null;
};

// if null-iterator, returns first node
// otherwise, returns next node
Iterator.prototype.next = function () {
  if (this._cursor === null) {
    var root = this._tree._root;
    if (root !== null) {
      this._minNode(root);
    }
  } else {
    if (this._cursor.right === null) {
      // no greater node in subtree, go up to parent
      // if coming from a right child, continue up the stack
      var save;
      do {
        save = this._cursor;
        if (this._ancestors.length) {
          this._cursor = this._ancestors.pop();
        } else {
          this._cursor = null;
          break;
        }
      } while (this._cursor.right === save);
    } else {
      // get the next node from the subtree
      this._ancestors.push(this._cursor);
      this._minNode(this._cursor.right);
    }
  }
  return this._cursor !== null ? this._cursor.data : null;
};

// if null-iterator, returns last node
// otherwise, returns previous node
Iterator.prototype.prev = function () {
  if (this._cursor === null) {
    var root = this._tree._root;
    if (root !== null) {
      this._maxNode(root);
    }
  } else {
    if (this._cursor.left === null) {
      var save;
      do {
        save = this._cursor;
        if (this._ancestors.length) {
          this._cursor = this._ancestors.pop();
        } else {
          this._cursor = null;
          break;
        }
      } while (this._cursor.left === save);
    } else {
      this._ancestors.push(this._cursor);
      this._maxNode(this._cursor.left);
    }
  }
  return this._cursor !== null ? this._cursor.data : null;
};

Iterator.prototype._minNode = function (start) {
  while (start.left !== null) {
    this._ancestors.push(start);
    start = start.left;
  }
  this._cursor = start;
};

Iterator.prototype._maxNode = function (start) {
  while (start.right !== null) {
    this._ancestors.push(start);
    start = start.right;
  }
  this._cursor = start;
};

function Node(data) {
  this.data = data;
  this.left = null;
  this.right = null;
  this.red = true;
}

Node.prototype.get_child = function (dir) {
  return dir ? this.right : this.left;
};

Node.prototype.set_child = function (dir, val) {
  if (dir) {
    this.right = val;
  } else {
    this.left = val;
  }
};

function RBTree(comparator) {
  this._root = null;
  this._comparator = comparator;
  this.size = 0;
}

RBTree.prototype = new TreeBase();

// returns true if inserted, false if duplicate
RBTree.prototype.insert = function (data) {
  var ret = false;

  if (this._root === null) {
    // empty tree
    this._root = new Node(data);
    ret = true;
    this.size++;
  } else {
    var head = new Node(undefined); // fake tree root

    var dir = 0;
    var last = 0;

    // setup
    var gp = null; // grandparent
    var ggp = head; // grand-grand-parent
    var p = null; // parent
    var node = this._root;
    ggp.right = this._root;

    // search down
    while (true) {
      if (node === null) {
        // insert new node at the bottom
        node = new Node(data);
        p.set_child(dir, node);
        ret = true;
        this.size++;
      } else if (is_red(node.left) && is_red(node.right)) {
        // color flip
        node.red = true;
        node.left.red = false;
        node.right.red = false;
      }

      // fix red violation
      if (is_red(node) && is_red(p)) {
        var dir2 = ggp.right === gp;

        if (node === p.get_child(last)) {
          ggp.set_child(dir2, single_rotate(gp, !last));
        } else {
          ggp.set_child(dir2, double_rotate(gp, !last));
        }
      }

      var cmp = this._comparator(node.data, data);

      // stop if found
      if (cmp === 0) {
        break;
      }

      last = dir;
      dir = cmp < 0;

      // update helpers
      if (gp !== null) {
        ggp = gp;
      }
      gp = p;
      p = node;
      node = node.get_child(dir);
    }

    // update root
    this._root = head.right;
  }

  // make root black
  this._root.red = false;

  return ret;
};

// returns true if removed, false if not found
RBTree.prototype.remove = function (data) {
  if (this._root === null) {
    return false;
  }

  var head = new Node(undefined); // fake tree root
  var node = head;
  node.right = this._root;
  var p = null; // parent
  var gp = null; // grand parent
  var found = null; // found item
  var dir = 1;

  while (node.get_child(dir) !== null) {
    var last = dir;

    // update helpers
    gp = p;
    p = node;
    node = node.get_child(dir);

    var cmp = this._comparator(data, node.data);

    dir = cmp > 0;

    // save found node
    if (cmp === 0) {
      found = node;
    }

    // push the red node down
    if (!is_red(node) && !is_red(node.get_child(dir))) {
      if (is_red(node.get_child(!dir))) {
        var sr = single_rotate(node, dir);
        p.set_child(last, sr);
        p = sr;
      } else if (!is_red(node.get_child(!dir))) {
        var sibling = p.get_child(!last);
        if (sibling !== null) {
          if (!is_red(sibling.get_child(!last)) && !is_red(sibling.get_child(last))) {
            // color flip
            p.red = false;
            sibling.red = true;
            node.red = true;
          } else {
            var dir2 = gp.right === p;

            if (is_red(sibling.get_child(last))) {
              gp.set_child(dir2, double_rotate(p, last));
            } else if (is_red(sibling.get_child(!last))) {
              gp.set_child(dir2, single_rotate(p, last));
            }

            // ensure correct coloring
            var gpc = gp.get_child(dir2);
            gpc.red = true;
            node.red = true;
            gpc.left.red = false;
            gpc.right.red = false;
          }
        }
      }
    }
  }

  // replace and remove if found
  if (found !== null) {
    found.data = node.data;
    p.set_child(p.right === node, node.get_child(node.left === null));
    this.size--;
  }

  // update root and make it black
  this._root = head.right;
  if (this._root !== null) {
    this._root.red = false;
  }

  return found !== null;
};

function is_red(node) {
  return node !== null && node.red;
}

function single_rotate(root, dir) {
  var save = root.get_child(!dir);

  root.set_child(!dir, save.get_child(dir));
  save.set_child(dir, root);

  root.red = true;
  save.red = false;

  return save;
}

function double_rotate(root, dir) {
  root.set_child(!dir, single_rotate(root.get_child(!dir), !dir));
  return single_rotate(root, dir);
}

//end red black tree

const placement = a => {
  a.sort((x, y) => {
    if (x.w !== y.w) return x.w - y.w;
    return x.h - y.h;
  });
  const res = Array(a.length).fill(0);
  const minHeight = [];
  const currentMinHeight = { v: Infinity };

  for (let i = 0; i < a.length; i++) {
    if (a[i].h < currentMinHeight.v) {
      currentMinHeight.v = a[i].h;
      currentMinHeight.i = i;
    }
    minHeight.push({ ...currentMinHeight });
  }

  const findResult = (w, h) => {
    // Find smaller width
    let l = 0,
      r = a.length - 1,
      best = null;
    while (true) {
      if (l > r) break;
      m = Math.floor((l + r) / 2);
      if (a[m].w < w) {
        best = m;
        l = m + 1;
      } else r = m - 1;
    }
    // In smaller range [0, m], compare the smallest height person and input h
    if (best !== null && h > a[minHeight[best].i].h)
      return a[minHeight[best].i].i + 1;
    return null;
  };

  for (let i = 0; i < a.length; i++) {
    res[a[i].i] =
      findResult(a[i].w, a[i].h) || findResult(a[i].h, a[i].w) || -1;
  }
  return res;
};

const main = () => {
  let test = parseInt(readline());
  while (test--) {
    const n = parseInt(readline());
    let a = [];
    for (let i = 0; i < n; i++) {
      const [w, h] = readline()
        .split(" ")
        .map(s => parseInt(s));
      a.push({ w, h, i });
    }
    const res = placement(a);
    console.log(res.join(" "));
  }
};

process.stdin.resume();
process.stdin.setEncoding("utf-8");

let inputString = "";
let currentLine = 0;

process.stdin.on("data", inputStdin => {
  inputString += inputStdin;
});

process.stdin.on("end", () => {
  inputString = inputString
    .trim()
    .split("\n")
    .map(string => string.trim());
  main();
});

const readline = () => {
  return inputString[currentLine++];
};

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
  inputString += inputStdin;
});

process.stdin.on('end', _ => {
  inputString = inputString.trim().split('\n').map(string => {
    return string.trim();
  });

  main();
});

function readline() {
  return inputString[currentLine++];
}

// Make a Snippet for the code above this and then write your logic in main();
var mod = 998244353n
var maxN = 10e6 + 1

function main() {
  var x = parseInt(readline())
  //

  Array(parseInt(x)).fill(1).map((t, iii) => {
    var n = readline().split(' ').map((x, iii) => {
      return parseInt(x)
    });
    var tree = new RBTree((a, b) => {
      // console.log(a)
      if(a.x === b.x) return a.y - b.y
      return a.x - b.x
    })
    var array = new Array(n)
    for (let i = 0; i < n; i++) {
      var [x, y] = readline().split(' ').map((x, iii) => {
        return parseInt(x)
      });
      array[i] = {x, y, index: i}
      tree.insert({x, y, index: i})
    }
    var ans1 = solve(tree, array, n)

    var tree1 = new RBTree((a, b) => {
      if(a.x === b.x) return a.y - b.y
      return a.x - b.x
    })

    for (let i = 0; i < n; i++) {
      tree1.insert({x: array[i].y, y: array[i].x, index: i})
    }
    var ans2 = solve(tree1, array, n)

    var res = new Array(n)
    for (let i = 0; i < n; i++) {
      res[i] = -1
      if (ans1[i] !== -1) res[i] = ans1[i]+1
      if (ans2[i] !== -1) res[i] = ans2[i]+1
    }
    // console.log(ans1.join(' '))
    // console.log(ans2.join(' '))
    console.log(res.join(' '))

    // console.log(ans.map(x => x !== -1 ? x + 1 : -1).join(' '))
  })
}

function solve(tree, array, n) {

  var min = Number.MAX_SAFE_INTEGER
  var minIndex = 0
  var pref = new Array(n)
  var index = new Array(n)
  var i = 0
  tree.each((next) => {
    if (min > next.y) {
      min = next.y
      minIndex = next.index
    }
    next.pref = min
    next.index = minIndex
    i++
  })

  var ans = []
  for (let j = 0; j < array.length; j++) {

    var find = tree.lowerBound({x: array[j].x - 1}).prev()
    // console.log(array[j],  find)
    if (find !== null && find.pref < array[j].y && find.x < array[j].x) {
      ans.push(find.index)
      continue
    }
    ans.push(-1)
  }
  return ans
}

//start end red black tree
function TreeBase() {
}

// removes all nodes from the tree
TreeBase.prototype.clear = function () {
  this._root = null;
  this.size = 0;
};

// returns node data if found, null otherwise
TreeBase.prototype.find = function (data) {
  var res = this._root;

  while (res !== null) {
    var c = this._comparator(data, res.data);
    if (c === 0) {
      return res.data;
    } else {
      res = res.get_child(c > 0);
    }
  }

  return null;
};

// returns iterator to node if found, null otherwise
TreeBase.prototype.findIter = function (data) {
  var res = this._root;
  var iter = this.iterator();

  while (res !== null) {
    var c = this._comparator(data, res.data);
    if (c === 0) {
      iter._cursor = res;
      return iter;
    } else {
      iter._ancestors.push(res);
      res = res.get_child(c > 0);
    }
  }

  return null;
};

// Returns an iterator to the tree node at or immediately after the item
TreeBase.prototype.lowerBound = function (item) {
  var cur = this._root;
  var iter = this.iterator();
  var cmp = this._comparator;

  while (cur !== null) {
    var c = cmp(item, cur.data);
    if (c === 0) {
      iter._cursor = cur;
      return iter;
    }
    iter._ancestors.push(cur);
    cur = cur.get_child(c > 0);
  }

  for (var i = iter._ancestors.length - 1; i >= 0; --i) {
    cur = iter._ancestors[i];
    if (cmp(item, cur.data) < 0) {
      iter._cursor = cur;
      iter._ancestors.length = i;
      return iter;
    }
  }

  iter._ancestors.length = 0;
  return iter;
};

// Returns an iterator to the tree node immediately after the item
TreeBase.prototype.upperBound = function (item) {
  var iter = this.lowerBound(item);
  var cmp = this._comparator;

  while (iter.data() !== null && cmp(iter.data(), item) === 0) {
    iter.next();
  }

  return iter;
};

// returns null if tree is empty
TreeBase.prototype.min = function () {
  var res = this._root;
  if (res === null) {
    return null;
  }

  while (res.left !== null) {
    res = res.left;
  }

  return res.data;
};

// returns null if tree is empty
TreeBase.prototype.max = function () {
  var res = this._root;
  if (res === null) {
    return null;
  }

  while (res.right !== null) {
    res = res.right;
  }

  return res.data;
};

// returns a null iterator
// call next() or prev() to point to an element
TreeBase.prototype.iterator = function () {
  return new Iterator(this);
};

// calls cb on each node's data, in order
TreeBase.prototype.each = function (cb) {
  var it = this.iterator(), data;
  while ((data = it.next()) !== null) {
    if (cb(data) === false) {
      return;
    }
  }
};

// calls cb on each node's data, in reverse order
TreeBase.prototype.reach = function (cb) {
  var it = this.iterator(), data;
  while ((data = it.prev()) !== null) {
    if (cb(data) === false) {
      return;
    }
  }
};

function Iterator(tree) {
  this._tree = tree;
  this._ancestors = [];
  this._cursor = null;
}

Iterator.prototype.data = function () {
  return this._cursor !== null ? this._cursor.data : null;
};

// if null-iterator, returns first node
// otherwise, returns next node
Iterator.prototype.next = function () {
  if (this._cursor === null) {
    var root = this._tree._root;
    if (root !== null) {
      this._minNode(root);
    }
  } else {
    if (this._cursor.right === null) {
      // no greater node in subtree, go up to parent
      // if coming from a right child, continue up the stack
      var save;
      do {
        save = this._cursor;
        if (this._ancestors.length) {
          this._cursor = this._ancestors.pop();
        } else {
          this._cursor = null;
          break;
        }
      } while (this._cursor.right === save);
    } else {
      // get the next node from the subtree
      this._ancestors.push(this._cursor);
      this._minNode(this._cursor.right);
    }
  }
  return this._cursor !== null ? this._cursor.data : null;
};

// if null-iterator, returns last node
// otherwise, returns previous node
Iterator.prototype.prev = function () {
  if (this._cursor === null) {
    var root = this._tree._root;
    if (root !== null) {
      this._maxNode(root);
    }
  } else {
    if (this._cursor.left === null) {
      var save;
      do {
        save = this._cursor;
        if (this._ancestors.length) {
          this._cursor = this._ancestors.pop();
        } else {
          this._cursor = null;
          break;
        }
      } while (this._cursor.left === save);
    } else {
      this._ancestors.push(this._cursor);
      this._maxNode(this._cursor.left);
    }
  }
  return this._cursor !== null ? this._cursor.data : null;
};

Iterator.prototype._minNode = function (start) {
  while (start.left !== null) {
    this._ancestors.push(start);
    start = start.left;
  }
  this._cursor = start;
};

Iterator.prototype._maxNode = function (start) {
  while (start.right !== null) {
    this._ancestors.push(start);
    start = start.right;
  }
  this._cursor = start;
};

function Node(data) {
  this.data = data;
  this.left = null;
  this.right = null;
  this.red = true;
}

Node.prototype.get_child = function (dir) {
  return dir ? this.right : this.left;
};

Node.prototype.set_child = function (dir, val) {
  if (dir) {
    this.right = val;
  } else {
    this.left = val;
  }
};

function RBTree(comparator) {
  this._root = null;
  this._comparator = comparator;
  this.size = 0;
}

RBTree.prototype = new TreeBase();

// returns true if inserted, false if duplicate
RBTree.prototype.insert = function (data) {
  var ret = false;

  if (this._root === null) {
    // empty tree
    this._root = new Node(data);
    ret = true;
    this.size++;
  } else {
    var head = new Node(undefined); // fake tree root

    var dir = 0;
    var last = 0;

    // setup
    var gp = null; // grandparent
    var ggp = head; // grand-grand-parent
    var p = null; // parent
    var node = this._root;
    ggp.right = this._root;

    // search down
    while (true) {
      if (node === null) {
        // insert new node at the bottom
        node = new Node(data);
        p.set_child(dir, node);
        ret = true;
        this.size++;
      } else if (is_red(node.left) && is_red(node.right)) {
        // color flip
        node.red = true;
        node.left.red = false;
        node.right.red = false;
      }

      // fix red violation
      if (is_red(node) && is_red(p)) {
        var dir2 = ggp.right === gp;

        if (node === p.get_child(last)) {
          ggp.set_child(dir2, single_rotate(gp, !last));
        } else {
          ggp.set_child(dir2, double_rotate(gp, !last));
        }
      }

      var cmp = this._comparator(node.data, data);

      // stop if found
      if (cmp === 0) {
        break;
      }

      last = dir;
      dir = cmp < 0;

      // update helpers
      if (gp !== null) {
        ggp = gp;
      }
      gp = p;
      p = node;
      node = node.get_child(dir);
    }

    // update root
    this._root = head.right;
  }

  // make root black
  this._root.red = false;

  return ret;
};

// returns true if removed, false if not found
RBTree.prototype.remove = function (data) {
  if (this._root === null) {
    return false;
  }

  var head = new Node(undefined); // fake tree root
  var node = head;
  node.right = this._root;
  var p = null; // parent
  var gp = null; // grand parent
  var found = null; // found item
  var dir = 1;

  while (node.get_child(dir) !== null) {
    var last = dir;

    // update helpers
    gp = p;
    p = node;
    node = node.get_child(dir);

    var cmp = this._comparator(data, node.data);

    dir = cmp > 0;

    // save found node
    if (cmp === 0) {
      found = node;
    }

    // push the red node down
    if (!is_red(node) && !is_red(node.get_child(dir))) {
      if (is_red(node.get_child(!dir))) {
        var sr = single_rotate(node, dir);
        p.set_child(last, sr);
        p = sr;
      } else if (!is_red(node.get_child(!dir))) {
        var sibling = p.get_child(!last);
        if (sibling !== null) {
          if (!is_red(sibling.get_child(!last)) && !is_red(sibling.get_child(last))) {
            // color flip
            p.red = false;
            sibling.red = true;
            node.red = true;
          } else {
            var dir2 = gp.right === p;

            if (is_red(sibling.get_child(last))) {
              gp.set_child(dir2, double_rotate(p, last));
            } else if (is_red(sibling.get_child(!last))) {
              gp.set_child(dir2, single_rotate(p, last));
            }

            // ensure correct coloring
            var gpc = gp.get_child(dir2);
            gpc.red = true;
            node.red = true;
            gpc.left.red = false;
            gpc.right.red = false;
          }
        }
      }
    }
  }

  // replace and remove if found
  if (found !== null) {
    found.data = node.data;
    p.set_child(p.right === node, node.get_child(node.left === null));
    this.size--;
  }

  // update root and make it black
  this._root = head.right;
  if (this._root !== null) {
    this._root.red = false;
  }

  return found !== null;
};

function is_red(node) {
  return node !== null && node.red;
}

function single_rotate(root, dir) {
  var save = root.get_child(!dir);

  root.set_child(!dir, save.get_child(dir));
  save.set_child(dir, root);

  root.red = true;
  save.red = false;

  return save;
}

function double_rotate(root, dir) {
  root.set_child(!dir, single_rotate(root.get_child(!dir), !dir));
  return single_rotate(root, dir);
}

//end red black tree

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
  inputString += inputStdin;
});

process.stdin.on('end', _ => {
  inputString = inputString.trim().split('\n').map(string => {
    return string.trim();
  });

  main();
});

function readline() {
  return inputString[currentLine++];
}

// Make a Snippet for the code above this and then write your logic in main();
var mod = 998244353n
var maxN = 10e6 + 1

function main() {
  var x = parseInt(readline())
  //

  Array(parseInt(x)).fill(1).map((t, iii) => {
    var n = readline().split(' ').map((x, iii) => {
      return parseInt(x)
    });
    var tree = new RBTree((a, b) => {
      // console.log(a)
      return a.x - b.x
    })
    var array = new Array(n)
    for (let i = 0; i < n; i++) {
      var [x, y] = readline().split(' ').map((x, iii) => {
        return parseInt(x)
      });
      array[i] = {x, y, index: i}
      tree.insert({x, y, index: i})
    }
    var ans1 = solve(tree, array, n)

    tree = new RBTree((a, b) => {
      return a.x - b.x
    })

    for (let i = 0; i < n; i++) {
      tree.insert({x: array[i].y, y: array[i].x, index: i})
    }
    var ans2 = solve(tree, array, n)

    var res = new Array(n)
    for (let i = 0; i < n; i++) {
      res[i] = -1
      if (ans1[i] !== -1) res[i] = ans1[i]+1
      if (ans2[i] !== -1) res[i] = ans2[i]+1
    }
    console.log(res.join(' '))

    // console.log(ans.map(x => x !== -1 ? x + 1 : -1).join(' '))
  })
}

function solve(tree, array, n) {

  var min = Number.MAX_SAFE_INTEGER
  var minIndex = 0
  var pref = new Array(n)
  var index = new Array(n)
  var i = 0
  tree.each((next) => {
    if (min > next.y) {
      min = next.y
      minIndex = next.index
    }
    next.pref = min
    next.index = minIndex
    i++
  })

  var ans = []
  for (let j = 0; j < array.length; j++) {

    var find = tree.lowerBound({x: array[j].x - 1})
    // console.log(array[j], find.data() !== null, find.pref , array[j].y)
    if (find.data() !== null && find.data().pref < array[j].y && find.data().x < array[j].x) {
      ans.push(find.data().index)
      continue
    }
    ans.push(-1)
  }
  return ans
}

//start end red black tree
function TreeBase() {
}

// removes all nodes from the tree
TreeBase.prototype.clear = function () {
  this._root = null;
  this.size = 0;
};

// returns node data if found, null otherwise
TreeBase.prototype.find = function (data) {
  var res = this._root;

  while (res !== null) {
    var c = this._comparator(data, res.data);
    if (c === 0) {
      return res.data;
    } else {
      res = res.get_child(c > 0);
    }
  }

  return null;
};

// returns iterator to node if found, null otherwise
TreeBase.prototype.findIter = function (data) {
  var res = this._root;
  var iter = this.iterator();

  while (res !== null) {
    var c = this._comparator(data, res.data);
    if (c === 0) {
      iter._cursor = res;
      return iter;
    } else {
      iter._ancestors.push(res);
      res = res.get_child(c > 0);
    }
  }

  return null;
};

// Returns an iterator to the tree node at or immediately after the item
TreeBase.prototype.lowerBound = function (item) {
  var cur = this._root;
  var iter = this.iterator();
  var cmp = this._comparator;

  while (cur !== null) {
    var c = cmp(item, cur.data);
    if (c === 0) {
      iter._cursor = cur;
      return iter;
    }
    iter._ancestors.push(cur);
    cur = cur.get_child(c > 0);
  }

  for (var i = iter._ancestors.length - 1; i >= 0; --i) {
    cur = iter._ancestors[i];
    if (cmp(item, cur.data) < 0) {
      iter._cursor = cur;
      iter._ancestors.length = i;
      return iter;
    }
  }

  iter._ancestors.length = 0;
  return iter;
};

// Returns an iterator to the tree node immediately after the item
TreeBase.prototype.upperBound = function (item) {
  var iter = this.lowerBound(item);
  var cmp = this._comparator;

  while (iter.data() !== null && cmp(iter.data(), item) === 0) {
    iter.next();
  }

  return iter;
};

// returns null if tree is empty
TreeBase.prototype.min = function () {
  var res = this._root;
  if (res === null) {
    return null;
  }

  while (res.left !== null) {
    res = res.left;
  }

  return res.data;
};

// returns null if tree is empty
TreeBase.prototype.max = function () {
  var res = this._root;
  if (res === null) {
    return null;
  }

  while (res.right !== null) {
    res = res.right;
  }

  return res.data;
};

// returns a null iterator
// call next() or prev() to point to an element
TreeBase.prototype.iterator = function () {
  return new Iterator(this);
};

// calls cb on each node's data, in order
TreeBase.prototype.each = function (cb) {
  var it = this.iterator(), data;
  while ((data = it.next()) !== null) {
    if (cb(data) === false) {
      return;
    }
  }
};

// calls cb on each node's data, in reverse order
TreeBase.prototype.reach = function (cb) {
  var it = this.iterator(), data;
  while ((data = it.prev()) !== null) {
    if (cb(data) === false) {
      return;
    }
  }
};

function Iterator(tree) {
  this._tree = tree;
  this._ancestors = [];
  this._cursor = null;
}

Iterator.prototype.data = function () {
  return this._cursor !== null ? this._cursor.data : null;
};

// if null-iterator, returns first node
// otherwise, returns next node
Iterator.prototype.next = function () {
  if (this._cursor === null) {
    var root = this._tree._root;
    if (root !== null) {
      this._minNode(root);
    }
  } else {
    if (this._cursor.right === null) {
      // no greater node in subtree, go up to parent
      // if coming from a right child, continue up the stack
      var save;
      do {
        save = this._cursor;
        if (this._ancestors.length) {
          this._cursor = this._ancestors.pop();
        } else {
          this._cursor = null;
          break;
        }
      } while (this._cursor.right === save);
    } else {
      // get the next node from the subtree
      this._ancestors.push(this._cursor);
      this._minNode(this._cursor.right);
    }
  }
  return this._cursor !== null ? this._cursor.data : null;
};

// if null-iterator, returns last node
// otherwise, returns previous node
Iterator.prototype.prev = function () {
  if (this._cursor === null) {
    var root = this._tree._root;
    if (root !== null) {
      this._maxNode(root);
    }
  } else {
    if (this._cursor.left === null) {
      var save;
      do {
        save = this._cursor;
        if (this._ancestors.length) {
          this._cursor = this._ancestors.pop();
        } else {
          this._cursor = null;
          break;
        }
      } while (this._cursor.left === save);
    } else {
      this._ancestors.push(this._cursor);
      this._maxNode(this._cursor.left);
    }
  }
  return this._cursor !== null ? this._cursor.data : null;
};

Iterator.prototype._minNode = function (start) {
  while (start.left !== null) {
    this._ancestors.push(start);
    start = start.left;
  }
  this._cursor = start;
};

Iterator.prototype._maxNode = function (start) {
  while (start.right !== null) {
    this._ancestors.push(start);
    start = start.right;
  }
  this._cursor = start;
};

function Node(data) {
  this.data = data;
  this.left = null;
  this.right = null;
  this.red = true;
}

Node.prototype.get_child = function (dir) {
  return dir ? this.right : this.left;
};

Node.prototype.set_child = function (dir, val) {
  if (dir) {
    this.right = val;
  } else {
    this.left = val;
  }
};

function RBTree(comparator) {
  this._root = null;
  this._comparator = comparator;
  this.size = 0;
}

RBTree.prototype = new TreeBase();

// returns true if inserted, false if duplicate
RBTree.prototype.insert = function (data) {
  var ret = false;

  if (this._root === null) {
    // empty tree
    this._root = new Node(data);
    ret = true;
    this.size++;
  } else {
    var head = new Node(undefined); // fake tree root

    var dir = 0;
    var last = 0;

    // setup
    var gp = null; // grandparent
    var ggp = head; // grand-grand-parent
    var p = null; // parent
    var node = this._root;
    ggp.right = this._root;

    // search down
    while (true) {
      if (node === null) {
        // insert new node at the bottom
        node = new Node(data);
        p.set_child(dir, node);
        ret = true;
        this.size++;
      } else if (is_red(node.left) && is_red(node.right)) {
        // color flip
        node.red = true;
        node.left.red = false;
        node.right.red = false;
      }

      // fix red violation
      if (is_red(node) && is_red(p)) {
        var dir2 = ggp.right === gp;

        if (node === p.get_child(last)) {
          ggp.set_child(dir2, single_rotate(gp, !last));
        } else {
          ggp.set_child(dir2, double_rotate(gp, !last));
        }
      }

      var cmp = this._comparator(node.data, data);

      // stop if found
      if (cmp === 0) {
        break;
      }

      last = dir;
      dir = cmp < 0;

      // update helpers
      if (gp !== null) {
        ggp = gp;
      }
      gp = p;
      p = node;
      node = node.get_child(dir);
    }

    // update root
    this._root = head.right;
  }

  // make root black
  this._root.red = false;

  return ret;
};

// returns true if removed, false if not found
RBTree.prototype.remove = function (data) {
  if (this._root === null) {
    return false;
  }

  var head = new Node(undefined); // fake tree root
  var node = head;
  node.right = this._root;
  var p = null; // parent
  var gp = null; // grand parent
  var found = null; // found item
  var dir = 1;

  while (node.get_child(dir) !== null) {
    var last = dir;

    // update helpers
    gp = p;
    p = node;
    node = node.get_child(dir);

    var cmp = this._comparator(data, node.data);

    dir = cmp > 0;

    // save found node
    if (cmp === 0) {
      found = node;
    }

    // push the red node down
    if (!is_red(node) && !is_red(node.get_child(dir))) {
      if (is_red(node.get_child(!dir))) {
        var sr = single_rotate(node, dir);
        p.set_child(last, sr);
        p = sr;
      } else if (!is_red(node.get_child(!dir))) {
        var sibling = p.get_child(!last);
        if (sibling !== null) {
          if (!is_red(sibling.get_child(!last)) && !is_red(sibling.get_child(last))) {
            // color flip
            p.red = false;
            sibling.red = true;
            node.red = true;
          } else {
            var dir2 = gp.right === p;

            if (is_red(sibling.get_child(last))) {
              gp.set_child(dir2, double_rotate(p, last));
            } else if (is_red(sibling.get_child(!last))) {
              gp.set_child(dir2, single_rotate(p, last));
            }

            // ensure correct coloring
            var gpc = gp.get_child(dir2);
            gpc.red = true;
            node.red = true;
            gpc.left.red = false;
            gpc.right.red = false;
          }
        }
      }
    }
  }

  // replace and remove if found
  if (found !== null) {
    found.data = node.data;
    p.set_child(p.right === node, node.get_child(node.left === null));
    this.size--;
  }

  // update root and make it black
  this._root = head.right;
  if (this._root !== null) {
    this._root.red = false;
  }

  return found !== null;
};

function is_red(node) {
  return node !== null && node.red;
}

function single_rotate(root, dir) {
  var save = root.get_child(!dir);

  root.set_child(!dir, save.get_child(dir));
  save.set_child(dir, root);

  root.red = true;
  save.red = false;

  return save;
}

function double_rotate(root, dir) {
  root.set_child(!dir, single_rotate(root.get_child(!dir), !dir));
  return single_rotate(root, dir);
}

//end red black tree

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
  inputString += inputStdin;
});

process.stdin.on('end', _ => {
  inputString = inputString.trim().split('\n').map(string => {
    return string.trim();
  });

  main();
});

function readline() {
  return inputString[currentLine++];
}

// Make a Snippet for the code above this and then write your logic in main();
var mod = 998244353n
var maxN = 10e6 + 1

function main() {
  var x = parseInt(readline())
  //

  Array(parseInt(x)).fill(1).map((t, iii) => {
    var n = readline().split(' ').map((x, iii) => {
      return parseInt(x)
    });
    var tree = new RBTree((a, b) => {
      // console.log(a)
      return a.x - b.x
    })
    var array = new Array(n)
    for (let i = 0; i < n; i++) {
      var [x, y] = readline().split(' ').map((x, iii) => {
        return parseInt(x)
      });
      array[i] = {x, y, index: i}
      tree.insert({x, y, index: i})
    }
    var ans1 = solve(tree, array, n)

    tree = new RBTree((a, b) => {
      return a.x - b.x
    })

    for (let i = 0; i < n; i++) {
      tree.insert({x: array[i].y, y: array[i].x, index: i})
    }
    var ans2 = solve(tree, array, n)

    var res = new Array(n)
    for (let i = 0; i < n; i++) {
      res[i] = -1
      if(ans1[i] !==-1)res[i] =ans1[i]
      if( ans2[i] !==-1)res[i] =ans2[i]
    }
    console.log(res.join(' '))

    // console.log(ans.map(x => x !== -1 ? x + 1 : -1).join(' '))
  })
}

function solve(tree, array, n) {

  var min = Number.MAX_SAFE_INTEGER
  var minIndex = 0
  var pref = new Array(n)
  var index = new Array(n)
  var i = 0
  tree.each((next) => {
    if (min > next.y) {
      min = next.y
      minIndex = next.index
    }
    next.pref = min
    next.index = minIndex
    i++
  })

  var ans = []
  for (let j = 0; j < array.length; j++) {

    var find = tree.lowerBound({x: array[j].x-1})
    // console.log(array[j], find.data() !== null, find.pref , array[j].y)
    if (find.data() !== null && find.data().pref < array[j].y&& find.data().x < array[j].x) {
      ans.push(find.data().index)
      continue
    }
    ans.push(-1)
  }
  return ans
}

//start end red black tree
function TreeBase() {
}

// removes all nodes from the tree
TreeBase.prototype.clear = function () {
  this._root = null;
  this.size = 0;
};

// returns node data if found, null otherwise
TreeBase.prototype.find = function (data) {
  var res = this._root;

  while (res !== null) {
    var c = this._comparator(data, res.data);
    if (c === 0) {
      return res.data;
    } else {
      res = res.get_child(c > 0);
    }
  }

  return null;
};

// returns iterator to node if found, null otherwise
TreeBase.prototype.findIter = function (data) {
  var res = this._root;
  var iter = this.iterator();

  while (res !== null) {
    var c = this._comparator(data, res.data);
    if (c === 0) {
      iter._cursor = res;
      return iter;
    } else {
      iter._ancestors.push(res);
      res = res.get_child(c > 0);
    }
  }

  return null;
};

// Returns an iterator to the tree node at or immediately after the item
TreeBase.prototype.lowerBound = function (item) {
  var cur = this._root;
  var iter = this.iterator();
  var cmp = this._comparator;

  while (cur !== null) {
    var c = cmp(item, cur.data);
    if (c === 0) {
      iter._cursor = cur;
      return iter;
    }
    iter._ancestors.push(cur);
    cur = cur.get_child(c > 0);
  }

  for (var i = iter._ancestors.length - 1; i >= 0; --i) {
    cur = iter._ancestors[i];
    if (cmp(item, cur.data) < 0) {
      iter._cursor = cur;
      iter._ancestors.length = i;
      return iter;
    }
  }

  iter._ancestors.length = 0;
  return iter;
};

// Returns an iterator to the tree node immediately after the item
TreeBase.prototype.upperBound = function (item) {
  var iter = this.lowerBound(item);
  var cmp = this._comparator;

  while (iter.data() !== null && cmp(iter.data(), item) === 0) {
    iter.next();
  }

  return iter;
};

// returns null if tree is empty
TreeBase.prototype.min = function () {
  var res = this._root;
  if (res === null) {
    return null;
  }

  while (res.left !== null) {
    res = res.left;
  }

  return res.data;
};

// returns null if tree is empty
TreeBase.prototype.max = function () {
  var res = this._root;
  if (res === null) {
    return null;
  }

  while (res.right !== null) {
    res = res.right;
  }

  return res.data;
};

// returns a null iterator
// call next() or prev() to point to an element
TreeBase.prototype.iterator = function () {
  return new Iterator(this);
};

// calls cb on each node's data, in order
TreeBase.prototype.each = function (cb) {
  var it = this.iterator(), data;
  while ((data = it.next()) !== null) {
    if (cb(data) === false) {
      return;
    }
  }
};

// calls cb on each node's data, in reverse order
TreeBase.prototype.reach = function (cb) {
  var it = this.iterator(), data;
  while ((data = it.prev()) !== null) {
    if (cb(data) === false) {
      return;
    }
  }
};

function Iterator(tree) {
  this._tree = tree;
  this._ancestors = [];
  this._cursor = null;
}

Iterator.prototype.data = function () {
  return this._cursor !== null ? this._cursor.data : null;
};

// if null-iterator, returns first node
// otherwise, returns next node
Iterator.prototype.next = function () {
  if (this._cursor === null) {
    var root = this._tree._root;
    if (root !== null) {
      this._minNode(root);
    }
  } else {
    if (this._cursor.right === null) {
      // no greater node in subtree, go up to parent
      // if coming from a right child, continue up the stack
      var save;
      do {
        save = this._cursor;
        if (this._ancestors.length) {
          this._cursor = this._ancestors.pop();
        } else {
          this._cursor = null;
          break;
        }
      } while (this._cursor.right === save);
    } else {
      // get the next node from the subtree
      this._ancestors.push(this._cursor);
      this._minNode(this._cursor.right);
    }
  }
  return this._cursor !== null ? this._cursor.data : null;
};

// if null-iterator, returns last node
// otherwise, returns previous node
Iterator.prototype.prev = function () {
  if (this._cursor === null) {
    var root = this._tree._root;
    if (root !== null) {
      this._maxNode(root);
    }
  } else {
    if (this._cursor.left === null) {
      var save;
      do {
        save = this._cursor;
        if (this._ancestors.length) {
          this._cursor = this._ancestors.pop();
        } else {
          this._cursor = null;
          break;
        }
      } while (this._cursor.left === save);
    } else {
      this._ancestors.push(this._cursor);
      this._maxNode(this._cursor.left);
    }
  }
  return this._cursor !== null ? this._cursor.data : null;
};

Iterator.prototype._minNode = function (start) {
  while (start.left !== null) {
    this._ancestors.push(start);
    start = start.left;
  }
  this._cursor = start;
};

Iterator.prototype._maxNode = function (start) {
  while (start.right !== null) {
    this._ancestors.push(start);
    start = start.right;
  }
  this._cursor = start;
};

function Node(data) {
  this.data = data;
  this.left = null;
  this.right = null;
  this.red = true;
}

Node.prototype.get_child = function (dir) {
  return dir ? this.right : this.left;
};

Node.prototype.set_child = function (dir, val) {
  if (dir) {
    this.right = val;
  } else {
    this.left = val;
  }
};

function RBTree(comparator) {
  this._root = null;
  this._comparator = comparator;
  this.size = 0;
}

RBTree.prototype = new TreeBase();

// returns true if inserted, false if duplicate
RBTree.prototype.insert = function (data) {
  var ret = false;

  if (this._root === null) {
    // empty tree
    this._root = new Node(data);
    ret = true;
    this.size++;
  } else {
    var head = new Node(undefined); // fake tree root

    var dir = 0;
    var last = 0;

    // setup
    var gp = null; // grandparent
    var ggp = head; // grand-grand-parent
    var p = null; // parent
    var node = this._root;
    ggp.right = this._root;

    // search down
    while (true) {
      if (node === null) {
        // insert new node at the bottom
        node = new Node(data);
        p.set_child(dir, node);
        ret = true;
        this.size++;
      } else if (is_red(node.left) && is_red(node.right)) {
        // color flip
        node.red = true;
        node.left.red = false;
        node.right.red = false;
      }

      // fix red violation
      if (is_red(node) && is_red(p)) {
        var dir2 = ggp.right === gp;

        if (node === p.get_child(last)) {
          ggp.set_child(dir2, single_rotate(gp, !last));
        } else {
          ggp.set_child(dir2, double_rotate(gp, !last));
        }
      }

      var cmp = this._comparator(node.data, data);

      // stop if found
      if (cmp === 0) {
        break;
      }

      last = dir;
      dir = cmp < 0;

      // update helpers
      if (gp !== null) {
        ggp = gp;
      }
      gp = p;
      p = node;
      node = node.get_child(dir);
    }

    // update root
    this._root = head.right;
  }

  // make root black
  this._root.red = false;

  return ret;
};

// returns true if removed, false if not found
RBTree.prototype.remove = function (data) {
  if (this._root === null) {
    return false;
  }

  var head = new Node(undefined); // fake tree root
  var node = head;
  node.right = this._root;
  var p = null; // parent
  var gp = null; // grand parent
  var found = null; // found item
  var dir = 1;

  while (node.get_child(dir) !== null) {
    var last = dir;

    // update helpers
    gp = p;
    p = node;
    node = node.get_child(dir);

    var cmp = this._comparator(data, node.data);

    dir = cmp > 0;

    // save found node
    if (cmp === 0) {
      found = node;
    }

    // push the red node down
    if (!is_red(node) && !is_red(node.get_child(dir))) {
      if (is_red(node.get_child(!dir))) {
        var sr = single_rotate(node, dir);
        p.set_child(last, sr);
        p = sr;
      } else if (!is_red(node.get_child(!dir))) {
        var sibling = p.get_child(!last);
        if (sibling !== null) {
          if (!is_red(sibling.get_child(!last)) && !is_red(sibling.get_child(last))) {
            // color flip
            p.red = false;
            sibling.red = true;
            node.red = true;
          } else {
            var dir2 = gp.right === p;

            if (is_red(sibling.get_child(last))) {
              gp.set_child(dir2, double_rotate(p, last));
            } else if (is_red(sibling.get_child(!last))) {
              gp.set_child(dir2, single_rotate(p, last));
            }

            // ensure correct coloring
            var gpc = gp.get_child(dir2);
            gpc.red = true;
            node.red = true;
            gpc.left.red = false;
            gpc.right.red = false;
          }
        }
      }
    }
  }

  // replace and remove if found
  if (found !== null) {
    found.data = node.data;
    p.set_child(p.right === node, node.get_child(node.left === null));
    this.size--;
  }

  // update root and make it black
  this._root = head.right;
  if (this._root !== null) {
    this._root.red = false;
  }

  return found !== null;
};

function is_red(node) {
  return node !== null && node.red;
}

function single_rotate(root, dir) {
  var save = root.get_child(!dir);

  root.set_child(!dir, save.get_child(dir));
  save.set_child(dir, root);

  root.red = true;
  save.red = false;

  return save;
}

function double_rotate(root, dir) {
  root.set_child(!dir, single_rotate(root.get_child(!dir), !dir));
  return single_rotate(root, dir);
}

//end red black tree

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readline() {
    return inputString[currentLine++];
}

// Make a Snippet for the code above this and then write your logic in main();

function main() {
    const x = readline();
    var answer = []

    // console.log(Number(x))
    // 1 1 7
    // 6 9, 15, 18
    Array(Number(x)).fill(1).map((t, i) => {
        var n = Number(readline());
        var array = []
        Array(Number(n)).fill(1).map((t, i) => {
            array[i] = []
            var xx
            array[i] = readline().split(' ').map((x, i) => {
                xx = Number(x)
                return xx
            })
            array[i].push(i)
        })
        // console.log(array)
        var max = 0
        var max1 = 10000000000
        var max2 = 0

        var maxx = 0
        var maxx1 = 0
        var maxx2 = 10000000000
        array.map((x, i) => {
            if (array[i][0] < max1) {
                max = i
                max1 = array[i][0]
                max2 = array[i][1]
            }
            if (array[i][0] === max1 && max2 > array[i][1]) {
                max = i
                max1 = array[i][0]
                max2 = array[i][1]
            }

            if (array[i][1] < maxx2) {
                maxx = i
                maxx1 = array[i][0]
                maxx2 = array[i][1]
            }
            if (array[i][1] === maxx2 && maxx1 > array[i][0]) {
                maxx = i
                maxx1 = array[i][0]
                maxx2 = array[i][1]
            }
        })
        var answer = []
        // console.log(max, max1, max2, maxx, maxx1, maxx2)
        array.map((x, i) => {
            if (array[i][0] > max1 && array[i][1] > max2) {
                // console.log(i, max)
                return answer.push(max + 1)
            }
            if (array[i][1] > maxx2 && array[i][0] > maxx1) {
                // console.log(i, maxx)
                return answer.push(maxx + 1)
            }
            answer.push(-1)
        })
        console.log(answer.join(' '))
        // var sorted1 = quickSort(array, 0, array.length - 1)
        // console.log(sorted1)
    })

}

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readline() {
    return inputString[currentLine++];
}

// Make a Snippet for the code above this and then write your logic in main();

function main() {
    const x = readline();
    var answer = []

    // console.log(Number(x))
    // 1 1 7
    // 6 9, 15, 18
    Array(Number(x)).fill(1).map((t, i) => {
        var n = Number(readline());
        var array = []
        Array(Number(n)).fill(1).map((t, i) => {
            array[i] = []
            var xx
            array[i] = readline().split(' ').map((x, i) => {
                xx = Number(x)
                return xx
            })
            array[i].push(i)
        })
        // console.log(array)
        var max = 0
        var max1 = 10000000000
        var max2 = 0

        var maxx = 0
        var maxx1 = 0
        var maxx2 = 10000000000
        array.map((x, i) => {
            if (array[i][0] < max1) {
                max = i
                max1 = array[i][0]
                max2 = array[i][1]
            }
            // if (array[i][0] === max1) {
            //     max = i
            //     max1 = array[i][0]
            //     max2 = array[i][1]
            // }

            if (array[i][1] < maxx2) {
                maxx = i
                maxx1 = array[i][0]
                maxx2 = array[i][1]
            }
            // if (array[i][1] === maxx2) {
            //     maxx = i
            //     maxx1 = array[i][0]
            //     maxx2 = array[i][1]
            // }
        })
        var answer = []
        // console.log(max, max1, max2, maxx, maxx1, maxx2)
        array.map((x, i) => {
            if (array[i][0] > max1 && array[i][1] > max2) {
                // console.log(i, max)
                return answer.push(max+1)
            }
            if (array[i][1] > maxx2 && array[i][0] > maxx1) {
                // console.log(i, maxx)
                return answer.push(maxx+1)
            }
            answer.push(-1)
        })
        console.log(answer.join(' '))
        // var sorted1 = quickSort(array, 0, array.length - 1)
        // console.log(sorted1)
    })

}

'use strict';

process.stdin.resume();
process.stdin.setEncoding('utf-8');

let inputString = '';
let currentLine = 0;

process.stdin.on('data', inputStdin => {
    inputString += inputStdin;
});

process.stdin.on('end', _ => {
    inputString = inputString.trim().split('\n').map(string => {
        return string.trim();
    });

    main();
});

function readline() {
    return inputString[currentLine++];
}

// Make a Snippet for the code above this and then write your logic in main();

function main() {
    const x = readline();
    var answer = []

    // console.log(Number(x))
    // 1 1 7
    // 6 9, 15, 18
    Array(Number(x)).fill(1).map((t, i) => {
        var n = Number(readline());
        var array = []
        Array(Number(n)).fill(1).map((t, i) => {
            array[i] = []
            var xx
            array[i] = readline().split(' ').map((x, i) => {
                xx = Number(x)
                return xx
            })
            array[i].push(i)
        })
        // console.log(array)
        var max = 0
        var max1 = 10000000000
        var max2 = 0

        var maxx = 0
        var maxx1 = 0
        var maxx2 = 10000000000
        array.map((x, i) => {
            if (array[i][0] < max1) {
                max = i
                max1 = array[i][0]
                max2 = array[i][1]
            }
            // if (array[i][0] === max1) {
            //     max = i
            //     max1 = array[i][0]
            //     max2 = array[i][1]
            // }

            if (array[i][1] < maxx2) {
                maxx = i
                maxx1 = array[i][0]
                maxx2 = array[i][1]
            }
            // if (array[i][1] === maxx2) {
            //     maxx = i
            //     maxx1 = array[i][0]
            //     maxx2 = array[i][1]
            // }
        })
        var answer = []
        // console.log(max, max1, max2, maxx, maxx1, maxx2)
        array.map((x, i) => {
            if (array[i][0] > max1 && array[i][1] > max2) {
                // console.log(i, max)
                return answer.push(max+1)
            }
            if (array[i][1] > maxx2 && array[i][0] > maxx1) {
                // console.log(i, maxx)
                return answer.push(maxx+1)
            }
            answer.push(-1)
        })
        console.log(answer)
        // var sorted1 = quickSort(array, 0, array.length - 1)
        // console.log(sorted1)
    })

}

var dataitr;
var stdin_input = "";
process.stdin.resume();
process.stdin.setEncoding("ascii");
process.stdin.on("data", function (input) { stdin_input += input; });
process.stdin.on("end", function () { dataitr = stdin_input.split('\n').values(); main(); });

const rl = () => dataitr.next().value.trim();
const rn = () => Number(rl());
const ra = () => rl().split(' ');
const rna = () => ra().map(x => Number(x));

const INF = 1e9;

function main () {
	let T = rn();
	while (T--) {
		const n = rn();
		const d = [];
		for (let i = 0; i < n; i++) {
			let [h, w] = rna();
			if (h < w) {
				[h, w] = [w, h];
			}
			d[i] = [h, w, i];
		}

		d.sort((x, y) => x[0] - y[0]);

		const ans = [];
		let mnw = INF, mnwi;
		for (const [h, w, indx] of d) {
			ans[indx] = (w > mnw ? mnwi + 1 : -1);
			if (w < mnw) {
				mnw = w;
				mnwi = indx;
			}
		}

		console.log(ans.join(' '));
	}
}