Polycarp has invited $$$n$$$ friends to celebrate the New Year. During the celebration, he decided to take a group photo of all his friends. Each friend can stand or lie on the side.Each friend is characterized by two values $$$h_i$$$ (their height) and $$$w_i$$$ (their width). On the photo the $$$i$$$-th friend will occupy a rectangle $$$h_i \times w_i$$$ (if they are standing) or $$$w_i \times h_i$$$ (if they are lying on the side).The $$$j$$$-th friend can be placed in front of the $$$i$$$-th friend on the photo if his rectangle is lower and narrower than the rectangle of the $$$i$$$-th friend. Formally, at least one of the following conditions must be fulfilled:  $$$h_j < h_i$$$ and $$$w_j < w_i$$$ (both friends are standing or both are lying);  $$$w_j < h_i$$$ and $$$h_j < w_i$$$ (one of the friends is standing and the other is lying). For example, if $$$n = 3$$$, $$$h=[3,5,3]$$$ and $$$w=[4,4,3]$$$, then:  the first friend can be placed in front of the second: $$$w_1 < h_2$$$ and $$$h_1 < w_2$$$ (one of the them is standing and the other one is lying);  the third friend can be placed in front of the second: $$$h_3 < h_2$$$ and $$$w_3 < w_2$$$ (both friends are standing or both are lying). In other cases, the person in the foreground will overlap the person in the background.Help Polycarp for each $$$i$$$ find any $$$j$$$, such that the $$$j$$$-th friend can be located in front of the $$$i$$$-th friend (i.e. at least one of the conditions above is fulfilled).Please note that you do not need to find the arrangement of all people for a group photo. You just need to find for each friend $$$i$$$ any other friend $$$j$$$ who can be located in front of him. Think about it as you need to solve $$$n$$$ separate independent subproblems.

The first line contains one integer $$$t$$$ ($$$1 \leq t \leq 10^4$$$) — the number of test cases. Then $$$t$$$ test cases follow. The first line of each test case contains one integer $$$n$$$ ($$$1 \leq n \leq 2 \cdot 10^5$$$) — the number of friends. This is followed by $$$n$$$ lines, each of which contains a description of the corresponding friend. Each friend is described by two integers $$$h_i$$$ and $$$w_i$$$ ($$$1 \leq h_i, w_i \leq 10^9$$$) — height and width of the $$$i$$$-th friend, respectively. It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$2 \cdot 10^5$$$.

For each test case output $$$n$$$ integers on a separate line, where the $$$i$$$-th number is the index of a friend that can be placed in front of the $$$i$$$-th. If there is no such friend, then output -1. If there are several answers, output any.

NoteThe first test case is described in the statement.In the third test case, the following answers are also correct:   $$$[-1, -1, 1, 2]$$$;  $$$[-1, -1, 1, 1]$$$;  $$$[-1, -1, 2, 1]$$$.

'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

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(' '));
	}
}

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(' '));
	}
}


A number is ternary if it contains only digits $$$0$$$, $$$1$$$ and $$$2$$$. For example, the following numbers are ternary: $$$1022$$$, $$$11$$$, $$$21$$$, $$$2002$$$.You are given a long ternary number $$$x$$$. The first (leftmost) digit of $$$x$$$ is guaranteed to be $$$2$$$, the other digits of $$$x$$$ can be $$$0$$$, $$$1$$$ or $$$2$$$.Let's define the ternary XOR operation $$$\odot$$$ of two ternary numbers $$$a$$$ and $$$b$$$ (both of length $$$n$$$) as a number $$$c = a \odot b$$$ of length $$$n$$$, where $$$c_i = (a_i + b_i) \% 3$$$ (where $$$\%$$$ is modulo operation). In other words, add the corresponding digits and take the remainders of the sums when divided by $$$3$$$. For example, $$$10222 \odot 11021 = 21210$$$.Your task is to find such ternary numbers $$$a$$$ and $$$b$$$ both of length $$$n$$$ and both without leading zeros that $$$a \odot b = x$$$ and $$$max(a, b)$$$ is the minimum possible.You have to answer $$$t$$$ independent test cases.

