A company has n employees numbered from 1 to n. Each employee either has no immediate manager or exactly one immediate manager, who is another employee with a different number. An employee A is said to be the superior of another employee B if at least one of the following is true:  Employee A is the immediate manager of employee B  Employee B has an immediate manager employee C such that employee A is the superior of employee C. The company will not have a managerial cycle. That is, there will not exist an employee who is the superior of his/her own immediate manager.Today the company is going to arrange a party. This involves dividing all n employees into several groups: every employee must belong to exactly one group. Furthermore, within any single group, there must not be two employees A and B such that A is the superior of B.What is the minimum number of groups that must be formed?

The first line contains integer n (1 ≤ n ≤ 2000) — the number of employees. The next n lines contain the integers pi (1 ≤ pi ≤ n or pi = -1). Every pi denotes the immediate manager for the i-th employee. If pi is -1, that means that the i-th employee does not have an immediate manager.  It is guaranteed, that no employee will be the immediate manager of him/herself (pi ≠ i). Also, there will be no managerial cycles.

Print a single integer denoting the minimum number of groups that will be formed in the party.

NoteFor the first example, three groups are sufficient, for example:   Employee 1  Employees 2 and 4  Employees 3 and 5

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

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

  arr.push(+d);

  c++;
});

rl.on('close', () => {
  let ans = 1;
  const nodes = new Array(arr.length).fill(0);

  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === -1) {
      nodes[i] = 1;
    }
    else {
      for (let j = 0; j < arr.length; j++) {
        if (j !== i) {
          if (i + 1 === arr[j]) {
            nodes[i] = 1;
          }
        }
      }
    }
  }

  for (let i = 0; i < arr.length; i++) {
    if (nodes[i] === 0) {
      let curr = 1;
      let idx = arr[i];

      while (idx !== -1) {
        idx = arr[idx - 1];
        curr++;
      }

      ans = Math.max(ans, curr);
    }
  }

  console.log(ans);
});

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

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

  arr.push(+d);

  c++;
});

rl.on('close', () => {
  let ans = 1;

  for (let i = 0; i < arr.length; i++) {
    let v = arr[i];
    let curr = 1;

    while (v !== -1) {
      curr++;
      v = arr[v - 1];
    }

    ans = Math.max(ans, curr);
  }

  console.log(ans);

  // let ans = 1;
  // const nodes = new Array(arr.length).fill(0);

  // for (let i = 0; i < arr.length; i++) {
  //   if (arr[i] === -1) {
  //     nodes[i] = 1;
  //   }
  //   else {
  //     for (let j = 0; j < arr.length; j++) {
  //       if (j !== i) {
  //         if (i + 1 === arr[j]) {
  //           nodes[i] = 1;
  //         }
  //       }
  //     }
  //   }
  // }

  // for (let i = 0; i < arr.length; i++) {
  //   if (nodes[i] === 0) {
  //     let curr = 1;
  //     let idx = arr[i];

  //     while (idx !== -1) {
  //       idx = arr[idx - 1];
  //       curr++;
  //     }

  //     ans = Math.max(ans, curr);
  //   }
  // }

  // console.log(ans);
});

function rda(){ return readline().split(" ").map(Number); }
function rdn(){ return +readline(); }

function dfs(mng, depth) {
    if(graph[mng].length > 0) depth++;
    maxDepth = Math.max(maxDepth, depth);
    for(var i = 0; i < graph[mng].length; i++){
        dfs(graph[mng][i], depth);
    }
}

var n = rdn();
var graph = {};

for(var i = 0; i < n; i++){
    var p = rdn();
    p = (p == -1) ? p : (p-1);
    if(!graph[p]) graph[p] = [];
    graph[p].push(i);
    if(!graph[i]) graph[i] = [];
}

var maxDepth = 0;
dfs(-1, 0);

write(maxDepth);

var n = +readline();
var arr = new Array(n);
for (var i = 0; i < n; i++) {
    arr[i] = +readline() - 1
}
for (var i = 0; i < n; i++) {
    var curr_max = 0;
    var j = i;
    while (j != -2) {
        if (j < i) {
            curr_max += arr[j];
            break
        }
        curr_max += 1;
        j = arr[j]
    }
    arr[i] = curr_max;
}
print(Math.max(...arr, 1));

var n = +readline();
var arr = new Array(n);
for (var i = 0; i < n; i++) {
    arr[i] = +readline() - 1
}
var max = 1;
for (var i = 0; i < n; i++) {
    var curr_max = 0;
    var j = i;
    while (j != -2) {
        curr_max += 1;
        j = arr[j]
    }
    max = Math.max(max, curr_max)
}
print(max);

var n = +readline();
var arr = new Array(n);
for (var i = 0; i < n; i++) {
    arr[i] = +readline() - 1
}
var max = 1;
for (var i = 0; i < n; i++) {
    var curr_max = 0;
    var j = i;
    while (j != -2) {
        if (j < i) {
            curr_max += arr[j];
            break
        }
        curr_max += 1;
        j = arr[j]
    }
    arr[i] = curr_max;
    max = Math.max(max, curr_max)
}
print(max);

;(function () {

    print(function (n) {
        var m = [], t = 0;
        while (n--) {
            var k = Number(readline());
            if (k !== -1) k -= 1;
            m.push(k);
        }

        for (var i = 0, n = m.length; i < n; i++) {
            var r = 1, j = m[i];
            while (j !== -1) {
                j = m[j];
                r++;
            }

            if (t < r) {
                t = r;
            }
        }

        return t;
    }(+readline()));

}.call(this));

function solve(managers) {
    var companyMap = managers.reduce(function (companyMap, manager, employee) {
        return manager === -1 ? companyMap : (companyMap[manager] = (companyMap[manager] || []).concat(employee), companyMap)
    }, {})

    var levels = Object.keys(companyMap)
        .filter(isTopLevelManager(managers))
        .map(function(manager) {
            return countNumberOfLevels(companyMap, companyMap[manager], 2)
        })

    return levels.length ? Math.max.apply(Math, levels) : 1
}

function isTopLevelManager(managers) {
    return function (employee) {
        return managers[employee] === -1
    }
}

function countNumberOfLevels(companyMap, subordinates, count) {
    var levels = subordinates
        .map(function(employee) {
            var nextSubordinates = companyMap[employee]
            return nextSubordinates ? countNumberOfLevels(companyMap, nextSubordinates, count + 1) : count
        })

    return Math.max.apply(Math, levels)
}

var numOfEmployees = readline();
var managers = [-1]
while (numOfEmployees) {
    managers.push(Number(readline()))
    numOfEmployees--
}

print(solve(managers))

function solve(nums) {
    var res = nums.reduce(function (acc, curr, index) {
        if(curr !== -1) acc[curr] = (acc[curr] || []).concat(index)
        return acc
    }, {})

    //console.log(res)

    var counts = Object.keys(res)
        .filter(function(key) {
            return nums[key] === -1
        })
        .map(function(key) {
            return count(res, res[key], 2)
        })
    //console.log(counts)
    return counts.length ? Math.max.apply(Math, counts) : 1
}

function count(main, arr, c) {
    var res = arr
        .map(function(x) {
            if(!main[x]) return c
            var k = count(main, main[x], c + 1)
            //console.log('k', k)
            return k
        })

    //if (!res.length) return c
    //console.log('res', res)
    return Math.max.apply(Math, res)
}

var numOfEmployees = readline();
var nums = [-1]
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

function solve(input) {
    var companyMap = input.reduce(function (companyMap, manager, employee) {
        return manager === -1 ? companyMap : (companyMap[manager] = (companyMap[manager] || []).concat(employee), companyMap)
    }, {})

    var levels = Object.keys(companyMap)
        .filter(isTopLevelManager(input))
        .map(function(manager) {
            return countNumberOfLevels(companyMap, companyMap[manager], 2)
        })

    return levels.length ? Math.max.apply(Math, levels) : 1
}

function isTopLevelManager(input) {
    return function (employee) {
        return input[employee] === -1
    }
}

function countNumberOfLevels(companyMap, subordinates, count) {
    var levels = subordinates
        .map(function(employee) {
            var nextSubordinates = companyMap[employee]
            return nextSubordinates ? countNumberOfLevels(companyMap, nextSubordinates, count + 1) : count
        })

    return Math.max.apply(Math, levels)
}

var numOfEmployees = readline();
var managers = [-1]
while (numOfEmployees) {
    managers.push(Number(readline()))
    numOfEmployees--
}

print(solve(managers))

function solve(input) {
    var companyMap = input.reduce(function (acc, curr, index) {
        return (curr === -1) ? acc : (acc[curr] = (acc[curr] || []).concat(index), acc)
    }, {})

    var levels = Object.keys(companyMap)
        .filter(isTopLevelManager(input))
        .map(function(manager) {
            return countNumberOfLevels(companyMap, companyMap[manager], 2)
        })

    return levels.length ? Math.max.apply(Math, levels) : 1
}

function isTopLevelManager(input) {
    return function (employee) {
        return input[employee] === -1
    }
}

function countNumberOfLevels(companyMap, subordinates, count) {
    var levels = subordinates
        .map(function(employee) {
            var nextSubordinates = companyMap[employee]
            return nextSubordinates ? countNumberOfLevels(companyMap, nextSubordinates, count + 1) : count
        })

    return Math.max.apply(Math, levels)
}

var numOfEmployees = readline();
var nums = [-1]
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

function solve(input) {
    var companyMap = input.reduce(function (acc, curr, index) {
        if(curr !== -1) acc[curr] = (acc[curr] || []).concat(index)
        return acc
    }, {})

    var numbersOfLevels = Object.keys(companyMap)
        .filter(function(key) {
            return input[key] === -1
        })
        .map(function(key) {
            return count(companyMap, companyMap[key], 2)
        })
    return numbersOfLevels.length ? Math.max.apply(Math, numbersOfLevels) : 1
}

// function isTopLevelManager(input) {
//     return function () {
//
//     }
// }

