#include <algorithm>
#include <array>
#include <iostream>
#include <map>
#include <string>

constexpr int NONE = -1, ROOT = 0, INTERNAL = 1, LEAF = 2;

struct Node {
    Node()
        : left(NONE),
          right(NONE),
          parent(NONE),
          sibling(NONE),
          degree(0),
          depth(NONE),
          height(0),
          type(INTERNAL) {}
    int left, right, parent, sibling, degree, depth, height, type;
};
using Nodes = std::map<int, Node>;

std::string type_num_to_string(int type) {
    const std::array<std::string, 3> name = {"root", "internal node", "leaf"};
    return name.at(type);
}

void walk_depth(Nodes& nodes, int tmp, int depth) {
    Node& node = nodes.find(tmp)->second;
    node.depth = depth;
    if (node.left != NONE) walk_depth(nodes, node.left, depth + 1);
    if (node.right != NONE) walk_depth(nodes, node.right, depth + 1);
}

int walk_height(Nodes& nodes, int tmp) {
    Node& node = nodes.find(tmp)->second;
    if (node.type == LEAF || nodes.size() == 1) {
        node.height = 0;
        return 0;
    } else {
        int height_left = NONE, height_right = NONE; 
        if (node.left != NONE) height_left = walk_height(nodes, node.left);
        if (node.right != NONE) height_right = walk_height(nodes, node.right);
        const int height_tmp = std::max(height_left, height_right) + 1;
        node.height = height_tmp;
        return height_tmp;
    }
}

void family(Nodes& nodes) {
    for (auto iter = nodes.begin(); iter != nodes.end(); ++iter) {
        const int id = iter->first;
        Node& node = iter->second;

        if (node.left != NONE) {
            nodes[node.left].parent = id;
            node.degree += 1;
        }
        if (node.right != NONE) {
            nodes[node.right].parent = id;
            node.degree += 1;
        }
        if (node.left != NONE && node.right != NONE) {
            nodes[node.left].sibling = node.right;
            nodes[node.right].sibling = node.left;
        }
    }
}

int set_type(Nodes& nodes) {
    int root;
    for (auto iter = nodes.begin(); iter != nodes.end(); ++iter) {
        const int id = iter->first;
        Node& node = iter->second;
        if (node.parent == NONE) {
            root = id;
            node.type = ROOT;
        } else if (node.left == NONE && node.right == NONE) {
            node.type = LEAF;
            node.height = 0;
        }
    }
    return root;
}

void construct(Nodes& nodes) {
    family(nodes);
    const int root = set_type(nodes);
    walk_depth(nodes, root, 0);
    walk_height(nodes, root);
}

void print_nodes(Nodes& nodes) {
    for (auto member : nodes) {
        Node node = member.second;
        std::cout << "node " << member.first << ": parent = " << node.parent
                  << ", sibling = " << node.sibling
                  << ", degree = " << node.degree << ", depth = " << node.depth
                  << ", height = " << node.height << ", "
                  << type_num_to_string(node.type) << std::endl;
    }
}

int main() {
    int n;
    std::cin >> n;

    Nodes nodes;
    for (int i = 0; i < n; ++i) {
        int id, left, right;
        std::cin >> id >> left >> right;
        Node node{};
        node.left = left;
        node.right = right;
        nodes.insert(std::pair<int, Node>(id, node));
    }

    construct(nodes);
    print_nodes(nodes);
}


Measured memory_bytes: 3196