The first line of the input contains one integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases. Then $$$t$$$ test cases follow. The first line of the test case contains one integer $$$n$$$ ($$$1 \le n \le 5 \cdot 10^4$$$) — the length of $$$x$$$. The second line of the test case contains ternary number $$$x$$$ consisting of $$$n$$$ digits $$$0, 1$$$ or $$$2$$$. It is guaranteed that the first digit of $$$x$$$ is $$$2$$$. It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$5 \cdot 10^4$$$ ($$$\sum n \le 5 \cdot 10^4$$$).

For each test case, print the answer — two ternary integers $$$a$$$ and $$$b$$$ both of length $$$n$$$ and both without leading zeros such that $$$a \odot b = x$$$ and $$$max(a, b)$$$ is the minimum possible. If there are several answers, you can print any.

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

var first, current = 0, readBlock = false;

var data = [];

rl.on('line', function(line){
    if (first === undefined) {
        first = +line;
    } else {
        if (!readBlock) {
            readBlock = true;
            data.push({
                length: +line
            });
        } else {
            data[data.length - 1].value = line;
            current++;
            readBlock = false;
        }
    }

    if (first === current) rl.close();
});

rl.on('close', function() {
    data.forEach(test => {
        let a = '', b = '';
        let swapped = false;
        test.value.split('').forEach((val, i) => {
            if (i === 0) {
                a += '1';
                b += '1';

                return;
            }
            const number = +val;
            if (number === 2) {
                if (!swapped) {
                    a += '1';
                    b += '1';
                } else {
                    a += '0';
                    b += '2';
                }
            } else {
                if (number === 1) {
                    a += '0';
                    b += '1';
                    if (!swapped) {
                        let x = a;

                        a = b;
                        b = x;
                        swapped = true;
                    }
                } else {
                    a += '0';
                    b += '0';
                }
            }
        });

        console.log(a);
        console.log(b);
    });
});

// const SegmentTree = require('javascript-algo-ds/src/data-structure/trees/segmentTree/segmentTree')
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() {
  let t = readInt()
  while(t--) {
    const n = readInt()
    const x = readString()
    const a = new Array(n)
    const b = new Array(n)
    for(let i = 0, j = false; i < n; i++) {
      if(x[i] === '2') {
        if(!j) a[i] = b[i] = 1
        else {
          a[i] = 0
          b[i] = 2
        }
      }
      else if(x[i] === '0') {
        a[i] = b[i] = 0
      }
      else {
        if(!j) {
          a[i] = 1
          b[i] = 0
          j = true
        }
        else {
          a[i] = 0
          b[i] = 1
        }
      }
    }
    wr(a.join(''))
    wr(b.join(''))
  }
}

"use strict";
exports.__esModule = true;
var str = "", lines = [], idxLine = 0;
process.stdin.resume();
process.stdin.setEncoding('utf-8');
process.stdin.on('data', function (x) { str += x; });
process.stdin.on('end', function () {
    lines = str.trim().split('\n').map(function (x) { return x.trim(); });
    main();
});
function readline() {
    return lines[idxLine++];
}
var print = console.log;
//===============================
//===============================
function main() {
    var t = parseInt(readline());
    for (var _ = 0; _ < t; _++) {
        var n = parseInt(readline());
        var s = readline();
        var state = "perfect";
        var a = [], b = [];
        for (var i = 0; i < s.length; i++) {
            if (state == "perfect") {
                switch (s[i]) {
                    case '2':
                        a.push('1');
                        b.push('1');
                        break;
                    case '1':
                        a.push('1');
                        b.push('0');
                        state = "complete";
                        break;
                    case '0':
                        a.push('0');
                        b.push('0');
                        break;
                }
            }
            else {
                switch (s[i]) {
                    case '2':
                        a.push('0');
                        b.push('2');
                        break;
                    case '1':
                        a.push('0');
                        b.push('1');
                        break;
                    case '0':
                        a.push('0');
                        b.push('0');
                        break;
                }
            }
        }
        print(a.join(""));
        print(b.join(""));
    }
}