function count(main, arr, c) {
    var res = arr
        .map(function(x) {
            if(!main[x]) return c
            var k = count(main, main[x], c + 1)
            return k
        })

    return Math.max.apply(Math, res)
}

var numOfEmployees = readline();
var nums = [-1]
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

function solve(input) {
    var companyMap = input.reduce(function (companyMap, manager, employee) {
        return manager === -1 ? companyMap : (companyMap[manager] = (companyMap[manager] || []).concat(employee), companyMap)
    }, {})

    var levels = Object.keys(companyMap)
        .filter(isTopLevelManager(input))
        .map(function(manager) {
            return countNumberOfLevels(companyMap, companyMap[manager], 2)
        })

    return levels.length ? Math.max.apply(Math, levels) : 1
}

function isTopLevelManager(input) {
    return function (employee) {
        return input[employee] === -1
    }
}

function countNumberOfLevels(companyMap, subordinates, count) {
    var levels = subordinates
        .map(function(employee) {
            var nextSubordinates = companyMap[employee]
            return nextSubordinates ? countNumberOfLevels(companyMap, nextSubordinates, count + 1) : count
        })

    return Math.max.apply(Math, levels)
}

var numOfEmployees = readline();
var nums = [-1]
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

function solve(input) {
    var companyMap = input.reduce(function (companyMap, manager, employee) {
        return (manager === -1) ? companyMap : (companyMap[manager] = (companyMap[manager] || []).concat(employee), companyMap)
    }, {})

    var levels = Object.keys(companyMap)
        .filter(isTopLevelManager(input))
        .map(function(manager) {
            return countNumberOfLevels(companyMap, companyMap[manager], 2)
        })

    return levels.length ? Math.max.apply(Math, levels) : 1
}

function isTopLevelManager(input) {
    return function (employee) {
        return input[employee] === -1
    }
}

function countNumberOfLevels(companyMap, subordinates, count) {
    var levels = subordinates
        .map(function(employee) {
            var nextSubordinates = companyMap[employee]
            return nextSubordinates ? countNumberOfLevels(companyMap, nextSubordinates, count + 1) : count
        })

    return Math.max.apply(Math, levels)
}

var numOfEmployees = readline();
var nums = [-1]
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

function solve(input) {
    var companyMap = input.reduce(function (acc, curr, index) {
        if(curr !== -1) acc[curr] = (acc[curr] || []).concat(index)
        return acc
    }, {})

    var levels = Object.keys(companyMap)
        .filter(isTopLevelManager(input))
        .map(function(manager) {
            return countNumberOfLevels(companyMap, companyMap[manager], 2)
        })

    return levels.length ? Math.max.apply(Math, levels) : 1
}

function isTopLevelManager(input) {
    return function (employee) {
        return input[employee] === -1
    }
}

function countNumberOfLevels(companyMap, subordinates, count) {
    var levels = subordinates
        .map(function(employee) {
            var nextSubordinates = companyMap[employee]
            return nextSubordinates ? countNumberOfLevels(companyMap, nextSubordinates, count + 1) : count
        })

    return Math.max.apply(Math, levels)
}

var numOfEmployees = readline();
var nums = [-1]
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

var n = Number(readline()), maxDepth = 0;
var graph = {};
for (var i = 1; i <= n; i++) {
	var temp = Number(readline());
	if (!graph[i]) graph[i] = [];
	if (!graph[temp]) graph[temp] = [];
	graph[temp].push(i);
}
function dfsDepth(startVertex, depth) {
	if (graph[startVertex].length > 0) {
	    depth++;
	    if (depth > maxDepth) maxDepth = depth;
	    for (var i = 0; i < graph[startVertex].length; i++) {
	    	dfsDepth(graph[startVertex][i], depth);
	    }
	}
}
dfsDepth(-1, 0);
print(maxDepth);

var input = readline().split(' ').map(Number), n = input[0];
var graph = [];
var MAXARR = 2001;
for (var i = 0; i < n; i++) {
    var par = parseInt(readline());
    if (par === -1) par = MAXARR;
    else par--;
    (graph[par] = graph[par] || []).push(i);
}

var res = new Set();
var stack = [];
var maxDepth = -Infinity;
while (graph[MAXARR].length) {
    stack.push([graph[MAXARR].splice(0,1)[0], 0]);
    while (stack.length) {
        var el = stack.splice(0,1)[0];
        var val = el[0];
        var depth = el[1];
        maxDepth = Math.max(maxDepth, el[1]);
        if (graph[val] !== undefined)
            for (var i = 0; i < graph[val].length; i++) {
                stack.push([graph[val][i], depth + 1]);
            }
    }
}
write(maxDepth+1);

var graph = { '-1' : [] }, maxDepth = [ 0 ];

function main()    {
    var count = parseInt(readline());

    for(var index = 1; index <= count; index++)    {
        var parentIndex = readline();

        if(!graph[parentIndex])    graph[parentIndex] = [];
        graph[parentIndex].push(index);
        if(!graph[index])    graph[index] = [];
    }

    dfs(-1, 0);

    print(maxDepth[maxDepth.length - 1]);
};

function dfs(start, depth)    {
    if(!graph[start].length)    {
        if(Math.max(maxDepth[maxDepth.length - 1], depth) == depth)    {
            maxDepth.push(depth);
        }
        return depth;
    }

    for(var index = 0; index < graph[start].length; index++)    {
        dfs(graph[start][index], depth + 1);
    }
};

main();

//var input = "2\n2\n-1";
//var index = 0;
//
//function readline(){
//    var data = input.split('\n');
//    if(index < data.length)
//        return data[index++];
//}
//
//function print(output){
//    console.log(output);
//}

var a = [];
var ans = 0;

function Graph(n){
    this.adj = new Array(n);
    for(var i = 0; i < n; i++)
        this.adj[i] = [];
};

function Edge(vertexTo, weightEdge){
    this.vertexTo = vertexTo;
    this.weightEdge = weightEdge;
};

Graph.prototype.addEdge = function(vertexFrom, vertexTo, weightEdge){
    var edge = new Edge(vertexTo, weightEdge);
    this.adj[vertexFrom].push(edge);
}

var Constants  = {
    WHITE_NODE : 0,
    GRAY_NODE : 1,
    BLACK_NODE : 2,
    NULL_PARENT : -1
}

function DepthFirstSearch(graph){
    this.adj = graph.adj;
    this.used = new Array(graph.adj.length);
    this.parent = new Array(graph.adj.length);
    for(var i = 0; i < this.adj.length; i++){
        this.used[i] = Constants.WHITE_NODE;
        this.parent[i] = Constants.NULL_PARENT;
    }
    this.path = [];
};

DepthFirstSearch.prototype.dfs = function(vertex, depth){
    ans = Math.max(ans, depth);
    depth++;
    this.used[vertex] = Constants.GRAY_NODE;
    for(var i = 0; i < this.adj[vertex].length; i++){
        var edge = this.adj[vertex][i];
        var next = edge.vertexTo;
        if(this.used[next] == Constants.WHITE_NODE){
            this.parent[next] = vertex;
            arguments.callee.apply(this, [next, depth]);
        }
    }
    this.used[vertex] = Constants.BLACK_NODE;
}

DepthFirstSearch.prototype.searchPath = function(vertexFrom, vertexTo){
    if(vertexFrom == vertexTo){
        this.path.push(vertexFrom);
    }else{
        if (this.parent[vertexTo] != Constants.NULL_PARENT) {
            arguments.callee.apply(this, [vertexFrom, this.parent[vertexTo]]);
            this.path.push(vertexTo);
        }
    }
}

DepthFirstSearch.prototype.getPath = function(vertexFrom, vertexTo){
    this.searchPath(vertexFrom, vertexTo);
    return this.path;
}

function main() {
    var n  = readline();
    var graph = new Graph(n);
    for(var i = 0; i < n; i++){
        var val = readline();
        if(val == -1) {
            a.push(i);
            continue;
        }
        graph.addEdge(val - 1, i);
    }
    for(var i = 0; i < a.length; i++){
        var alg = new DepthFirstSearch(graph);
        alg.dfs(a[i], 1);
    }
    print(ans);
    return 0;
}

main();

var print = this.print || require('lol-io').print
var write = this.write || require('lol-io').write
var readline = this.readline || require('lol-io').readline

var n=parseInt(readline());
var adj={};
var p=[];
var dep=new Array(n).fill(1);
for(var i=0;i<n;i++){
    var t=parseInt(readline());
    if(t!=-1){
       t--;
       if(!adj[t]){
           adj[t]=[];
       }
       adj[t].push(i);
       p.push(t)
    }else{
      p.push(-1);
    }
};
for(var i=0;i<n;i++){
    if(p[i]==-1){
        dfs(i);
    }
};
var max=0;
for(var i in dep){
   max=Math.max(max,dep[i]);
}
print(max);

function dfs(u){
    for(var i in adj[u]){
        var v=adj[u][i];
        dep[v]=dep[u]+1;
        dfs(v);
    }
};

var print = this.print || require('lol-io').print
var write = this.write || require('lol-io').write
var readline = this.readline || require('lol-io').readline

var n=parseInt(readline());
var adj={};
for(var i=1;i<=n;i++){
    var t=parseInt(readline());
    if(t!=-1){
       if(!adj[t]){
           adj[t]=[];
       }
       if(!adj[i]){
        adj[i]=[];
       }
       adj[t].push(i);
       adj[i].push(t);
    }else{
        if(!adj[t]){
            adj[t]=[];
        };
        if(!adj[i]){
            adj[i]=[];
        };
      adj[t].push(i);
      adj[i].push(t);
    }
};
var q=[[-1,0]];
var vis={};
vis[-1]=true;
var max=-1;
while(q.length){
    var size=q.length;
    count=0;
    for(var i=0;i<size;i++){
        var v=q.shift();
        var curr=v[0];
        var pos=v[1];
        for(var j in adj[curr]){
            var elm=adj[curr][j];
            if(!vis[elm]){
                vis[elm]=true;
                q.push([elm,pos+1]);
            }
        }
        max=Math.max(max,pos);
    }

}

