#include <bits/stdc++.h>
#include <cmath>

using namespace std;
typedef long long ll;
//typedef unsigned long long ll;

//#define rep(i, n) for (int i = 0; i < (n); ++i)
#define rep(i, n) for (ll i = 0; i < (n); ++i)
//#define sz(x) ll(x.size())
//typedef pair<ll, int> P;
//typedef pair<ll, ll> P;
//const double INF = 1e10;
//const ll INF = LONG_LONG_MAX / 10;
//const ll INF = 1e15;
const ll MINF = LONG_LONG_MIN;
const int INF = INT_MAX / 10;
#define cmin(x, y) x = min(x, y)
#define cmax(x, y) x = max(x, y)

bool contain(set<char> &s, int a) { return s.find(a) != s.end(); }

//ifstream myfile("C:\\Users\\riku\\Downloads\\0_00.txt");
//ofstream outfile("log.txt");
//outfile << setw(6) << setfill('0') << prefecture << setw(6) << setfill('0') << rank << endl;
// std::cout << std::bitset<8>(9);

typedef pair<int, int> P;

void print_line(vector<P> &line) {
    if (line.size() == 0ll) {
        cout << endl;
        return;
    }
    for (ll i = 0; i < line.size(); i++) {
        cout << line[i].second;
        if (i == line.size() - 1) cout << endl;
        else cout << ' ';
    }
}


typedef priority_queue<long long, vector<long long>, greater<long long> > PQ_ASK;
const int mod = 1000000007;

struct Child {
    int id, parent, depth, sibling;
};

int dfs(int from, vector<P> &tos, vector<int> &heights) {
    assert(from != -1);
    assert(from != -1);
    P to = tos[from];
    int height = 0;
    if (to.first != -1) {
        int nh = dfs(to.first, tos, heights);
        cmax(height, nh);
    }
    if (to.second != -1) {
        int nh = dfs(to.second, tos, heights);
        cmax(height, nh);
    }
    heights[from] = height;
    return height + 1;

}

void bfs(int n, vector<P> &tos, vector<int> &parents, vector<int> &depths, vector<int> &siblings, vector<int> &height) {

    set<int> s;
    rep(i, n) s.insert(i);
    rep(i, n) {
        s.erase(tos[i].first);
        s.erase(tos[i].second);
    }
    int root = *s.begin();


    queue<Child> q;
    q.push(Child{root, -1, 0, -1});

    while (!q.empty()) {
        Child parent = q.front();
        q.pop();

        parents[parent.id] = parent.parent;
        depths[parent.id] = parent.depth;
        siblings[parent.id] = parent.sibling;

        int to1 = tos[parent.id].first;
        int to2 = tos[parent.id].second;
        if (to1 != -1) {
            Child next1{to1, parent.id, parent.depth + 1, to2};
            q.push(next1);
        }
        if (to2 != -1) {
            Child next2{to2, parent.id, parent.depth + 1, to1};
            q.push(next2);
        }
    }

    dfs(root, tos, height);

}

string get_types(int i, vector<int> &parents, vector<P> &tos) {
    if (parents[i] == -1) return "root";
    if (tos[i] == P(-1, -1)) return "leaf";
    return "internal node";

}

string get_children(int i, vector<int> &tos) {
    if (tos.empty()) {
        return "[]";
    }

    ostringstream oss;
    oss << "[";
    for (int i = 0; i < tos.size(); i++) {
        oss << tos[i];
        if (i == tos.size() - 1) oss << "]";
        else oss << ", ";
    }
    return oss.str();
}

int get_degree(P p) {
    if (p == P(-1, -1)) return 0;
    if (p.first == -1 || p.second == -1) return 1;
    return 2;
}

int main() {
    int n;
    cin >> n;

    vector<P> tos(n);

    rep(i, n) {
        int j;
        cin >> j;
        assert(j < n);
        cin >> tos[j].first >> tos[j].second;
    }

    vector<int> parents(n);
    vector<int> depths(n);
    vector<int> siblings(n);
    vector<int> heights(n);

    bfs(n, tos, parents, depths, siblings, heights);

    rep(i, n) {
        string type = get_types(i, parents, tos);

        printf("node %d: parent = %d, sibling = %d, degree = %d, depth = %d, height = %d, %s\n",
               (int) i,
               parents[i],
               siblings[i],
               get_degree(tos[i]),
               depths[i],
               heights[i],
               type.c_str()
        );
    }

}




Measured memory_bytes: 3288