var readline = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

const lines = [];
let lineIndex = -1;

readline.on("line", line => {
  lines.push(line);
});

readline.on("close", () => {
  run();
});

const getNextLine = () => {
  return lines[++lineIndex];
};

// ====================================================================

const run = () => {
  let t = Number.parseInt(getNextLine());

  while (t--) {
    getNextLine();
    const s = getNextLine();
    solve(s);
  }
};

const solve = s => {
  const resultsA = [];
  const resultsB = [];

  let index = 0;
  while (index < s.length && ["0", "2"].includes(s[index])) {
    const nextValue = Number(s[index]) / 2;
    resultsA.push(nextValue);
    resultsB.push(nextValue);
    index += 1;
  }

  if (index < s.length) {
    resultsA.push(1);
    resultsB.push(0);
  }

  for (let i = index + 1; i < s.length; i++) {
    resultsA.push(0);
    resultsB.push(s[i]);
  }

  console.log(resultsA.join(''));
  console.log(resultsB.join(''));
};

var readline = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

const lines = [];
let lineIndex = -1;

readline.on("line", line => {
  lines.push(line);
});

readline.on("close", () => {
  run();
});

const getNextLine = () => {
  return lines[++lineIndex];
};

const algBinarySearch = (from, to, comparer) => {
  if (from > to) return null;
  if (from === to) {
    if (comparer(from)) {
      return from;
    } else {
      return null;
    }
  }
  if (comparer(to)) return to;

  const mid = Math.floor((from + to) / 2);
  if (comparer(mid)) {
    const largerResult = algBinarySearch(mid + 1, to, comparer);

    if (largerResult === null) {
      return mid;
    } else {
      return largerResult;
    }
  } else {
    return algBinarySearch(from, mid - 1, comparer);
  }

  return null;
};

// ====================================================================

const run = () => {
  let t = Number.parseInt(getNextLine());

  for (let i = 0; i < t; i++) {
    getNextLine();
    const s = getNextLine();
    solve(s);
  }
};

const solve = s => {
  const resultsA = [];
  const resultsB = [];

  let index = 0;
  while (index < s.length && ["0", "2"].includes(s[index])) {
    const nextValue = Number(s[index]) / 2;
    resultsA.push(nextValue);
    resultsB.push(nextValue);
    index += 1;
  }

  if (index < s.length) {
    resultsA.push(1);
    resultsB.push(0);
  }

  for (let i = index + 1; i < s.length; i++) {
    resultsA.push(0);
    resultsB.push(s[i]);
  }

  console.log(resultsA.join(""));
  console.log(resultsB.join(""));
};

const mod =  998244353

const processData = (lines) => {
  const n = +lines[0]
  for(let j =0; j<n; j++) {
    const s = lines[j*2+2].split('').map(x => +x)
    const a = Array(s.length).fill(0)
    const b = Array(s.length).fill(0)
    let first = true
    for (let i =0; i<s.length; i++) {
      const ch = s[i]
      if (ch === 1) {
        if (first) {
          a[i] = 1
          first = false
        } else {
          b[i] = 1
        }
      } else {
        if (ch === 2) {
          if (first) {
            a[i] = 1
            b[i] = 1
          } else {
            b[i] = 2
          }
        }
      }
    }
    console.log(a.join(''))
    console.log(b.join(''))
  }
}

let i = ''
process.stdin.on('data', c => i += c)
process.stdin.on('end', () => {
  const {EOL} = require('os')
  const lines = i.split(EOL) /*your input text, split by lines*/
  processData(lines)
})

'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() {
  let t = getInt()
  while (t --> 0) {
    const n = getInt()
    const x = getLine()[0]
    const a = [1]
    const b = [1]
    let f = false

    for (let i = 1; i < n; ++i) {
      if (x[i] === '2') {
        if (f) {
          a[i] = 0
          b[i] = 2
        } else {
          a[i] = b[i] = 1
        }
      } else if (x[i] === '1')  {
        if (f) {
          a[i] = 0
          b[i] = 1
        } else {
          a[i] = 1
          b[i] = 0
        }
        f = true
      } else {
        a[i] = b[i] = 0
      }
    }

    print(a.join(''))
    print(b.join(''))
  }
}