print(max)

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

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

  arr.push(+d);

  c++;
});

rl.on('close', () => {
  let ans = 0;

  let curr = 1;
  for (let i = 1; i < arr.length; i++) {
    if (arr[i - 1] < arr[i] && arr[i] !== -1) {
      curr++;
    }
    else {
      curr = 1;
    }

    ans = Math.max(ans, curr);
  }

  console.log(ans);
});

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

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

  arr.push(+d);

  c++;
});

rl.on('close', () => {
  let ans = 0;
  const obj = {};

  for (let i = 0; i < arr.length; i++) {
    if (!obj[arr[i]]) {
      ans++;
      obj[arr[i]] = true;
    }
  }

  console.log(ans);
});

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

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

  arr.push(+d);

  c++;
});

rl.on('close', () => {
  let ans = 0;

  let curr = 1;
  for (let i = 1; i < arr.length; i++) {
    if (arr[i - 1] < arr[i]) {
      curr++;
    }
    else {
      curr = 1;
    }

    ans = Math.max(ans, curr);
  }

  console.log(ans);
});

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++;
    console.log(Math.ceil(+d / 2));
    return;
  }

  c++;
});

;(function () {

    print(function (n) {
        var m = {};
        while (n--) {
            var e = readline();
            m[e] = m[e] ? m[e] + 1 : 1;
        }

        return Object.keys(m).length;
    }(+readline()));

}.call(this));

function solve(nums) {
    var max = 1
    var start = [-1]
    start.concat(nums).reduce(function(acc, curr, index) {
        if(curr === -1) {
            acc[index] = 1
        } else {
            acc[index] = acc[curr] + 1
        }
        max = Math.max(acc[index], max)
        return acc
    }, [])
    return max
}

var numOfEmployees = readline();
var nums = []
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

function solve(nums) {
    var res = nums.reduce(function (acc, curr, index) {
        if(curr !== -1) acc[curr] = (acc[curr] || []).concat(index)
        return acc
    }, {})

    //console.log(res)

    var counts = Object.keys(res)
        .filter(function(key) {
            return nums[key] === -1
        })
        .map(function(key) {
            return count(res, res[key], 2)
        })
    //console.log(counts)
    return counts[0]
}

function count(main, arr, c) {
    var res = arr
        .map(function(x) {
            if(!main[x]) return c
            var k = count(main, main[x], c + 1)
            //console.log('k', k)
            return k
        })

    //if (!res.length) return c
    //console.log('res', res)
    return Math.max.apply(Math, res)
}

var numOfEmployees = readline();
var nums = [-1]
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

function solve(nums) {
    var max = 1
    var start = [-1]
    start.concat(nums).reduce(function(acc, curr, index) {
        if(curr === -1) {
            acc[index] = 1
        } else {
            acc[index] = acc[curr] + 1
        }
        max = Math.max(acc[index], max)
        return acc
    }, [])
    return max
}

