#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <vector>
#include <stack>
#include <climits>
#include <utility>
#include <cmath>
#include <cstddef>

using namespace std;
typedef long long ll;
#define LN printf("\n")
#define OB printf(" ")
#define rep(i,n,m) for(int  i=n;i<=m;i++)
#define per(i,n,m) for(int i=n;i>=m;i--)
inline void scan(int&x){scanf("%d", &x);}inline void scan(ll&x){scanf("%lld",&x);}inline void scan(double&x){scanf("%lf",&x);}inline void scan(string&x){const char *str;scanf("%s",str);x = string(str);}inline void scan(char&ch){scanf("%c",&ch);}
inline void print(const int&x){printf("%d",x);}inline void print(const ll&x) {printf("%lld",x);}inline void print(const double&x) {printf("%lf",x);}inline void print(const string&x){ const char *str=x.c_str();printf("%s",str);}inline void print(const char&x) {printf("%c",x);}
template<class T> inline void printob(const T&x){print(x);OB;}template<class T> inline void println(const T&x){print(x);LN;}inline void printob(const string&x){const char *str=x.c_str();printf("%s",str); OB;}inline void println(const string&x){const char *str=x.c_str();printf("%s",str); LN;}
template<class T>inline T*scanarray(int&n){T*a=0;scan(n);a=new T[n];if(a==0)exit(1);rep(i,0,n-1){ll tmp;scanf("%lld",&tmp);a[i]=(T)tmp;}return a;}
template<class T>inline void printarray(T*a,int n){if(n==1)println(a[0]);else{rep(i,0,n-2){printob(a[i]);}println(a[n-1]);}}
template<class T>inline T*copyarray(int*a,int n){T*b=0;b=new T[n];if(b==0)exit(1);rep(i,0,n-1)b[i]=a[i];return b;}
/*
scan, print, println    : int, ll, double, string, char
(*)scanarrayはすべての入力の型が同一でないとバグるので注意。 2 5.3 9 8　とかはダメ
stringについては入出力の際はchar*で行い、コード中で便利のためにstringを使えるようにしている
*/
// const ll MaxN = 0;
// ll A[MaxN];
#define NIL (void*)(-1)


template<class S>
class List{
    template<class T>
    class Node {
    public:
        Node<T> *prev;
        Node<T> *next;
        T data;

        Node(Node<T>* prev, Node<T>* next, T data): prev(prev), next(next), data(data) {

        }
        ~Node() {

        }
        void printDataob() {printob(data);}
        void printDataln() {println(data);}


    };

private:
    Node<S>* head;
    Node<S>* tail;
    // Node<S>* NIL = nullptr;
public:

    // List *NIL = nullptr;

    List():head(NIL), tail(NIL) {
        println("List constructor called");
    }

    ~List() {
        Node<S>* del = head;
        Node<S>* delnext;
        while(del != NIL) {
            delnext = del->next;
            delete del;
            del = delnext;
        }
    }

    void insertHead(S data){
        if(tail == NIL) {
            head = new Node<S>(NIL,NIL,data);
            tail = head;
        }
        else {
            head->prev = new Node<S>(NIL,head,data);
            head = head->prev;
        }
    }

    void printAll() {
        Node<S> *idx = head;

        while(idx->next != NIL) {
            idx->printDataob();
            idx = idx->next;
        }
        idx->printDataln();
    }
    // Node* insertTail(S data);

};

class Node {
    public:
        // Node* NIL = nullptr;

        int no;
        int childsize;
        Node* parent;
        int* childNodes;
        Node** children;

        Node(int no, int childsize, Node* parent):
        no(no), childsize(childsize), parent(parent)
         {
             children = new Node*[childsize];
             childNodes = new int[childsize];
        }

        ~Node() {
            delete [] childNodes;
            delete [] children;
        }

        void printData() {
            print("parent = ");
            if(parent == NIL) print("-1");
            else print(parent->no);
            printob(",");

            print("depth = "); print(getDepth()); printob(",");

            if(parent == NIL) {
                printob("root,");
            }
            else if(childsize == 0) {
                printob("leaf,");
            } else {
                printob("internal node,");
            }

            printChildren();

            // printob("children: ");
            // if(childsize>0) {
            //     printarray(childNodes,childsize);
            // }
            // else {
            //     println("No children");
            // }
        }

        int getDepth() {
            int count = 0;
            for(Node *tmp = parent; tmp!=NIL; tmp=tmp->parent) {
                count++;
            }
            return count;
        }

        void printChildren() {
            print("[");
            printarrayMod(childNodes,childsize);
            println("]");
        }

        template<typename T>
        void printarrayMod(T*a,int n){
            if(n==0) {
                //do nothing
            }
            else if(n==1)print(a[0]);
            else {
                rep(i,0,n-2) {
                    print(a[i]); printob(",");
                }
                print(a[n-1]);
            }
        }

    };
class Tree {


private:
    int nsize;
    Node* root;
    Node **nodes;
    int count;

public:

    // Tree *NIL = nullptr;

    Tree(int nsize):nsize(nsize), count(0) {
        nodes = new Node*[nsize];
    }

    ~Tree() {
        delete [] nodes;
    }
    void insertNode(Node* node, int no) {
        nodes[no] = node;
    }
    void makeTree() {
        //set parent
        rep(i,0,nsize-1) {
            int childsizeOfi = nodes[i]->childsize;
            if(childsizeOfi>0) {
                rep(j,0,childsizeOfi-1) {
                    nodes[nodes[i]->childNodes[j]]->parent = nodes[i];
                }
            }
            else {
                //do nothing
            }
        }

    }
    void printAll() {
        rep(i,0,nsize-1) {
            printf("node %d: ", i); nodes[i]->printData();
        }
    }

    int getCount() {
        return count;
    }
    int getNsize() {
        return nsize;
    }

};

int main() {
    //TEMPLATE
    int n;
    scan(n);
    // println(n);

    Tree tree(n);
    if(n>0) {
        rep(i,0,n-1) {
            int nodeNo; scan(nodeNo);
            // println(nodeNo);
            int childsize; scan(childsize);
            // println(childsize);
            Node* newNode = new Node(nodeNo,childsize,(Node*)NIL);
            rep(j,0,childsize-1) {
                int childNodeNo;
                scan(childNodeNo);
                // println(childNodeNo);
                newNode->childNodes[j] = childNodeNo;
            }
            tree.insertNode(newNode,nodeNo);
        }
        //make Tree
        tree.makeTree();
        // println(tree.getCount());
        // println(tree.getNsize());

        }

    tree.printAll();



    return 0;
}



Measured memory_bytes: 15176