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

//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)

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));

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

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)


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

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
}

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

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


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

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);


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