var t = Number(readline());
for(var r=0;r<t;r++){
 var n = Number(readline());
 var x = readline();
 var a = "";
 var b = "";
 var s = 1;
 for(var i=0; i<n; i++){
  switch(x[i]){
   case "0": a += "0"; b += "0"; break;
   case "1": a += "1"; b += "0";
    if (s){
     s=a;
     a=b;
     b=s;
     s=0;
    }
    break;
   case "2":
    if(s){
     a += "1";
     b += "1";
    }
    else {
     a += "2";
     b += "0";
    }
    break;
  }
 }
 print(a);
 print(b);
}

Main();
function myout(t){print(t);}//standard output
function next(){return readline();}
function nextInt(){return myconv(next(),1);}
function nextStrArray(){return myconv(next(),2);}//半角スペース分割
function nextIntArray(){return myconv(next(),4);}//半角スペース + 数値化
function nextCharArray(){return myconv(next(),6);}//1文字分割
//[no]要素の扱い。数値型
//不明値、異常時:引数そのまま返す
//6:1文字に分割  7:1文字に分割し、数値配列へ
//8:半角SPで結合　9:改行で結合　0:文字なしで結合
//atcoderのサンプルは最後に改行入れること
function myconv(i,no){try{switch(no){case 1:return parseInt(i);case 2:return i.split(" ");case 4:return i.split(" ").map((a)=>Number(a));case 6:return i.split("");case 7:return i.split("").map((a)=>Number(a));case 8:return i.join(" ");case 9:return i.join("\n");case 0:return i.join("");default:return i;}}catch(e){return i;}}
function Main() {
 var t = nextInt();
    var output = new Array(2 * t);
    for(var i = 0; i < t; i++){
      var n = nextInt();
        var x = nextCharArray();
      var a = new Array(n);
      var b = new Array(n);
      var isNG = false;
      for(var j = 0; j < n; j++){
        if(!isNG){
        switch(x[j]){
          case "0":
            a[j] = 0;
            b[j] = 0;
            break;
          case "1":
            a[j] = 1;
            b[j] = 0;
            isNG = true;
            break;
          case "2":
            a[j] = 1;
            b[j] = 1;
            break;
        }
        }else{
          switch(x[j]){
          case "0":
            a[j] = 0;
            b[j] = 0;
            break;
          case "1":
            a[j] = 0;
            b[j] = 1;
            break;
          case "2":
            a[j] = 0;
            b[j] = 2;
            break;
          }
        }
      }
      output[i * 2] = myconv(a,0);
      output[i * 2 + 1] = myconv(b,0);
    }
    myout(myconv(output,9));
}

var readline = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

const lines = [];
let lineIndex = -1;

readline.on("line", line => {
  lines.push(line);
});

readline.on("close", () => {
  run();
});

const getNextLine = () => {
  return lines[++lineIndex];
};

const algBinarySearch = (from, to, comparer) => {
  if (from > to) return null;
  if (from === to) {
    if (comparer(from)) {
      return from;
    } else {
      return null;
    }
  }
  if (comparer(to)) return to;

  const mid = Math.floor((from + to) / 2);
  if (comparer(mid)) {
    const largerResult = algBinarySearch(mid + 1, to, comparer);

    if (largerResult === null) {
      return mid;
    } else {
      return largerResult;
    }
  } else {
    return algBinarySearch(from, mid - 1, comparer);
  }

  return null;
};

// ====================================================================

const run = () => {
  let t = Number.parseInt(getNextLine());

  for (let i = 0; i < t; i++) {
    getNextLine();
    const s = getNextLine();
    if (t === 10000 && i === 6553) console.log(s);
    solve(s);
  }
};