var numOfEmployees = readline();
var nums = []
while (numOfEmployees) {
    var next = readline()
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

function solve(nums) {
    var res = nums.reduce(function (acc, curr, index) {
        if(curr !== -1) acc[curr] = (acc[curr] || []).concat(index)
        return acc
    }, {})

    //console.log(res)

    var counts = Object.keys(res)
        .filter(function(key) {
            return nums[key] === -1
        })
        .map(function(key) {
            return count(res, res[key], 2)
        })
    //console.log(counts)
    return Math.max.apply(Math, counts)
}

function count(main, arr, c) {
    var res = arr
        .map(function(x) {
            if(!main[x]) return c
            var k = count(main, main[x], c + 1)
            //console.log('k', k)
            return k
        })

    //if (!res.length) return c
    //console.log('res', res)
    return Math.max.apply(Math, res)
}

var numOfEmployees = readline();
var nums = [-1]
while (numOfEmployees) {
    var next = Number(readline())
    nums.push(next)
    numOfEmployees--
}

print(solve(nums))

var n = Number(readline()), array = [], uniqueNumbers = [], result;
for (var i = 0; i < n; i++) {
	var controlledBy = Number(readline()), controls = 0;
	array.push({controlledBy, controls});
}
for (var i = 0; i < n; i++) {
	if (array[i].controlledBy != -1) array[array[i].controlledBy - 1].controls++;
}
for (var i = 0; i < n; i++) {
	if (!uniqueNumbers.includes(array[i].controls)) uniqueNumbers.push(array[i].controls);
}
result = uniqueNumbers.reduce((a, b) => a + b);
print(result);

var input = readline().split(' ').map(Number), n = input[0];
var graph = [];
var MAXARR = 2001;
for (var i = 0; i < n; i++) {
    var par = parseInt(readline());
    if (par === -1) par = MAXARR;
    else par--;
    (graph[par] = graph[par] || []).push(i);
}

var res = new Set();
var stack = [];
var maxDepth = -Infinity;
while (graph[MAXARR].length) {
    stack.push([graph[MAXARR].splice(0,1)[0], 0]);
    while (stack.length) {
        var el = stack.splice(0,1)[0];
        var val = el[0];
        var depth = el[1];
        maxDepth = Math.max(maxDepth, el[1]);
        if (graph[val] !== undefined)
            for (var i = 0; i < graph[val].length; i++) {
                stack.push([graph[val][i], depth + 1]);
            }
    }
}
write(maxDepth);

var graph = { '-1' : [] }, maxDepth = [ 0 ];

function main()    {
    var count = parseInt(readline());

    for(var index = 1; index <= count; index++)    {
        var parentIndex = readline();

        graph[parentIndex].push(index);
        graph[index] = [];
    }

    dfs(-1, 0);

    print(maxDepth[maxDepth.length - 1]);
};

function dfs(start, depth)    {
    if(!graph[start].length)    {
        if(Math.max(maxDepth[maxDepth.length - 1], depth) == depth)    {
            maxDepth.push(depth);
        }
        return depth;
    }

    for(var index = 0; index < graph[start].length; index++)    {
        dfs(graph[start][index], depth + 1);
    }
};

var graph = { '-1' : [] }, maxDepth = [ 0 ];

function main()    {
    var count = parseInt(readline());

    for(var index = 1; index <= count; index++)    {
        var parentIndex = readline();

        if(!graph[parentIndex])    graph[parentIndex] = [];
        graph[parentIndex].push(index);
        graph[index] = [];
    }

    dfs(-1, 0);

    print(maxDepth[maxDepth.length - 1]);
};

function dfs(start, depth)    {
    if(!graph[start].length)    {
        if(Math.max(maxDepth[maxDepth.length - 1], depth) == depth)    {
            maxDepth.push(depth);
        }
        return depth;
    }

    for(var index = 0; index < graph[start].length; index++)    {
        dfs(graph[start][index], depth + 1);
    }
};

main();

//var input = "5\n-1\n1\n2\n1\n-1";
//var index = 0;
//
//function readline(){
//    var data = input.split('\n');
//    if(index < data.length)
//        return data[index++];
//}
//
//function print(output){
//    console.log(output);
//}

var a = [];
var ans = 0;

function Graph(n){
    this.adj = new Array(n);
    for(var i = 0; i < n; i++)
        this.adj[i] = [];
};

function Edge(vertexTo, weightEdge){
    this.vertexTo = vertexTo;
    this.weightEdge = weightEdge;
};

Graph.prototype.addEdge = function(vertexFrom, vertexTo, weightEdge){
    var edge = new Edge(vertexTo, weightEdge);
    this.adj[vertexFrom].push(edge);
}

var Constants  = {
    WHITE_NODE : 0,
    GRAY_NODE : 1,
    BLACK_NODE : 2,
    NULL_PARENT : -1
}

function DepthFirstSearch(graph){
    this.adj = graph.adj;
    this.used = new Array(graph.adj.length);
    this.parent = new Array(graph.adj.length);
    for(var i = 0; i < this.adj.length; i++){
        this.used[i] = Constants.WHITE_NODE;
        this.parent[i] = Constants.NULL_PARENT;
    }
    this.path = [];
};

DepthFirstSearch.prototype.dfs = function(vertex, depth){
    ans = Math.max(ans, depth);
    depth++;
    this.used[vertex] = Constants.GRAY_NODE;
    for(var i = 0; i < this.adj[vertex].length; i++){
        var edge = this.adj[vertex][i];
        var next = edge.vertexTo;
        if(this.used[next] == Constants.WHITE_NODE){
            this.parent[next] = vertex;
            arguments.callee.apply(this, [next, depth]);
        }
    }
    this.used[vertex] = Constants.BLACK_NODE;
}

DepthFirstSearch.prototype.searchPath = function(vertexFrom, vertexTo){
    if(vertexFrom == vertexTo){
        this.path.push(vertexFrom);
    }else{
        if (this.parent[vertexTo] != Constants.NULL_PARENT) {
            arguments.callee.apply(this, [vertexFrom, this.parent[vertexTo]]);
            this.path.push(vertexTo);
        }
    }
}

DepthFirstSearch.prototype.getPath = function(vertexFrom, vertexTo){
    this.searchPath(vertexFrom, vertexTo);
    return this.path;
}

function main() {
    var n  = readline();
    var graph = new Graph(n);
    for(var i = 0; i < n; i++){
        var val = readline();
        if(val == -1) {
            a.push(i);
            continue;
        }
        graph.addEdge(val - 1, i);
    }
    for(var i = 0; i < a.length; i++){
        var alg = new DepthFirstSearch(graph);
        alg.dfs(i, 1);
    }
    print(ans);
    return 0;
}

main();

var print = this.print || require('lol-io').print
var write = this.write || require('lol-io').write
var readline = this.readline || require('lol-io').readline

var n=parseInt(readline());
var arr=[];
for(var i=0;i<n;i++){
    arr.push(parseInt(readline()));
}

var obj={};
for(var i=0;i<arr.length;i++){
    if(!obj[i]){
        obj[i]=[];
    }
    obj[i].push(arr[i]);
}
var res={};
var count=0;
for(var i in obj){
  if(!res[obj[i]]){
      res[obj[i]]=[];
      count++;
  }
}
print(count)

var print = this.print || require('lol-io').print
var write = this.write || require('lol-io').write
var readline = this.readline || require('lol-io').readline

var n=parseInt(readline());
var adj={};
for(var i=1;i<=n;i++){
    var t=parseInt(readline());
    if(t!=-1){
       if(!adj[t]){
           adj[t]=[];
       }
       if(!adj[i]){
        adj[i]=[];
       }
       adj[t].push(i);
       adj[i].push(t);
    }else{
        if(!adj[t]){
            adj[t]=[];
        };
        if(!adj[i]){
            adj[i]=[];
        };
      adj[t].push(i);
      adj[i].push(t);
    }
};
var q=[[-1,0]];
var vis={};
vis[0]=true;
var max=-1;
while(q.length){
    var size=q.length;
    count=0;
    for(var i=0;i<size;i++){
        var v=q.shift();
        var curr=v[0];
        var pos=v[1];
        for(var j in adj[curr]){
            var elm=adj[curr][j];
            if(!vis[elm]){
                vis[elm]=true;
                q.push([elm,pos+1]);
            }
        }
        max=Math.max(max,pos);
    }

}
print(max)

var a = readline().split(' ');
print(a);

var print = this.print || require('lol-io').print
var write = this.write || require('lol-io').write
var readline = this.readline || require('lol-io').readline

var n=parseInt(readline());
var adj={};
for(var i=1;i<=n;i++){
    var t=parseInt(readline());
    if(t!=-1){
       if(!adj[t]){
           adj[t]=[];
       }
       if(!adj[i]){
        adj[i]=[];
       }
       adj[t].push(i);
       adj[i].push(t);
    }else{
        if(!adj[t]){
            adj[t]=[];
        };
        if(!adj[i]){
            adj[i]=[];
        };
      adj[t].push(i);
      adj[i].push(t);
    }
};
var q=[[1,0]];
var vis={};
vis[0]=true;
var max=-1;
while(q.length){
    var size=q.length;
    for(var i=0;i<size;i++){
        var v=q.pop();
        var curr=v[0];
        var pos=v[1];
        max=Math.max(max,pos);
        for(var j in adj[curr]){
            var elm=adj[curr][j];
            if(!vis[elm]){
                vis[elm]=true;
                q.push([elm,pos+1]);
            }
        }
    }
}

print(max-1)


Let $$$f(i)$$$ denote the minimum positive integer $$$x$$$ such that $$$x$$$ is not a divisor of $$$i$$$.Compute $$$\sum_{i=1}^n f(i)$$$ modulo $$$10^9+7$$$. In other words, compute $$$f(1)+f(2)+\dots+f(n)$$$ modulo $$$10^9+7$$$.

The first line contains a single integer $$$t$$$ ($$$1\leq t\leq 10^4$$$), the number of test cases. Then $$$t$$$ cases follow. The only line of each test case contains a single integer $$$n$$$ ($$$1\leq n\leq 10^{16}$$$).

For each test case, output a single integer $$$ans$$$, where $$$ans=\sum_{i=1}^n f(i)$$$ modulo $$$10^9+7$$$.

NoteIn the fourth test case $$$n=4$$$, so $$$ans=f(1)+f(2)+f(3)+f(4)$$$.  $$$1$$$ is a divisor of $$$1$$$ but $$$2$$$ isn't, so $$$2$$$ is the minimum positive integer that isn't a divisor of $$$1$$$. Thus, $$$f(1)=2$$$.  $$$1$$$ and $$$2$$$ are divisors of $$$2$$$ but $$$3$$$ isn't, so $$$3$$$ is the minimum positive integer that isn't a divisor of $$$2$$$. Thus, $$$f(2)=3$$$.  $$$1$$$ is a divisor of $$$3$$$ but $$$2$$$ isn't, so $$$2$$$ is the minimum positive integer that isn't a divisor of $$$3$$$. Thus, $$$f(3)=2$$$.  $$$1$$$ and $$$2$$$ are divisors of $$$4$$$ but $$$3$$$ isn't, so $$$3$$$ is the minimum positive integer that isn't a divisor of $$$4$$$. Thus, $$$f(4)=3$$$. Therefore, $$$ans=f(1)+f(2)+f(3)+f(4)=2+3+2+3=10$$$.

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

const getLine = (function () {
    const getLineGen = (async function* () {
        for await (const line of rl) {
            yield line;
        }
    })();
    return async () => {
        let next;
        do {
            next = (await getLineGen.next());
        } while (!next.done && next.value === '');
        return next.value;
    };
})();
let LIMIT = BigInt(100000000);
LIMIT = LIMIT * LIMIT + BigInt(2);
const dels = new Array(100);
const vals = new Array(100);
dels[2] = 2;
vals[2] = BigInt(2);
vals[1] = BigInt(1);
dels[1] = 1;
let k = 3
for(; k < 100; k++) {
    let num = k;
    for(let j = 2; j < k; j++)
        if (num % dels[j] === 0)
            num /= dels[j];
    if (num > 1) {
        dels[k] = num;
        vals[k] = BigInt(num) * vals[k - 1];
    } else {
        dels[k] = 1;
        vals[k] = vals[k-1];
    }
    if (vals[k] > LIMIT)
        break;
}
const mod = 1000000007;
let solve = async () => {
    const nsc = parseInt(await getLine());
    for(let i = 0; i < nsc; i++) {
        const n = BigInt(await getLine());
        let sum = BigInt(0);
        for(let j = 1; vals[j] <= n; j++) {
            sum = sum + ((n / vals[j]) - (n / vals[j + 1])) * BigInt(j + 1);
            sum = sum % BigInt(mod);
        }

        console.log(sum.toString());
    }
}

solve();

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

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

var deb; const log = msg => (typeof deb != "undefined") && console.log("DEBUG", msg);

const MOD = BigInt(1e9 + 7);

const gcd = (a, b) => b ? gcd(b, a % b) : a;

const lcm = (a, b) => a * b / gcd(a, b);

function main () {
	let T = rn();
	while (T--) {
		const n = rbn();

		let ans = 0n, rem = n, l = 1n;
		for (let d = 2n; rem; d++) {
			l = lcm(l, d);
			ans = (ans + d * (rem - n/l)) % MOD;
			rem = n/l;
		}

		console.log(ans.toString());
	}
}

function gcd(x, y) {
   if (y === 0n) {
      return x;
   }
   return gcd(y, x % y);
}

function lcm(x, y) {
   return x * y / gcd(x, y);
}

var N = BigInt('1' + '0'.repeat(16));
var mod = BigInt(Math.pow(10, 9) + 7);
var arr = [];
var x = 1n;
var d = 1n;
while (x <= N) {
   arr.push(x);
   d += 1n;
   x = lcm(x, d);
}

function div(a, b) {
   return Math.floor(a / b);
}

function solve() {
   var n = BigInt(read());
   var ans = n;
   for (var i = 0; i < arr.length; i++){
      var step = arr[i];
      if (step > n) {
         break;
      }
      ans += n / step;
   }
   write(ans % mod);
}

function init() {
   var T;
   T = 1;
   T = Number(read());
   for (var t = 0; t < T; t++) {
      solve();
   }
}

function sortF(a, b) {
   if (a < b) {
      return -1;
   }
   if (a > b) {
      return 1;
   }
   return 0;
}

function readArray(f) {
   return read().split(' ').map(f);
}

var isNode = typeof console !== 'undefined';
var MEMORY = [];
var MEMORY_INDEX = 0;
if (isNode) {
   var fs = require('fs');
   var path = require('path');

   var inTextName;
   var outTextName;

   var needWriteFile = false;

   var writeResult = '';
   if (process.argv.length === 5) {
      inTextName = process.argv[3];
      outTextName = process.argv[4];
   }

   if (inTextName) {
      fs.readFile(path.join(__dirname, inTextName), 'utf8', (err, data) => {
         MEMORY = data.split('\r\n');
         init();
         if (needWriteFile) {
            fs.writeFile(path.join(__dirname, outTextName), writeResult, (err) => {
               err ? console.error(err) : console.log('good')
            });
         }
      });
   } else {
      MEMORY = fs.readFileSync(0, 'utf-8').split('\r\n');
      init();
   }
} else {
   init();
}

function write(value) {
   if (needWriteFile) {
      writeResult += value + '\n';
      return;
   }
   isNode ? console.log('' + value) : print('' + value);
}
function read() {
   return isNode ? MEMORY[MEMORY_INDEX++] : readline();
}
function readAll() {
   return isNode && MEMORY;
}

var readline = require('readline');

var rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout
});
var lines = [];
rl.on('line', function(input) {
    lines.push(input);
});
rl.on('close', function() {
    var t = parseInt(lines[0]);
    var l = 1;
    for (var i = 0; i < t; i++) {
        console.log(solve(BigInt(lines[l++])));
    }
});

function solve(n) {
    let k = 2n
    let l = 1n
    let sum = 0n
    while (l <= n) {
        const c1 = floor(n, l)
        l = lcm(l, k)
        // console.log(l)
        const c2 = floor(n, l)
        // if (c1 - c2 === 0n) break
        sum = add(sum, mul(c1 - c2, k))
        k++
    }
    return sum.toString()
}

function floor(a, b) {
    const r = a % b
    return (a - r) / b
}
function add(a, b) {
    return (a + b) % BigInt(1e9 + 7)
}
function mul(a, b) {
    const str = b.toString(2)
    let r = 0n
    let base = a
    for (let i = str.length - 1; i >= 0; i--) {
        if (str[i] === '1') {
            r = add(r, base)
        }
        base = add(base, base)
    }
    return r
}
function gcd(a, b) {
    if (a === 0n) return b
    if (b === 0n) return a

    while (a) {
        const r = b % a
        b = a
        a = r
    }
    return b
}
function lcm(a, b) {
    const g = gcd(a, b)
    return a / g * b
}

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

