#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

class Node {
public:
	int ID;
	int child1; 
	int child2;
	int parent;
	int depth;
	int height;
	int sibling;
public:
	Node() {}
	Node(int ID, int child1, int child2) { this->ID = ID; this->child1 = child1; this->child2 = child2; }
	bool operator<(const Node& rhs) { return this->ID < rhs.ID; }
	bool operator<=(const Node& rhs) { return this->ID <= rhs.ID; }
	bool operator>(const Node& rhs) { return this->ID > rhs.ID; }
	bool operator>=(const Node& rhs) { return this->ID >= rhs.ID; }
	bool operator==(const Node& rhs) { return this->ID == rhs.ID; }
	bool operator!=(const Node& rhs) { return this->ID != rhs.ID; }
	int getDegree() {
		if (this->child1 == -1 && this->child2 == -1) return 0;
		else if (this->child1 >= 0 && this->child2 >= 0) return 2;
		else return 1;
	}
	std::string getType() {
		if (this->parent == -1) return "root";
		else if (this->getDegree() == 0) return "leaf";
		else return "internal node";
	}
	~Node(){}
};

int max(int x, int y)
{
	return x>y ? x : y;
}

void compute_pds(Node* tree, int index_of_node)
{
	int c1 = tree[index_of_node].child1;
	if (c1 >= 0) {
		tree[c1].parent = tree[index_of_node].ID;
		tree[c1].depth  = tree[index_of_node].depth + 1;
		compute_pds(tree, c1);
	}
	
	int c2 = tree[index_of_node].child2;
	if (c2 >= 0) {
		tree[c2].parent = tree[index_of_node].ID;
		tree[c2].depth  = tree[index_of_node].depth + 1;
		compute_pds(tree, c2);
	}
	
	if (c1 >= 0 && c2 >= 0) {
		tree[c1].sibling = c2;
		tree[c2].sibling = c1;
	} else if (c1 >= 0 && c2 < 0) {
		tree[c1].sibling = -1;
	} else if (c2 >= 0) {
		tree[c2].sibling = -1;
	}
}

void update_height(Node* tree, int node, int h)
{
	tree[node].height = max(tree[node].height, h);
	
	if (tree[node].parent >= 0) {
		update_height(tree, tree[node].parent, h+1);
	}
}

int main()
{
	int n;
	std::cin >> n;
	
	Node* bintree = new Node[n];
	
	for (int i=0; i<n; i++) {
		int ID;
		int c1, c2;
		std::cin >> ID >> c1 >> c2;
		bintree[i] = Node(ID, c1, c2);
	}
	
	std::sort(bintree, bintree + n);
	
	bool* isRoot = new bool[n];
	for (int i=0; i<n; i++) isRoot[i] = true;
	
	for (int i=0; i<n; i++) {
		if (bintree[i].child1 >= 0) isRoot[bintree[i].child1] = false;
		if (bintree[i].child2 >= 0) isRoot[bintree[i].child2] = false;
	}
	
	// search the index of the root node
	int index_of_root = -1;
	for (int i=0; i<n; i++) {
		if (isRoot[i]) { index_of_root = i; break; }
	}
	
	bintree[index_of_root].parent  = -1;
	bintree[index_of_root].depth   = 0;
	bintree[index_of_root].sibling = -1;
	
	// std::cout << "root node = " << rtree[index_of_root].ID << std::endl;
	
	// comput parent, depth, sibling
	compute_pds(bintree, index_of_root);
	
	//compute height
	for (int i=0; i<n; i++) bintree[i].height = 0;
	
	for (int i=0; i<n; i++) {
		if (bintree[i].getType() == "leaf") update_height(bintree, i, 0);
	}
	
	// output
	for (int i=0; i<n; i++) {
		std::cout << "node " << bintree[i].ID << ": parent = " << bintree[i].parent << ", sibling = " << bintree[i].sibling 
			  	  << ", degree = " << bintree[i].getDegree() << ", depth = " << bintree[i].depth << ", height = " << bintree[i].height
				  << ", " << bintree[i].getType() << std::endl;
	}
	
	delete[] isRoot;
	delete[] bintree;
	
	return 0;
}




Measured memory_bytes: 3184