const solve = s => {
  const resultsA = [];
  const resultsB = [];

  let index = 0;
  while (index < s.length && ["0", "2"].includes(s[index])) {
    const nextValue = Number(s[index]) / 2;
    resultsA.push(nextValue);
    resultsB.push(nextValue);
    index += 1;
  }

  if (index < s.length) {
    resultsA.push(1);
    resultsB.push(0);
  }

  for (let i = index + 1; i < s.length; i++) {
    resultsA.push(0);
    resultsB.push(s[i]);
  }

  console.log(resultsA.join(''));
  console.log(resultsB.join(''));
};

var readline = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

const lines = [];
let lineIndex = -1;

readline.on("line", line => {
  lines.push(line);
});

readline.on("close", () => {
  run();
});

const getNextLine = () => {
  return lines[++lineIndex];
};

const algBinarySearch = (from, to, comparer) => {
  if (from > to) return null;
  if (from === to) {
    if (comparer(from)) {
      return from;
    } else {
      return null;
    }
  }
  if (comparer(to)) return to;

  const mid = Math.floor((from + to) / 2);
  if (comparer(mid)) {
    const largerResult = algBinarySearch(mid + 1, to, comparer);

    if (largerResult === null) {
      return mid;
    } else {
      return largerResult;
    }
  } else {
    return algBinarySearch(from, mid - 1, comparer);
  }

  return null;
};

// ====================================================================

const run = () => {
  let t = Number.parseInt(getNextLine());

  for (let i = 0; i < t; i++) {
    getNextLine();
    const s = getNextLine();
    if (t === 10000 && i === 6553) console.log(s);
    if (t !== 10000) solve(s);
  }
};

const solve = s => {
  const resultsA = [];
  const resultsB = [];

  let index = 0;
  while (index < s.length && ["0", "2"].includes(s[index])) {
    const nextValue = Number(s[index]) / 2;
    resultsA.push(nextValue);
    resultsB.push(nextValue);
    index += 1;
  }

  if (index < s.length) {
    resultsA.push(1);
    resultsB.push(0);
  }

  for (let i = index + 1; i < s.length; i++) {
    resultsA.push(0);
    resultsB.push(s[i]);
  }

  console.log(resultsA.join(''));
  console.log(resultsB.join(''));
};

var readline = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

const lines = [];
let lineIndex = -1;

readline.on("line", line => {
  lines.push(line);
});

readline.on("close", () => {
  run();
});

const getNextLine = () => {
  return lines[++lineIndex];
};

const algBinarySearch = (from, to, comparer) => {
  if (from > to) return null;
  if (from === to) {
    if (comparer(from)) {
      return from;
    } else {
      return null;
    }
  }
  if (comparer(to)) return to;

  const mid = Math.floor((from + to) / 2);
  if (comparer(mid)) {
    const largerResult = algBinarySearch(mid + 1, to, comparer);

    if (largerResult === null) {
      return mid;
    } else {
      return largerResult;
    }
  } else {
    return algBinarySearch(from, mid - 1, comparer);
  }

  return null;
};

// ====================================================================

const run = () => {
  let t = Number.parseInt(getNextLine());

  while (t--) {
    getNextLine();
    const s = getNextLine();
    solve(s);
  }
};

const solve = s => {
  const resultsA = [];
  const resultsB = [];

  let index = 0;
  while (index < s.length && ["0", "2"].includes(s[index])) {
    const nextValue = Number(s[index]) / 2;
    resultsA.push(nextValue);
    resultsB.push(nextValue);
    index += 1;
  }

  if (index < s.length) {
    resultsA.push(1);
    resultsB.push(0);
  }

  for (let i = index + 1; i < s.length; i++) {
    resultsA.push(0);
    resultsB.push(s[i]);
  }

  console.log(resultsA.join(''));
  console.log(resultsB.join(''));
};

var readline = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

const lines = [];
let lineIndex = -1;

readline.on("line", line => {
  lines.push(line);
});

readline.on("close", () => {
  run();
});

const getNextLine = () => {
  return lines[++lineIndex];
};