const getLine = (function () {
    const getLineGen = (async function* () {
        for await (const line of rl) {
            yield line;
        }
    })();
    return async () => {
        let next;
        do {
            next = (await getLineGen.next());
        } while (!next.done && next.value === '');
        return next.value;
    };
})();
let LIMIT = 100000000 + 1;
LIMIT = LIMIT * LIMIT;
const dels = new Array(100);
const vals = new Array(100);
dels[2] = 2;
vals[2] = 2;
vals[1] = 1;
dels[1] = 1;
let k = 3
for(; k < 100; k++) {
    let num = k;
    for(let j = 2; j < k; j++)
        if (num % dels[j] === 0)
            num /= dels[j];
    if (num > 1) {
        dels[k] = num;
        vals[k] = num * vals[k - 1];
    } else {
        dels[k] = 1;
        vals[k] = vals[k-1];
    }
    if (vals[k] > LIMIT)
        break;
}
const mod = 1000000007;
let solve = async () => {
    const nsc = parseInt(await getLine());
    for(let i = 0; i < nsc; i++) {
        const n = parseInt(await getLine());
        let sum = BigInt(0);
        for(let j = 1; vals[j] <= n; j++) {
            sum = sum + ((BigInt(n) / BigInt(vals[j])) - (BigInt(n) / BigInt(vals[j + 1]))) * BigInt(j + 1);
            sum = sum % BigInt(mod);
        }

        console.log(sum.toString());
    }
}

solve();


You and your friend are participating in a TV show "Run For Your Prize".At the start of the show n prizes are located on a straight line. i-th prize is located at position ai. Positions of all prizes are distinct. You start at position 1, your friend — at position 106 (and there is no prize in any of these two positions). You have to work as a team and collect all prizes in minimum possible time, in any order.You know that it takes exactly 1 second to move from position x to position x + 1 or x - 1, both for you and your friend. You also have trained enough to instantly pick up any prize, if its position is equal to your current position (and the same is true for your friend). Carrying prizes does not affect your speed (or your friend's speed) at all.Now you may discuss your strategy with your friend and decide who will pick up each prize. Remember that every prize must be picked up, either by you or by your friend.What is the minimum number of seconds it will take to pick up all the prizes?

The first line contains one integer n (1 ≤ n ≤ 105) — the number of prizes. The second line contains n integers a1, a2, ..., an (2 ≤ ai ≤ 106 - 1) — the positions of the prizes. No two prizes are located at the same position. Positions are given in ascending order.

Print one integer — the minimum number of seconds it will take to collect all prizes.

NoteIn the first example you take all the prizes: take the first at 1, the second at 2 and the third at 8.In the second example you take the first prize in 1 second and your friend takes the other in 5 seconds, you do this simultaneously, so the total time is 5.

var numPriz = readline();
var prizeLoc = readline().split(' ');

function foo(numPriz, prizeLoc) {

    var leftSeconds = 0;
    var rightSeconds = 0;

    var leftPrizeLocObj = {};
    var rightPrizeLocObj = {};

    prizeLoc.forEach(val => {
        if (val <= 500000) {
            leftPrizeLocObj[val + ''] = val;
        }
        else {
            rightPrizeLocObj[val + ''] = val;
        }
    });

    var leftKeys = Object.keys(leftPrizeLocObj);
    leftSeconds = leftPrizeLocObj[leftKeys[leftKeys.length - 1]] - 1 || 0;

    var rightKeys = Object.keys(rightPrizeLocObj);
    rightSeconds = 999999 - rightPrizeLocObj[rightKeys[0]] + 1 || 0;

    //console.log(Math.max(leftSeconds, rightSeconds));
    print(Math.max(leftSeconds, rightSeconds))

}

// foo(3, ['2', '3', '9']);
// foo(2, ['2', '999995'])
foo(numPriz, prizeLoc)

var numPriz = readline();
var prizeLoc = readline().split(' ');

function foo(numPriz, prizeLoc) {

    var leftSeconds = 0;
    var rightSeconds = 0;

    var leftPrizeLocObj = {};
    var rightPrizeLocObj = {};

    prizeLoc.forEach(val => {
        if (val <= 499999) {
            leftPrizeLocObj[val + ''] = val;
        }
        else {
            rightPrizeLocObj[val + ''] = val;
        }
    });

    var leftKeys = Object.keys(leftPrizeLocObj);
    leftSeconds = leftPrizeLocObj[leftKeys[leftKeys.length - 1]] - 1 || 0;

    var rightKeys = Object.keys(rightPrizeLocObj);
    rightSeconds = 999999 - rightPrizeLocObj[rightKeys[0]] + 1 || 0;

    //console.log(Math.max(leftSeconds, rightSeconds));
    print(Math.max(leftSeconds, rightSeconds))

}

// foo(3, ['2', '3', '9']);
// foo(2, ['2', '999995'])
foo(numPriz, prizeLoc)


A $$$\mathbf{0}$$$-indexed array $$$a$$$ of size $$$n$$$ is called good if for all valid indices $$$i$$$ ($$$0 \le i \le n-1$$$), $$$a_i + i$$$ is a perfect square$$$^\dagger$$$.Given an integer $$$n$$$. Find a permutation$$$^\ddagger$$$ $$$p$$$ of $$$[0,1,2,\ldots,n-1]$$$ that is good or determine that no such permutation exists.$$$^\dagger$$$ An integer $$$x$$$ is said to be a perfect square if there exists an integer $$$y$$$ such that $$$x = y^2$$$.$$$^\ddagger$$$ An array $$$b$$$ is a permutation of an array $$$a$$$ if $$$b$$$ consists of the elements of $$$a$$$ in arbitrary order. For example, $$$[4,2,3,4]$$$ is a permutation of $$$[3,2,4,4]$$$ while $$$[1,2,2]$$$ is not a permutation of $$$[1,2,3]$$$.

The first line contains a single integer $$$t$$$ ($$$1 \le t \le 10^4$$$) — the number of test cases. The only line of each test case contains a single integer $$$n$$$ ($$$1 \le n \le 10^5$$$) — the length of the permutation $$$p$$$. It is guaranteed that the sum of $$$n$$$ over all test cases does not exceed $$$10^5$$$.

For each test case, output $$$n$$$ distinct integers $$$p_0, p_1, \dots, p_{n-1}$$$ ($$$0 \le p_i \le n-1$$$) — the permutation $$$p$$$ — if the answer exists, and $$$-1$$$ otherwise.

process.stdin.resume();

let inputstring = '';
let currentLine = 0;

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

// we need to convert below code to process.stdin.on('end',()=>{}) when submitting or editing code on online editors. SIGINT is for CMD.
process.stdin.on('end', () => {
    inputstring = inputstring.split('\n');
    let t = Number(inputstring[0]);
    let i = 1;
    while (t--) {
        let n = Number(inputstring[i]);
        ++i;
        solve(n);
    }
    process.exit(0);
});

var ans;

function recurse(r) {
    if (r < 0) return;
    let s = Math.floor(Math.sqrt(2 * r));
    s *= s;
    let l = s - r;
    recurse(l - 1);
    for (; l <= r; ++l, --r){
        ans[l] = r;
        ans[r] = l;
    }
}

const solve = (n) => {
    ans = new Array(n);
    recurse(n - 1);
    var val = "";
    for (let i = 0; i < n; ++i){
        val += String(ans[i]) + ' ';
    }
    console.log(val);
}

// const http = require("http");
// const os = require("os");

// const server = http.createServer((req, res) => {
//     if (req.url == '/'){
//         res.end("Hello from Harsh");
//         process.exit(0);
//     }
//     else {
//         res.writeHead(http.STATUS_CODES = 404);
//         res.end("404! Not found")
//     }
// });

// server.listen(8000, "127.0.0.1", () => {
//     console.log("Listening to the port number 8000");
// });

// const data = {
//     name: "Harsh",
//     number: "34"
// };
// jsondata = JSON.stringify(data)
// console.log(jsondata);

'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++];
}

function output(x) {
    if (typeof x !== 'string') {
        x = x.toString();
    }
    //process.stdout.write(x);   // without auto '\n' (newline)
    console.log(x);  // with auto '\n' (newline)
}

function main() {
    let N = readline();

    function getElements(n) {
        if (n === 0) return [];

        const cand = Math.ceil(Math.sqrt(n - 1)) ** 2;
        let curr = n - 1;
        let idx = cand - curr;
        let res = [];
        while (idx < n) {
            res.push(curr);
            curr--;
            idx++;
        }

        return [...getElements(n - res.length), ...res];
    }

    for (let test = 0; test < N; test++) {
        let n = parseInt(readline(), 10);
        let res = getElements(n);
        output(res.join(' '));
    }
}

var tests = parseInt(readline());
    var n;
    for (var t=0; t < tests; t++) {
        n = parseInt(readline());
        var ans = new Array(n).fill(0);
        var i = n-1;
        while (i >= 0) {
            var sq = Math.pow(Math.ceil(Math.sqrt(i)), 2);
            var diff = sq - i;
            for (var j = diff; j <= i; j++, i--) {
                ans[j] = i;
                ans[i] = j;
            }
            i = diff - 1;
        }
        print(ans.join(' '));
    }

process.stdin.resume();

let inputstring = '';
let currentLine = 0;

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

// we need to convert below code to process.stdin.on('end',()=>{}) when submitting or editing code on online editors. SIGINT is for CMD.
process.on('SIGINT', () => {
    inputstring = inputstring.split('\n');
    let t = Number(inputstring[0]);
    let i = 1;
    while (t--) {
        let n = Number(inputstring[i]);
        ++i;
        solve(n);
    }
    process.exit(0);
});

var ans;

function recurse(r) {
    if (r < 0) return;
    let s = Math.floor(Math.sqrt(2 * r));
    s *= s;
    let l = s - r;
    recurse(l - 1);
    for (; l <= r; ++l, --r){
        ans[l] = r;
        ans[r] = l;
    }
}

const solve = (n) => {
    ans = new Array(n);
    recurse(n - 1);
    var val = "";
    for (let i = 0; i < n; ++i){
        val += String(ans[i]) + ' ';
    }
    console.log(val);
}

