#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <numeric>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#include <unordered_map>
#include <unordered_set>

using namespace std;

#define ll long long
#define ull unsigned long long
#define INF (1 << 30)
#define LLINF (1LL << 62)
#define MOD7 1000000007
#define MOD9 1000000009
#define eps 1e-9
#define P pair<int, int>
#define pii pair<int, int>
#define pll pair<ll, ll>
#define pul pair<ull, ull>
#define all(a) (a).begin(), (a).end()
#define FOR(i,a,b) for (int i=(a);i<(b);++i)
#define RFOR(i,a,b) for (int i=(b)-1;i>=(a);--i)
#define REP(i,n) for (int i=0;i<(n);++i)
#define RREP(i,n) for (int i=(n)-1;i>=0;--i)

void YES() { cout << "YES\n"; }
void NO() { cout << "NO\n"; }
void Yes() { cout << "Yes\n"; }
void No() { cout << "No\n"; }

template<class T>
class BinaryTree {
public:
	class Node {
	public:
		int parent = -1;
		int left;
		int right;

		int sibling;
		int degree;
		int depth;
		int height;
		T value;

		string getName() {
			if (parent == -1)
				return "root";
			else if (left == -1 && right == -1)
				return "leaf";
			else
				return "internal node";
		}
	};

	vector<Node> data;
	int root = -1;
	int _size = 1;

	BinaryTree() {
		data.resize(1);
	}

	Node operator[](int id) {
		return data[id];
	}

	void resize(int size) {
		if (size > _size) {
			while (_size < size) {
				_size *= 2;
			}
			data.resize(_size);
		}
	}

	void addNode(int id, int left, int right, T value) {
		resize(id + 1);

		if (root == -1) {
			root = id;
			data[id].parent = -1;
		}

		data[id].left = left;
		data[id].right = right;
		data[id].value = value;

		resize(left + 1);
		if (left != -1)
			data[left].parent = id;
		resize(right + 1);
		if (right != -1)
			data[right].parent = id;

		if (root == left || root == right) {
			while (data[root].parent != -1) {
				root = data[root].parent;
			}
		}
	}

	void construct() {
		if (root == -1) {
			return;
		}
		getSibling(root);
		getDegree(root);
		getDepth(root, 0);
		getHeight(root);
	}

	void getSibling(int id) {
		if (data[id].parent != -1) {
			int parent = data[id].parent;
			if (data[parent].left == id)
				data[id].sibling = data[parent].right;
			else if (data[parent].right == id)
				data[id].sibling = data[parent].left;
			else
				data[id].sibling = -1;
		}
		else
			data[id].sibling = -1;

		if (data[id].left != -1)
			getSibling(data[id].left);
		if (data[id].right != -1)
			getSibling(data[id].right);
	}

	void getDegree(int id) {
		int degree = 0;
		if (data[id].left != -1) {
			degree++;
			getDegree(data[id].left);
		}
		if (data[id].right != -1) {
			degree++;
			getDegree(data[id].right);
		}
		data[id].degree = degree;
	}

	void getDepth(int id, int depth) {
		data[id].depth = depth;
		if (data[id].left != -1)
			getDepth(data[id].left, depth + 1);
		if (data[id].right != -1)
			getDepth(data[id].right, depth + 1);
	}

	int getHeight(int id) {
		int h1 = -1, h2 = -1, height;
		if (data[id].left != -1)
			h1 = getHeight(data[id].left);
		if (data[id].right != -1)
			h2 = getHeight(data[id].right);

		height = max(h1, h2) + 1;
		data[id].height = height;
		return height;
	}
};

int main() {
	BinaryTree<int> tree;
	int n, id, l, r;
	cin >> n;
	for (int i = 0; i < n; ++i) {
		cin >> id >> l >> r;
		tree.addNode(id, l, r, 0);
	}

	tree.construct();

	for (int i = 0; i < n; ++i) {
		printf("node %d: parent = %d, ", i, tree[i].parent);
		printf("sibling = %d, degree = %d, ", tree[i].sibling, tree[i].degree);
		printf("depth = %d, height = %d, ", tree[i].depth, tree[i].height);
		printf("%s\n", tree[i].getName().c_str());
	}

	return 0;
}

Measured memory_bytes: 3284