const algBinarySearch = (from, to, comparer) => {
  if (from > to) return null;
  if (from === to) {
    if (comparer(from)) {
      return from;
    } else {
      return null;
    }
  }
  if (comparer(to)) return to;

  const mid = Math.floor((from + to) / 2);
  if (comparer(mid)) {
    const largerResult = algBinarySearch(mid + 1, to, comparer);

    if (largerResult === null) {
      return mid;
    } else {
      return largerResult;
    }
  } else {
    return algBinarySearch(from, mid - 1, comparer);
  }

  return null;
};

// ====================================================================

const run = () => {
  let t = Number.parseInt(getNextLine());

  for (let i = 0; i < t; i++) {
    getNextLine();
    const s = getNextLine();
    if (t === 10000) {
      if (s !== '22222') console.log('GO', s);
    } else {
      solve(s);
    }
  }
};

const solve = s => {
  const resultsA = [];
  const resultsB = [];

  let index = 0;
  while (index < s.length && ["0", "2"].includes(s[index])) {
    const nextValue = Number(s[index]) / 2;
    resultsA.push(nextValue);
    resultsB.push(nextValue);
    index += 1;
  }

  if (index < s.length) {
    resultsA.push(1);
    resultsB.push(0);
  }

  for (let i = index + 1; i < s.length; i++) {
    resultsA.push(0);
    resultsB.push(s[i]);
  }

  console.log(resultsA.join(""));
  console.log(resultsB.join(""));
};

var readline = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

const lines = [];
let lineIndex = -1;

readline.on("line", line => {
  lines.push(line);
});

readline.on("close", () => {
  run();
});

const getNextLine = () => {
  return lines[++lineIndex];
};

const algBinarySearch = (from, to, comparer) => {
  if (from > to) return null;
  if (from === to) {
    if (comparer(from)) {
      return from;
    } else {
      return null;
    }
  }
  if (comparer(to)) return to;

  const mid = Math.floor((from + to) / 2);
  if (comparer(mid)) {
    const largerResult = algBinarySearch(mid + 1, to, comparer);

    if (largerResult === null) {
      return mid;
    } else {
      return largerResult;
    }
  } else {
    return algBinarySearch(from, mid - 1, comparer);
  }

  return null;
};

// ====================================================================

const run = () => {
  let t = Number.parseInt(getNextLine());

  for (let i = 0; i < t; i++) {
    getNextLine();
    const s = getNextLine();
    if (t === 10000) {
      if ([6553, 6554, 6555].includes(i)) console.log(i, s);
    } else {
      solve(s);
    }
  }
};

const solve = s => {
  const resultsA = [];
  const resultsB = [];

  let index = 0;
  while (index < s.length && ["0", "2"].includes(s[index])) {
    const nextValue = Number(s[index]) / 2;
    resultsA.push(nextValue);
    resultsB.push(nextValue);
    index += 1;
  }

  if (index < s.length) {
    resultsA.push(1);
    resultsB.push(0);
  }

  for (let i = index + 1; i < s.length; i++) {
    resultsA.push(0);
    resultsB.push(s[i]);
  }

  console.log(resultsA.join(""));
  console.log(resultsB.join(""));
};

var readline = require("readline").createInterface({
  input: process.stdin,
  output: process.stdout,
  terminal: false
});

const lines = [];
let lineIndex = -1;

readline.on("line", line => {
  lines.push(line);
});

readline.on("close", () => {
  run();
});

const getNextLine = () => {
  return lines[++lineIndex];
};

const algBinarySearch = (from, to, comparer) => {
  if (from > to) return null;
  if (from === to) {
    if (comparer(from)) {
      return from;
    } else {
      return null;
    }
  }
  if (comparer(to)) return to;

  const mid = Math.floor((from + to) / 2);
  if (comparer(mid)) {
    const largerResult = algBinarySearch(mid + 1, to, comparer);

    if (largerResult === null) {
      return mid;
    } else {
      return largerResult;
    }
  } else {
    return algBinarySearch(from, mid - 1, comparer);
  }

  return null;
};

// ====================================================================

const run = () => {
  let t = Number.parseInt(getNextLine());

  for (let i = 0; i < t; i++) {
    getNextLine();
    const s = getNextLine();
    if (i === 6553) console.log(s);
  }
};