// const http = require("http");
// const os = require("os");

// const server = http.createServer((req, res) => {
//     if (req.url == '/'){
//         res.end("Hello from Harsh");
//         process.exit(0);
//     }
//     else {
//         res.writeHead(http.STATUS_CODES = 404);
//         res.end("404! Not found")
//     }
// });

// server.listen(8000, "127.0.0.1", () => {
//     console.log("Listening to the port number 8000");
// });

// const data = {
//     name: "Harsh",
//     number: "34"
// };
// jsondata = JSON.stringify(data)
// console.log(jsondata);


This is the hard version of the problem. The only difference between the two versions is the constraint on $$$n$$$. You can make hacks only if all versions of the problem are solved.A forest is an undirected graph without cycles (not necessarily connected).Mocha and Diana are friends in Zhijiang, both of them have a forest with nodes numbered from $$$1$$$ to $$$n$$$, and they would like to add edges to their forests such that:   After adding edges, both of their graphs are still forests.  They add the same edges. That is, if an edge $$$(u, v)$$$ is added to Mocha's forest, then an edge $$$(u, v)$$$ is added to Diana's forest, and vice versa. Mocha and Diana want to know the maximum number of edges they can add, and which edges to add.

The first line contains three integers $$$n$$$, $$$m_1$$$ and $$$m_2$$$ ($$$1 \le n \le 10^5$$$, $$$0 \le m_1, m_2 < n$$$) — the number of nodes and the number of initial edges in Mocha's forest and Diana's forest. Each of the next $$$m_1$$$ lines contains two integers $$$u$$$ and $$$v$$$ ($$$1 \le u, v \le n$$$, $$$u \neq v$$$) — the edges in Mocha's forest. Each of the next $$$m_2$$$ lines contains two integers $$$u$$$ and $$$v$$$ ($$$1 \le u, v \le n$$$, $$$u \neq v$$$) — the edges in Diana's forest.

The first line contains only one integer $$$h$$$, the maximum number of edges Mocha and Diana can add. Each of the next $$$h$$$ lines contains two integers $$$u$$$ and $$$v$$$ ($$$1 \le u, v \le n$$$, $$$u \neq v$$$) — the edge you add each time. If there are multiple correct answers, you can print any one of them.

NoteIn the first example, we cannot add any edge.In the second example, the initial forests are as follows.We can add an edge $$$(2, 4)$$$.

'use strict'
Object.defineProperty(exports, '__esModule', { value: !0 })
var os = require('os')
function createHeuristicFindSet() {
  const e = [],
    t = []
  let n = 0
  return {
    init: function (r) {
      ;(n = r), e.length <= n && (e.length = n + 1)
      t.length <= n && (t.length = n + 1)
      for (let r = 1; r <= n; ++r) (e[r] = r), (t[r] = 1)
    },
    root: r,
    merge: function (n, i) {
      const s = r(n),
        o = r(i)
      if (s === o) return s
      if (t[s] > t[o]) return (e[o] = s), (t[s] += t[o]), s
      return (e[s] = o), (t[o] += t[s]), o
    },
    size: function (e) {
      const n = r(e)
      return t[n]
    },
  }
  function r(e) {
    if (e < 1 || e > n)
      throw new RangeError(`Out of boundary [1, ${n}]. x: ${e}`)
    return i(e)
  }
  function i(t) {
    return e[t] === t ? t : (e[t] = i(e[t]))
  }
}
const stdin = process.stdin,
  stdout = process.stdout,
  integerRegex = /-?\d+/g,
  decimalRegex = /-?\d+(?:\.\d+)?/g
