#include<iostream>
#include<string>
using namespace std;

class Tree;

class Node
{
public:
	enum TYPE { NONE, ROOT, INTERNAL_NODE, LEAF };
	TYPE type;
	Node(Tree* T, int ID, Node* PARENT, int LEFT, int RIGHT)
	{
		t = T;
		id = ID;
		parent = PARENT;
		left = LEFT;
		right = RIGHT;
	}
	Tree* t = 0;
	int id, left, right,c, depth = -1, child_left = -1;
	Node* parent;
};

class Tree
{
public:
	Tree()
	{
		for (int i = 0; i < 100000; i++)nodes[i] = 0;
	}
	~Tree()
	{
		for (int i = 0; i < 100000; i++)
		{
			if (nodes[i] != 0)
			{
				delete nodes[i];
			}
		}
	}
	Node* nodes[100000];
	void CreateNode(int ID, Node* PARENT, int LEFT, int RIGHT)
	{
		nodes[ID] = new Node(this, ID, PARENT, LEFT, RIGHT);
	}
	int GetDepth(Node* NODE)
	{
		if (NODE->type == Node::ROOT)return 0;
		else if (NODE->left != -1)
		{
			if (nodes[NODE->left]->depth != -1)return nodes[NODE->left]->depth;
			return GetDepth(nodes[NODE->left]);
		}
		else
		{
			if (NODE->parent->depth != -1)return NODE->parent->depth+1;
			return GetDepth(NODE->parent) + 1;
		}
	}
	void Show(Node* node)
	{
		string text;
		if (node->parent != NULL)printf("node %d: parent = %d, depth = %d, ", node->id, node->parent->id, node->depth);
		else printf("node %d: parent = %d, depth = %d, ", node->id, -1, node->depth);
		switch (node->type)
		{
		case Node::ROOT:
			text = "root";
			break;
		case Node::INTERNAL_NODE:
			text = "internal node";
			break;
		case Node::LEAF:
			text = "leaf";
			break;
		}
		printf("%s, ", text.c_str());
		printf("[");
		int next = node->child_left;
		if (next != -1)
		{
			while (1)
			{
				if (next == -1)break;
				if (nodes[next]->right == -1)printf("%d", next);
				else printf("%d, ", next);
				next = nodes[next]->right;
			}
		}
		printf("]\n");
	}
	void SetRoot()
	{
		for (int i = 0; i < 100000; i++)
		{
			if (nodes[i] == 0)break;
			if (nodes[i]->parent == 0)
			{
				nodes[i]->type = Node::ROOT;
				break;
			}
		}
	}
};

int main()
{
	Tree T;
	int n;
	int input[100000];
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
	{
		int id,c;
		scanf("%d", &id);
		scanf("%d", &c);
		if (T.nodes[id] == 0)
		{
			T.CreateNode(id, 0, -1, -1);
			T.nodes[id]->c = c;
		}
		else
		{
			T.nodes[id]->c = c;
		}
		for (int l = 0; l < c; l++)
		{
			scanf("%d",&input[l]);
		}
		if (c == 0)T.nodes[id]->type = Node::LEAF;
		else T.nodes[id]->type = Node::INTERNAL_NODE;
		for (int l = 0; l < c; l++)
		{
			if (T.nodes[input[l]] == 0)
			{
				if (c == 1)
				{
					T.CreateNode(input[l], T.nodes[id], -1, -1);
					T.nodes[id]->child_left = input[l];
				}
				else if (l == 0)
				{
					T.CreateNode(input[l], T.nodes[id], -1, input[l + 1]);
					T.nodes[id]->child_left = input[l];
				}
				else if (l == c - 1)
				{
					T.CreateNode(input[l], T.nodes[id], input[l - 1], -1);
				}
				else
				{
					T.CreateNode(input[l], T.nodes[id], input[l - 1], input[l + 1]);
				}
			}
			else
			{
				if (c == 1)
				{
					T.nodes[id]->child_left = input[l];
					T.nodes[input[l]]->left = -1;
					T.nodes[input[l]]->right = -1;
				}
				else if (l == 0)
				{
					T.nodes[id]->child_left = input[l];
					T.nodes[input[l]]->left = -1;
					T.nodes[input[l]]->right = input[l+1];
				}
				else if (l == c - 1)
				{
					T.nodes[input[l]]->left = input[l - 1];
					T.nodes[input[l]]->right = -1;
				}
				else
				{
					T.nodes[input[l]]->left = input[l - 1];
					T.nodes[input[l]]->right = input[l+1];
				}
				T.nodes[input[l]]->parent = T.nodes[id];
				if(T.nodes[input[l]]->c==0)T.nodes[input[l]]->type = Node::LEAF;
				else   T.nodes[input[l]]->type = Node::INTERNAL_NODE;
			}
		}
	}
	T.SetRoot();
	for (int i = 0; i < 100000; i++)
	{
		if (T.nodes[i] == 0)break;
		T.nodes[i]->depth = T.GetDepth(T.nodes[i]);
		T.Show(T.nodes[i]);
	}
	return 0;
}

Measured memory_bytes: 10608