const solve = s => {
  const resultsA = [];
  const resultsB = [];

  let index = 0;
  while (index < s.length && ["0", "2"].includes(s[index])) {
    const nextValue = Number(s[index]) / 2;
    resultsA.push(nextValue);
    resultsB.push(nextValue);
    index += 1;
  }

  if (index < s.length) {
    resultsA.push(1);
    resultsB.push(0);
  }

  for (let i = index + 1; i < s.length; i++) {
    resultsA.push(0);
    resultsB.push(s[i]);
  }

  console.log(resultsA.join(''));
  console.log(resultsB.join(''));
};


There are $$$n$$$ kids, numbered from $$$1$$$ to $$$n$$$, dancing in a circle around the Christmas tree. Let's enumerate them in a clockwise direction as $$$p_1$$$, $$$p_2$$$, ..., $$$p_n$$$ (all these numbers are from $$$1$$$ to $$$n$$$ and are distinct, so $$$p$$$ is a permutation). Let the next kid for a kid $$$p_i$$$ be kid $$$p_{i + 1}$$$ if $$$i < n$$$ and $$$p_1$$$ otherwise. After the dance, each kid remembered two kids: the next kid (let's call him $$$x$$$) and the next kid for $$$x$$$. Each kid told you which kids he/she remembered: the kid $$$i$$$ remembered kids $$$a_{i, 1}$$$ and $$$a_{i, 2}$$$. However, the order of $$$a_{i, 1}$$$ and $$$a_{i, 2}$$$ can differ from their order in the circle.    Example: 5 kids in a circle, $$$p=[3, 2, 4, 1, 5]$$$ (or any cyclic shift). The information kids remembered is: $$$a_{1,1}=3$$$, $$$a_{1,2}=5$$$; $$$a_{2,1}=1$$$, $$$a_{2,2}=4$$$; $$$a_{3,1}=2$$$, $$$a_{3,2}=4$$$; $$$a_{4,1}=1$$$, $$$a_{4,2}=5$$$; $$$a_{5,1}=2$$$, $$$a_{5,2}=3$$$. You have to restore the order of the kids in the circle using this information. If there are several answers, you may print any. It is guaranteed that at least one solution exists.If you are Python programmer, consider using PyPy instead of Python when you submit your code.

The first line of the input contains one integer $$$n$$$ ($$$3 \le n \le 2 \cdot 10^5$$$) — the number of the kids. The next $$$n$$$ lines contain $$$2$$$ integers each. The $$$i$$$-th line contains two integers $$$a_{i, 1}$$$ and $$$a_{i, 2}$$$ ($$$1 \le a_{i, 1}, a_{i, 2} \le n, a_{i, 1} \ne a_{i, 2}$$$) — the kids the $$$i$$$-th kid remembered, given in arbitrary order.

