#include<stdio.h>
#define MAX 100005
#define NIL -1
#define TRUE 1
#define FALSE 0

/*
	p: parent
	l: left-child
	r: right sibling
*/

int n;
struct Node {
	int p, l, r;
};
int found;
int root;

struct Node T[MAX];	// Tree

int dfs (int curr, int depth )
{
	if (found == TRUE ) return depth;
	if (curr == root ){
		found = TRUE;
		return depth;
	} // end if

	return dfs (T[curr].p, depth + 1 );
}

int calc_depth (int node )
{
	int i;
	found = FALSE;
	if (root == NIL ){
		for (i = 0; i < n; i++ ){
			if (T[i].p == NIL ){
				root = i;
				break;
			} // end if
		} // end for
	} // end if

	int res = dfs (node, 0 );

	return res;	
}

int main()
{
	int i, j, d, v, c, l;
	root = NIL;
	scanf("%d", &n );

	for (i = 0; i < n; i++ ){
		T[i].p = T[i].l = T[i].r = NIL;
	} // end for

	for (i = 0; i < n; i++ ){
		scanf ("%d %d", &v, &d );	// v: 節点の番号 d: 次数 
		for (j = 0; j < d; j++ ){
			scanf ("%d", &c );	// c: 子の節点番号 
			if (j == 0 ){
				T[v].r = c;
			}else{
				T[l].l = c;
			} // end if
			l = c;
			T[l].p = v;
		} // end for
	} // end for

	for (i = 0; i < n; i++ ){
		printf ("node %d: parent = %d, depth = %d, ", i, T[i].p, calc_depth(i ) );
		if (T[i].p == NIL ){		// case root 
			printf ("root, [" );
			int next = T[i].r;
			while (next != NIL ){
				printf ("%d", next );
				next = T[next].l;
				if (next != NIL ) printf (", " );
			} // end while
			printf ("]\n" );
		}else
		if (T[i].r == NIL ){		// case leaf
			printf ("leaf, []\n" );
		}else{				// case internal node
			printf ("internal node, [" );
			int next = T[i].r;
			while (next != NIL ){
				printf ("%d", next );
				next = T[next].l;
				if (next != NIL ) printf (", " );
			} // end while
			printf ("]\n" );
		} // end if
	} // end for		

	return 0;
}