class InputAndOutput {
  lineIndex = 0
  lines = []
  dried() {
    return this.lineIndex >= this.lines.length
  }
  readLine() {
    const e = this.lines[this.lineIndex]
    return (this.lineIndex += 1), e
  }
  readLineAsNumber() {
    return Number(this.readLine())
  }
  readIntegersOfLine() {
    const e = this.readLine().match(integerRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  readNumsOfLine() {
    const e = this.readLine().match(decimalRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  print(e) {
    stdout.write(String(e))
  }
  println(e) {
    stdout.write(String(e)), stdout.write('\n')
  }
  async init() {
    const e = await this.readLines()
    this.lines = e
  }
  readLines() {
    const e = []
    return new Promise(t => {
      stdin.on('data', t => e.push(t)),
        stdin.on('end', function () {
          const n = e.join('').split(os.EOL)
          t(n)
        })
    })
  }
}
async function __main__(e) {
  const t = new InputAndOutput()
  await t.init(), e(t)
}
function solve() {
  return -1
}
const MAX_N = 100010,
  findset1 = createHeuristicFindSet(),
  findset2 = createHeuristicFindSet(),
  pos1 = new Array(MAX_N).fill(0),
  pos2 = new Array(MAX_N).fill(0)
__main__(function (e) {
  for (let t = 1; t <= 1; ++t) {
    const [t, n, r] = e.readIntegersOfLine()
    findset1.init(t), findset2.init(t)
    for (let t = 0; t < n; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset1.merge(t, n)
    }
    for (let t = 0; t < r; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset2.merge(t, n)
    }
    e.println(t - 1 - Math.max(n, r))
    const i = Math.min(Math.floor(Math.random() * t) + 1, t)
    for (let n = 1; n <= t; ++n) {
      const t = findset1.root(n),
        r = findset1.root(i),
        s = findset2.root(n),
        o = findset2.root(i)
      t !== r &&
        s !== o &&
        (findset1.merge(t, r), findset2.merge(s, o), e.println(i + ' ' + n))
    }
    let s = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset1.root(e),
        n = findset1.root(i)
      t !== n && (findset1.merge(t, n), (pos1[s++] = e))
    }
    let o = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset2.root(e),
        n = findset2.root(i)
      t !== n && (findset2.merge(t, n), (pos2[o++] = e))
    }
    for (let t = 0, n = Math.min(s, o); t < n; ++t) {
      const n = pos1[t],
        r = pos2[t]
      e.println(n + ' ' + r)
    }
  }
})

'use strict'
Object.defineProperty(exports, '__esModule', { value: !0 })
var os = require('os')
function createHeuristicFindSet(e) {
  const t = new Array(e + 1),
    n = new Array(e + 1)
  let r = e
  return {
    init: function (e) {
      r = e
      for (let e = 1; e <= r; ++e) (t[e] = e), (n[e] = 1)
    },
    root: i,
    merge: function (e, r) {
      const s = i(e),
        o = i(r)
      if (s === o) return s
      if (n[s] > n[o]) return (t[o] = s), (n[s] += n[o]), s
      return (t[s] = o), (n[o] += n[s]), o
    },
    size: function (e) {
      const t = i(e)
      return n[t]
    },
  }
  function i(e) {
    if (e < 1 || e > r)
      throw new RangeError(`Out of boundary [1, ${r}]. x: ${e}`)
    return s(e)
  }
  function s(e) {
    return t[e] === e ? e : (t[e] = s(t[e]))
  }
}
const stdin = process.stdin,
  stdout = process.stdout,
  integerRegex = /-?\d+/g,
  decimalRegex = /-?\d+(?:\.\d+)?/g
class InputAndOutput {
  lineIndex = 0
  lines = []
  dried() {
    return this.lineIndex >= this.lines.length
  }
  readLine() {
    const e = this.lines[this.lineIndex]
    return (this.lineIndex += 1), e
  }
  readLineAsNumber() {
    return Number(this.readLine())
  }
  readIntegersOfLine() {
    const e = this.readLine().match(integerRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  readNumsOfLine() {
    const e = this.readLine().match(decimalRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  print(e) {
    stdout.write(String(e))
  }
  println(e) {
    stdout.write(String(e)), stdout.write('\n')
  }
  async init() {
    const e = await this.readLines()
    this.lines = e
  }
  readLines() {
    const e = []
    return new Promise(t => {
      stdin.on('data', t => e.push(t)),
        stdin.on('end', function () {
          const n = e.join('').split(os.EOL)
          t(n)
        })
    })
  }
}
async function __main__(e) {
  const t = new InputAndOutput()
  await t.init(), e(t)
}
function solve() {
  return -1
}
const MAX_N = 100010,
  findset1 = createHeuristicFindSet(MAX_N),
  findset2 = createHeuristicFindSet(MAX_N),
  pos1 = new Array(MAX_N).fill(0),
  pos2 = new Array(MAX_N).fill(0)
__main__(function (e) {
  for (let t = 1; t <= 1; ++t) {
    const [t, n, r] = e.readIntegersOfLine()
    findset1.init(t), findset2.init(t)
    for (let t = 0; t < n; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset1.merge(t, n)
    }
    for (let t = 0; t < r; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset2.merge(t, n)
    }
    e.println(t - 1 - Math.max(n, r))
    const i = Math.min(Math.floor(Math.random() * t) + 1, t)
    for (let n = 1; n <= t; ++n) {
      const t = findset1.root(n),
        r = findset1.root(i),
        s = findset2.root(n),
        o = findset2.root(i)
      t !== r &&
        s !== o &&
        (findset1.merge(t, r), findset2.merge(s, o), e.println(i + ' ' + n))
    }
    let s = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset1.root(e),
        n = findset1.root(i)
      t !== n && (findset1.merge(t, n), (pos1[s++] = e))
    }
    let o = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset2.root(e),
        n = findset2.root(i)
      t !== n && (findset2.merge(t, n), (pos2[o++] = e))
    }
    for (let t = 0, n = Math.min(s, o); t < n; ++t) {
      const n = pos1[t],
        r = pos2[t]
      e.println(n + ' ' + r)
    }
  }
})

'use strict'
Object.defineProperty(exports, '__esModule', { value: !0 })
var os = require('os')
function createFindSet(e) {
  const t = new Array(e + 1)
  let n = e
  return {
    init: function (e) {
      n = e
      for (let n = 1; n <= e; ++n) t[n] = n
    },
    root: r,
    merge: function (e, n) {
      const i = r(e),
        s = r(n)
      if (i === s) return i
      if (i < s) return (t[s] = i), i
      return (t[i] = s), s
    },
  }
  function r(e) {
    if (e < 1 || e > n)
      throw new RangeError(`Out of boundary [1, ${n}]. x: ${e}`)
    return i(e)
  }
  function i(e) {
    return t[e] === e ? e : (t[e] = i(t[e]))
  }
}
const stdin = process.stdin,
  stdout = process.stdout,
  integerRegex = /-?\d+/g,
  decimalRegex = /-?\d+(?:\.\d+)?/g
class InputAndOutput {
  lineIndex = 0
  lines = []
  dried() {
    return this.lineIndex >= this.lines.length
  }
  readLine() {
    const e = this.lines[this.lineIndex]
    return (this.lineIndex += 1), e
  }
  readLineAsNumber() {
    return Number(this.readLine())
  }
  readIntegersOfLine() {
    const e = this.readLine().match(integerRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  readNumsOfLine() {
    const e = this.readLine().match(decimalRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  print(e) {
    stdout.write(String(e))
  }
  println(e) {
    stdout.write(String(e)), stdout.write('\n')
  }
  async init() {
    const e = await this.readLines()
    this.lines = e
  }
  readLines() {
    const e = []
    return new Promise(t => {
      stdin.on('data', t => e.push(t)),
        stdin.on('end', function () {
          const n = e.join('').split(os.EOL)
          t(n)
        })
    })
  }
}
async function __main__(e) {
  const t = new InputAndOutput()
  await t.init(), e(t)
}
function solve() {
  return -1
}
const MAX_N = 100010,
  findset1 = createFindSet(MAX_N),
  findset2 = createFindSet(MAX_N),
  pos1 = new Array(MAX_N).fill(0),
  pos2 = new Array(MAX_N).fill(0)
__main__(function (e) {
  for (let t = 1; t <= 1; ++t) {
    const [t, n, r] = e.readIntegersOfLine()
    findset1.init(t), findset2.init(t)
    for (let t = 0; t < n; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset1.merge(t, n)
    }
    for (let t = 0; t < r; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset2.merge(t, n)
    }
    e.println(t - 1 - Math.max(n, r))
    const i = Math.min(Math.floor(Math.random() * t) + 1, t)
    for (let n = 1; n <= t; ++n) {
      const t = findset1.root(n),
        r = findset1.root(i),
        s = findset2.root(n),
        o = findset2.root(i)
      t !== r &&
        s !== o &&
        (findset1.merge(t, r), findset2.merge(s, o), e.println(i + ' ' + n))
    }
    let s = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset1.root(e),
        n = findset1.root(i)
      t !== n && (findset1.merge(t, n), (pos1[s++] = e))
    }
    let o = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset2.root(e),
        n = findset2.root(i)
      t !== n && (findset2.merge(t, n), (pos2[o++] = e))
    }
    for (let t = 0, n = Math.min(s, o); t < n; ++t) {
      const n = pos1[t],
        r = pos2[t]
      e.println(n + ' ' + r)
    }
  }
})

'use strict'
Object.defineProperty(exports, '__esModule', { value: !0 })
var os = require('os')
function createFindSet(e) {
  const t = new Array(e + 1)
  return {
    init: function (e) {
      for (let n = 1; n <= e; ++n) t[n] = n
    },
    root: n,
    merge: function (e, r) {
      const i = n(e),
        s = n(r)
      if (i === s) return i
      if (i < s) return (t[s] = i), i
      return (t[i] = s), s
    },
  }
  function n(e) {
    return t[e] === e ? e : (t[e] = n(t[e]))
  }
}
const stdin = process.stdin,
  stdout = process.stdout,
  integerRegex = /-?\d+/g,
  decimalRegex = /-?\d+(?:\.\d+)?/g
class InputAndOutput {
  lineIndex = 0
  lines = []
  dried() {
    return this.lineIndex >= this.lines.length
  }
  readLine() {
    const e = this.lines[this.lineIndex]
    return (this.lineIndex += 1), e
  }
  readLineAsNumber() {
    return Number(this.readLine())
  }
  readIntegersOfLine() {
    const e = this.readLine().match(integerRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  readNumsOfLine() {
    const e = this.readLine().match(decimalRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  print(e) {
    stdout.write(String(e))
  }
  println(e) {
    stdout.write(String(e)), stdout.write('\n')
  }
  async init() {
    const e = await this.readLines()
    this.lines = e
  }
  readLines() {
    const e = []
    return new Promise(t => {
      stdin.on('data', t => e.push(t)),
        stdin.on('end', function () {
          const n = e.join('').split(os.EOL)
          t(n)
        })
    })
  }
}
async function __main__(e) {
  const t = new InputAndOutput()
  await t.init(), e(t)
}
function solve() {
  return -1
}
const MAX_N = 100010,
  findset1 = createFindSet(MAX_N),
  findset2 = createFindSet(MAX_N),
  pos1 = new Array(MAX_N).fill(0),
  pos2 = new Array(MAX_N).fill(0)
__main__(function (e) {
  for (let t = 1; t <= 1; ++t) {
    const [t, n, r] = e.readIntegersOfLine()
    findset1.init(t), findset2.init(t)
    for (let t = 0; t < n; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset1.merge(t, n)
    }
    for (let t = 0; t < r; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset2.merge(t, n)
    }
    e.println(t - 1 - Math.max(n, r))
    const i = Math.min(Math.floor(Math.random() * t) + 1, t)
    for (let n = 1; n <= t; ++n) {
      const t = findset1.root(n),
        r = findset1.root(i),
        s = findset2.root(n),
        o = findset2.root(i)
      t !== r &&
        s !== o &&
        (findset1.merge(t, r), findset2.merge(s, o), e.println(i + ' ' + n))
    }
    let s = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset1.root(e),
        n = findset1.root(i)
      t !== n && (findset1.merge(t, n), (pos1[s++] = e))
    }
    let o = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset2.root(e),
        n = findset2.root(i)
      t !== n && (findset2.merge(t, n), (pos2[o++] = e))
    }
    for (let t = 0, n = Math.min(s, o); t < n; ++t) {
      const n = pos1[t],
        r = pos2[t]
      e.println(n + ' ' + r)
    }
  }
})

'use strict'
Object.defineProperty(exports, '__esModule', { value: !0 })
var os = require('os')
function createHeuristicFindSet(e) {
  const t = new Array(e + 1),
    n = new Array(e + 1)
  let r = e
  return {
    init: function (e) {
      ;(r = e), n.fill(1, r + 1, 1)
      for (let e = 1; e <= r; ++e) t[e] = e
    },
    root: i,
    merge: function (e, r) {
      const s = i(e),
        o = i(r)
      if (s === o) return s
      if (n[s] > n[o]) return (t[o] = s), (n[s] += n[o]), s
      return (t[s] = o), (n[o] += n[s]), o
    },
    size: function (e) {
      const t = i(e)
      return n[t]
    },
  }
  function i(e) {
    if (e < 1 || e > r)
      throw new RangeError(`Out of boundary [1, ${r}]. x: ${e}`)
    return t[e] === e ? e : (t[e] = i(t[e]))
  }
}
const stdin = process.stdin,
  stdout = process.stdout,
  integerRegex = /-?\d+/g,
  decimalRegex = /-?\d+(?:\.\d+)?/g
class InputAndOutput {
  lineIndex = 0
  lines = []
  dried() {
    return this.lineIndex >= this.lines.length
  }
  readLine() {
    const e = this.lines[this.lineIndex]
    return (this.lineIndex += 1), e
  }
  readLineAsNumber() {
    return Number(this.readLine())
  }
  readIntegersOfLine() {
    const e = this.readLine().match(integerRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  readNumsOfLine() {
    const e = this.readLine().match(decimalRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  print(e) {
    stdout.write(String(e))
  }
  println(e) {
    stdout.write(String(e)), stdout.write('\n')
  }
  async init() {
    const e = await this.readLines()
    this.lines = e
  }
  readLines() {
    const e = []
    return new Promise(t => {
      stdin.on('data', t => e.push(t)),
        stdin.on('end', function () {
          const n = e.join('').split(os.EOL)
          t(n)
        })
    })
  }
}
async function __main__(e) {
  const t = new InputAndOutput()
  await t.init(), e(t)
}
function solve() {
  return -1
}
const MAX_N = 100010,
  findset1 = createHeuristicFindSet(MAX_N),
  findset2 = createHeuristicFindSet(MAX_N),
  pos1 = new Array(MAX_N).fill(0),
  pos2 = new Array(MAX_N).fill(0)
__main__(function (e) {
  for (let t = 1; t <= 1; ++t) {
    const [t, n, r] = e.readIntegersOfLine()
    findset1.init(t), findset2.init(t)
    for (let t = 0; t < n; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset1.merge(t, n)
    }
    for (let t = 0; t < r; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset2.merge(t, n)
    }
    e.println(t - 1 - Math.max(n, r))
    const i = Math.min(Math.floor(Math.random() * t) + 1, t)
    for (let n = 1; n <= t; ++n) {
      const t = findset1.root(n),
        r = findset1.root(i),
        s = findset2.root(n),
        o = findset2.root(i)
      t !== r &&
        s !== o &&
        (findset1.merge(t, r), findset2.merge(s, o), e.println(i + ' ' + n))
    }
    let s = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset1.root(e),
        n = findset1.root(i)
      t !== n && (findset1.merge(t, n), (pos1[s++] = e))
    }
    let o = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset2.root(e),
        n = findset2.root(i)
      t !== n && (findset2.merge(t, n), (pos2[o++] = e))
    }
    for (let t = 0, n = Math.min(s, o); t < n; ++t) {
      const n = pos1[t],
        r = pos2[t]
      e.println(n + ' ' + r)
    }
  }
})

'use strict'
Object.defineProperty(exports, '__esModule', { value: !0 })
var os = require('os')
function createHeuristicFindSet(e) {
  const t = new Array(e + 1),
    n = new Array(e + 1)
  let i = e
  return {
    init: function (e) {
      ;(i = e), n.fill(1, i + 1, 1)
      for (let e = 1; e <= i; ++e) t[e] = e
    },
    root: r,
    merge: function (e, i) {
      const s = r(e),
        o = r(i)
      if (s === o) return s
      if (n[s] > n[o]) return (t[o] = s), (n[s] += n[o]), s
      return (t[s] = o), o
    },
  }
  function r(e) {
    return t[e] === e ? e : (t[e] = r(t[e]))
  }
}
const stdin = process.stdin,
  stdout = process.stdout,
  integerRegex = /-?\d+/g,
  decimalRegex = /-?\d+(?:\.\d+)?/g
class InputAndOutput {
  lineIndex = 0
  lines = []
  dried() {
    return this.lineIndex >= this.lines.length
  }
  readLine() {
    const e = this.lines[this.lineIndex]
    return (this.lineIndex += 1), e
  }
  readLineAsNumber() {
    return Number(this.readLine())
  }
  readIntegersOfLine() {
    const e = this.readLine().match(integerRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  readNumsOfLine() {
    const e = this.readLine().match(decimalRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  print(e) {
    stdout.write(String(e))
  }
  println(e) {
    stdout.write(String(e)), stdout.write('\n')
  }
  async init() {
    const e = await this.readLines()
    this.lines = e
  }
  readLines() {
    const e = []
    return new Promise(t => {
      stdin.on('data', t => e.push(t)),
        stdin.on('end', function () {
          const n = e.join('').split(os.EOL)
          t(n)
        })
    })
  }
}
async function __main__(e) {
  const t = new InputAndOutput()
  await t.init(), e(t)
}
function solve() {
  return -1
}
const MAX_N = 100010,
  findset1 = createHeuristicFindSet(MAX_N),
  findset2 = createHeuristicFindSet(MAX_N),
  pos1 = new Array(MAX_N).fill(0),
  pos2 = new Array(MAX_N).fill(0)
__main__(function (e) {
  for (let t = 1; t <= 1; ++t) {
    const [t, n, i] = e.readIntegersOfLine()
    findset1.init(t), findset2.init(t)
    for (let t = 0; t < n; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset1.merge(t, n)
    }
    for (let t = 0; t < i; ++t) {
      const [t, n] = e.readIntegersOfLine()
      findset2.merge(t, n)
    }
    e.println(t - 1 - Math.max(n, i))
    const r = Math.min(Math.floor(Math.random() * t) + 1, t)
    for (let n = 1; n <= t; ++n) {
      const t = findset1.root(n),
        i = findset1.root(r),
        s = findset2.root(n),
        o = findset2.root(r)
      t !== i &&
        s !== o &&
        (findset1.merge(t, i), findset2.merge(s, o), e.println(r + ' ' + n))
    }
    let s = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset1.root(e),
        n = findset1.root(r)
      t !== n && (findset1.merge(t, n), (pos1[s++] = e))
    }
    let o = 0
    for (let e = 1; e <= t; ++e) {
      const t = findset2.root(e),
        n = findset2.root(r)
      t !== n && (findset2.merge(t, n), (pos2[o++] = e))
    }
    for (let t = 0, n = Math.min(s, o); t < n; ++t) {
      const n = pos1[t],
        i = pos2[t]
      e.println(n + ' ' + i)
    }
  }
})

'use strict'
Object.defineProperty(exports, '__esModule', { value: !0 })
var os = require('os')
function createHeuristicFindSet(e) {
  const t = new Array(e + 1),
    n = new Array(e + 1)
  let r = e
  return {
    init: function (e) {
      ;(r = e), n.fill(1, r + 1, 1)
      for (let e = 1; e <= r; ++e) t[e] = e
    },
    root: i,
    merge: function (e, r) {
      const s = i(e),
        o = i(r)
      if (s === o) return s
      if (n[s] > n[o]) return (t[o] = s), (n[s] += n[o]), s
      return (t[s] = o), o
    },
  }
  function i(e) {
    return t[e] === e ? e : (t[e] = i(t[e]))
  }
}
const stdin = process.stdin,
  stdout = process.stdout,
  integerRegex = /-?\d+/g,
  decimalRegex = /-?\d+(?:\.\d+)?/g
class InputAndOutput {
  lineIndex = 0
  lines = []
  dried() {
    return this.lineIndex >= this.lines.length
  }
  readLine() {
    const e = this.lines[this.lineIndex]
    return (this.lineIndex += 1), e
  }
  readLineAsNumber() {
    return Number(this.readLine())
  }
  readIntegersOfLine() {
    const e = this.readLine().match(integerRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  readNumsOfLine() {
    const e = this.readLine().match(decimalRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  print(e) {
    stdout.write(String(e))
  }
  println(e) {
    stdout.write(String(e)), stdout.write('\n')
  }
  async init() {
    const e = await this.readLines()
    this.lines = e
  }
  readLines() {
    const e = []
    return new Promise(t => {
      stdin.on('data', t => e.push(t)),
        stdin.on('end', function () {
          const n = e.join('').split(os.EOL)
          t(n)
        })
    })
  }
}
async function __main__(e) {
  const t = new InputAndOutput()
  await t.init(), e(t)
}
function solve() {
  return -1
}
__main__(function (e) {
  const t = 100010,
    n = createHeuristicFindSet(t),
    r = createHeuristicFindSet(t)
  for (let t = 1; t <= 1; ++t) {
    const [t, i, s] = e.readIntegersOfLine()
    n.init(t), r.init(t)
    for (let t = 0; t < i; ++t) {
      const [t, r] = e.readIntegersOfLine()
      n.merge(t, r)
    }
    for (let t = 0; t < s; ++t) {
      const [t, n] = e.readIntegersOfLine()
      r.merge(t, n)
    }
    e.println(t - 1 - Math.max(i, s))
    const o = Math.min(Math.floor(Math.random() * t) + 1, t)
    for (let i = 1; i <= t; ++i) {
      const t = n.root(i),
        s = n.root(o),
        u = r.root(i),
        c = r.root(o)
      t !== s &&
        u !== c &&
        (n.merge(t, s), r.merge(u, c), e.println(o + ' ' + i))
    }
    const u = []
    for (let e = 1; e <= t; ++e) {
      const t = n.root(e),
        r = n.root(o)
      t !== r && (n.merge(t, r), u.push(e))
    }
    const c = []
    for (let e = 1; e <= t; ++e) {
      const t = r.root(e),
        n = r.root(o)
      t !== n && (r.merge(t, n), c.push(e))
    }
    for (let t = 0, n = Math.min(u.length, c.length); t < n; ++t) {
      const n = u[t],
        r = c[t]
      e.println(n + ' ' + r)
    }
  }
})

'use strict'
Object.defineProperty(exports, '__esModule', { value: !0 })
var os = require('os')
function createHeuristicFindSet(e) {
  const t = new Array(e + 1),
    n = new Array(e + 1)
  let r = e
  return {
    init: function (e) {
      ;(r = e), n.fill(1, r + 1, 1)
      for (let e = 1; e <= r; ++e) t[e] = e
    },
    root: i,
    merge: function (e, r) {
      const o = i(e),
        s = i(r)
      if (o === s) return o
      if (n[o] > n[s]) return (t[s] = o), (n[o] += n[s]), o
      return (t[o] = s), s
    },
  }
  function i(e) {
    return t[e] === e ? e : (t[e] = i(t[e]))
  }
}
const stdin = process.stdin,
  stdout = process.stdout,
  integerRegex = /-?\d+/g,
  decimalRegex = /-?\d+(?:\.\d+)?/g
class InputAndOutput {
  lineIndex = 0
  lines = []
  dried() {
    return this.lineIndex >= this.lines.length
  }
  readLine() {
    const e = this.lines[this.lineIndex]
    return (this.lineIndex += 1), e
  }
  readLineAsNumber() {
    return Number(this.readLine())
  }
  readIntegersOfLine() {
    const e = this.readLine().match(integerRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  readNumsOfLine() {
    const e = this.readLine().match(decimalRegex)
    return null == e ? [] : e.map(e => Number(e))
  }
  print(e) {
    stdout.write(e)
  }
  async init() {
    const e = await this.readLines()
    this.lines = e
  }
  readLines() {
    const e = []
    return new Promise(t => {
      stdin.on('data', t => e.push(t)),
        stdin.on('end', function () {
          const n = e.join('').split(os.EOL)
          t(n)
        })
    })
  }
}
async function __main__(e) {
  const t = new InputAndOutput()
  await t.init(), e(t)
}
function solve() {
  return -1
}
__main__(function (e) {
  const t = 100010,
    n = createHeuristicFindSet(t),
    r = createHeuristicFindSet(t)
  for (let t = 1; t <= 1; ++t) {
    const [t, i, o] = e.readIntegersOfLine()
    n.init(t), r.init(t)
    for (let t = 0; t < i; ++t) {
      const [t, r] = e.readIntegersOfLine()
      n.merge(t, r)
    }
    for (let t = 0; t < o; ++t) {
      const [t, n] = e.readIntegersOfLine()
      r.merge(t, n)
    }
    const s = [],
      u = Math.floor(Math.random() * t) + 1
    for (let e = 1; e <= t; ++e) {
      const t = n.root(e),
        i = n.root(u),
        o = r.root(e),
        c = r.root(u)
      t !== i && o !== c && (n.merge(t, i), r.merge(o, c), s.push([u, e]))
    }
    const c = []
    for (let e = 1; e <= t; ++e) {
      const t = n.root(e),
        r = n.root(u)
      t !== r && (n.merge(t, r), c.push(e))
    }
    const a = []
    for (let e = 1; e <= t; ++e) {
      const t = r.root(e),
        n = r.root(u)
      t !== n && (r.merge(t, n), a.push(e))
    }
    for (let e = 0, t = Math.min(c.length, a.length); e < t; ++e)
      s.push([c[e], a[e]])
    e.print(s.length + '\n')
    for (const t of s) e.print(t.join(' ') + '\n')
  }
})