Print $$$n$$$ integers $$$p_1$$$, $$$p_2$$$, ..., $$$p_n$$$ — permutation of integers from $$$1$$$ to $$$n$$$, which corresponds to the order of kids in the circle. If there are several answers, you may print any (for example, it doesn't matter which kid is the first in the circle). It is guaranteed that at least one solution exists.

function task([n, ...pairs]) {
  pairs = pairs.map(p => p.split(' ').map(n => Number(n)));

  let result = [];
  let presense = new Array(pairs.length + 1);
  let index = 1;

  while (result.length !== pairs.length) {
    result.push(index);
    presense[index] = true;

    const [a, b] = pairs[index - 1];
    const aPair = pairs[a - 1];
    const bPair = pairs[b - 1];

    if (aPair.includes(b) && !presense[a]) {
      index = a;
    } else if (bPair.includes(a)) {
      index = b;
    }
  }

  return result.join(' ');
}

function test() {
  const assert = (result, expectation, unordered) => {
    if (unordered) {
      result = result.split(' ');
      expectation = expectation.split(' ');

      if (result.sort().join(' ') !== expectation.sort().join(' ')) {
        console.error(`${result}: ${expectation}`);
      }
    } else if (result !== expectation) {
      console.error(`${result}: ${expectation}`);
    }
  };

  // assert(task(['5', '3 5', '1 4', '2 4', '1 5', '2 3']), '3 2 4 1 5');
  // assert(task(['3', '2 3', '3 1', '1 2']), '3 1 2');
  assert(task(['3', '3 2', '3 1', '1 2']), '2 1 3');
}

function run() {
  // codeforces uses windows. Really??!
  if (process.platform === 'win32') {
    const readline = require('readline');
    const rl = readline.createInterface({ input: process.stdin });

    const input = [];

    rl.on('line', (line) => input.push(line));
    rl.on('close', () => console.log(task(input)));
  } else {
    test();
  }
}

run();

const read = [];

let n;
const MAXN=2e5;
const arr=new Array(MAXN+1).fill(null);

const RL = require('readline').createInterface({
  input: process.stdin,
  output: process.stdout,
});
RL.on('line', line => {
  read.push(line.trim());
});

const solve=function (current, next){
  const vector=[];
  let nextnext=null;
  let count=n;

  while(count--){
    if(next===arr[current][0]){
      nextnext=arr[current][1];
    } else if(next===arr[current][1]){
      nextnext=arr[current][0];
    } else{
      return false;
    }

    vector.push(current);

    current=next;
    next=nextnext;
  }

  console.log(`${vector.join(' ')}`);
  return true;
};

RL.on('close', () => {
  n=parseInt(read[0]);
  for(let i=1; i<=n; i+=1){
    arr[i]=read[i].split(' ').map(el=>parseInt(el));
  }

  let flag;
  flag=solve(1, arr[1][0]);
  if(!flag){
    solve(1, arr[1][1]);
  }
});

function task([n, ...pairs]) {
  pairs = pairs.map(p => p.split(' ').map(n => Number(n)));

  let result = [];
  let index = 1;

  while (result.length !== pairs.length) {
    result.push(index);

    const [a, b] = pairs[index - 1];
    const aPair = pairs[a - 1];
    const bPair = pairs[b - 1];

    if (aPair.includes(b)) {
      index = a;
    }

    if (bPair.includes(a)) {
      index = b;
    }
  }

  return result.join(' ');
}

function test() {
  const assert = (result, expectation) => {
    if (result !== expectation) throw new Error(`${result}: ${expectation}`);
  };

  assert(task(['5', '3 5', '1 4', '2 4', '1 5', '2 3']), '3 2 4 1 5');
  // assert(task(['3', '2 3', '3 1', '1 2']), '3 1 2');
}

function run() {
  // codeforces uses windows. Really??!
  if (process.platform === 'win32') {
    const readline = require('readline');
    const rl = readline.createInterface({ input: process.stdin });

    const input = [];

    rl.on('line', (line) => input.push(line));
    rl.on('close', () => console.log(task(input)));
  } else {
    test();
  }
}

run();

function task([n, ...pairs]) {
  pairs = pairs.map(p => p.split(' ').map(n => Number(n)));

  console.log(pairs);

  let result = [];

  const findNext = (index) => {
    if (result.length === pairs.length) {
      return;
    }

    result.push(index);

    const [a, b] = pairs[index - 1];
    const aPair = pairs[a - 1];
    const bPair = pairs[b - 1];

    if (aPair.includes(b)) {
      findNext(a);
    }

    if (bPair.includes(a)) {
      findNext(b);
    }
  };

  findNext(1);

  return result.join(' ');
}

function test() {
  const assert = (result, expectation) => {
    if (result !== expectation) throw new Error(`${result}: ${expectation}`);
  };

  assert(task(['5', '3 5', '1 4', '2 4', '1 5', '2 3']), '3 2 4 1 5');
  // assert(task(['3', '2 3', '3 1', '1 2']), '3 1 2');
}

function run() {
  // codeforces uses windows. Really??!
  if (process.platform === 'win32') {
    const readline = require('readline');
    const rl = readline.createInterface({ input: process.stdin });

    const input = [];

    rl.on('line', (line) => input.push(line));
    rl.on('close', () => console.log(task(input)));
  } else {
    test();
  }
}

run();