use std::io::Read;
use std::cmp::max;

fn main() {
    let mut buf = String::new();
    std::io::stdin().read_to_string(&mut buf).unwrap();

    let answer = solve(&buf);

    println!("{}", answer);
}

fn solve(input: &str) -> String {
    let mut iterator = input.split_whitespace();

    let n: usize = iterator.next().unwrap().parse().unwrap();

    let mut tree: Vec<Node> = vec![Node { parent: -1, left: -1, right: -1 }; n];
    for _ in 0..n {
        let id: isize = iterator.next().unwrap().parse().unwrap();
        let left: isize = iterator.next().unwrap().parse().unwrap();
        let right: isize = iterator.next().unwrap().parse().unwrap();

        if left != -1 {
            tree[id as usize].left = left;
            tree[left as usize].parent = id;
        }
        if right != -1 {
            tree[id as usize].right = right;
            tree[right as usize].parent = id;
        }
    }

    let root_id = tree.iter().position(|node| node.parent == -1).unwrap();

    let mut depths: Vec<usize> = vec![0; n];
    set_depth(root_id, 0, &tree, &mut depths);

    let mut heights: Vec<usize> = vec![0; n];
    set_heights(root_id, &tree, &mut heights);

    let mut ans = String::new();
    for i in 0..n {
        let node = &tree[i];

        let sibling = if node.parent == -1 {
            -1
        } else if i == tree[node.parent as usize].left as usize {
            tree[node.parent as usize].right
        } else {
            tree[node.parent as usize].left
        };

        let degree = if node.left == -1 && node.right == -1 {
            0
        } else if node.left == -1 || node.right == -1 {
            1
        } else {
            2
        };

        let node_type = if node.parent == -1 {
            "root"
        } else if node.left == -1 && node.right == -1 {
            "leaf"
        } else {
            "internal node"
        };

        ans += &format!(
            "node {}: parent = {}, sibling = {}, degree = {}, depth = {}, height = {}, {}\n",
            i,
            node.parent,
            sibling,
            degree,
            depths[i],
            heights[i],
            node_type
        );
    }

    return ans.trim().to_string();
}

fn set_depth(id: usize, depth: usize, tree: &Vec<Node>, depths: &mut Vec<usize>) {
    depths[id] = depth;

    let node = &tree[id];
    if node.left != -1 {
        set_depth(node.left as usize, depth + 1, tree, depths);
    }
    if node.right != -1 {
        set_depth(node.right as usize, depth + 1, tree, depths);
    }
}

fn set_heights(id: usize, tree: &Vec<Node>, heights: &mut Vec<usize>) -> usize {
    let node = &tree[id];
    if node.left == -1 && node.right == -1 {
        heights[id] = 0;
        return 0;
    }

    let mut left_height = 0;
    if node.left != -1 {
        left_height = set_heights(node.left as usize, tree, heights);
    }

    let mut right_height = 0;
    if node.right != -1 {
        right_height = set_heights(node.right as usize, tree, heights);
    }

    let height = max(left_height, right_height) + 1;
    heights[id] = height;
    return height;
}

#[derive(Clone)]
struct Node {
    parent: isize,
    left: isize,
    right: isize,
}



Measured memory_bytes: 5020