Problem: cf1879_e
Difficulty: easy
Categories: graph, greedy
Time limit: 2000 ms, memory limit: 512 MB

This is an interactive problem. Remember to flush your output while communicating with the testing program. You may use fflush(stdout) in C++, system.out.flush() in Java, stdout.flush() in Python or flush(output) in Pascal to flush the output. If you use some other programming language, consult its documentation. You may also refer to the guide on interactive problems: [link omitted].

You are given a tree on $n$ vertices; vertex $1$ is the root of the tree. For every $i \in [2, n]$, the parent of the $i$-th vertex is $p_i$, and $p_i < i$.

You have to color all edges of the tree using the minimum possible number of colors such that you can win the game on that tree (every edge should be painted into exactly one color).

The game we're going to play will be conducted as follows. After you paint the edges and print their colors, the jury will place a chip into one of the vertices of the tree (except for the root). Your goal is to move this chip to the root in exactly $d$ moves, where $d$ is the distance from the root to that vertex (the distance is equal to the number of edges on the path). If the chip reaches the root in $d$ moves, you win. Otherwise, you lose.

The jury won't tell you where the chip is located. You won't even know the value of $d$ in advance. However, at the start of each move, you will be told how many edges of each color are incident to the current vertex (this includes both the edge leading up the tree and the edges leading away from the root). You have to choose one of these colors, and the chip will be moved along the edge of the chosen color (if there are multiple edges with that color incident to the current vertex, the jury gets to choose one of them). After the chip is moved, you will be told the same information about the current vertex again, and the game continues, until you either reach the root, or you make $d$ moves without reaching the root.

The interactor for this problem is adaptive. It means that both the starting vertex and the current vertex are not fixed and may change "on the run" depending on the output of your program. However, the state of the game will always be consistent with the information you are given: there will always be at least one starting vertex and at least one path of your chip from that vertex consistent with both the information about the colors you receive and the colors you've chosen during the moves.

Input

The first line contains one integer $n$ ($3 \le n \le 100$) — the number of vertices in the tree.

The second line contains $n-1$ integers $p_2, p_3, \dots, p_n$ ($1 \le p_i < i$), where $p_i$ is the parent of the $i$-th vertex in the tree.

Interaction

First, you have to print the coloring of the edges you've chosen as follows:

* in the first line, print one integer $k$ ($1 \le k \le n - 1$) — the number of colors you are using;
* in the second line, print $n-1$ integers $c_2, c_3, \dots, c_n$ ($1 \le c_i \le k$), where $c_i$ should be the color of the edge connecting $p_i$ with $i$.

Then, the game begins. At the start of each move, the jury program prints one of the following:

* one integer $1$ on a separate line, indicating that the chip has reached the root and you won;
* one integer $-1$ on a separate line, indicating that either you didn't reach the root in $d$ moves and lost, or you have done something incorrect (either the coloring you provided didn't meet the constraints, or your previous move is impossible);
* or one integer $0$ on a separate line, followed by a line containing $k$ integers $e_1, e_2, \dots, e_k$, where $e_i$ is the number of edges with color $i$ incident to the current vertex.

If you receive $1$ or $-1$, your program should terminate immediately, otherwise the verdict for your submission may be undefined. If you receive $0$ followed by $k$ integers $e_1, e_2, \dots, e_k$, you have to print one integer indicating the color you choose during the move (of course, $e_i$ for that color should not be equal to $0$).

Don't forget to flush the output every time you print something!

Examples

Input

```
5
1 1 1 1
0
1
1
```

Output

```
1
1 1 1 1
1
```

Input

```
4
1 2 3
0
0 1 0
0
1 1 0
0
1 0 1
1
```

Output

```
3
3 1 2
2
1
3
```

Input

```
3
1 2
0
1 1
1
```

Output

```
2
1 2
1
```

Note

In the first example, every vertex from $2$ to $n$ is connected to the root. So, we can paint all edges into the same color $1$, and when the game starts, there will be only one edge incident to the current vertex (and it will lead to the root).

In the second example, the tree is a path of $4$ vertices. We have to paint its edges into different colors, because it can be shown that we don't have a winning strategy with just two colors.

Non-adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;


static long long queries = 0;
static long long query_limit = 0;


static void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {
        
    }
}


static void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}

int main(int argc, char* argv[]) {
    
    
    registerInteraction(argc, argv);
    atexit(log_metrics);

    
    int n = inf.readInt(3, 100, "n");
    vector<int> parent(n + 1);
    vector<int> depth(n + 1);

    
    for (int i = 2; i <= n; i++) {
        parent[i] = inf.readInt(1, i - 1, format("p_%d", i));
    }

    
    depth[1] = 0;
    for (int i = 2; i <= n; i++) {
        depth[i] = depth[parent[i]] + 1;
    }

    
    int target = inf.readInt(2, n, "target");

    
    query_limit = depth[target];

    
    cout << n << endl;
    for (int i = 2; i <= n; i++) {
        cout << parent[i] << (i == n ? "" : " ");
    }
    cout << endl; 

    
    
    int k = ouf.readInt(1, n - 1, "k");
    vector<int> colors(n + 1); 
    for (int i = 2; i <= n; i++) {
        colors[i] = ouf.readInt(1, k, format("c_%d", i));
    }

    
    
    vector<vector<pair<int, int>>> adj(n + 1);
    for (int i = 2; i <= n; i++) {
        int p = parent[i];
        int c = colors[i];
        adj[i].push_back({p, c});
        adj[p].push_back({i, c});
    }

    
    int curr = target;
    int moves = 0;

    
    while (true) {
        
        if (curr == 1) {
            cout << "1" << endl;
            finish(_ok, format("Reached root in %d moves.", moves));
        }

        
        if (moves >= query_limit) {
            cout << "-1" << endl;
            finish(_wa, format("Failed to reach root in %d moves (target %d).", moves, query_limit));
        }

        
        vector<int> counts(k + 1, 0);
        for (auto& edge : adj[curr]) {
            int c = edge.second;
            if (c >= 1 && c <= k) counts[c]++;
        }

        
        cout << "0" << endl;
        for (int i = 1; i <= k; i++) {
            cout << counts[i] << (i == k ? "" : " ");
        }
        cout << endl; 

        
        int choice = ouf.readInt(1, k, "choice");
        queries++;

        
        if (counts[choice] == 0) {
            cout << "-1" << endl;
            finish(_wa, format("Selected color %d not present at vertex %d.", choice, curr));
        }

        
        
        vector<int> candidates;
        for (auto& edge : adj[curr]) {
            if (edge.second == choice) {
                candidates.push_back(edge.first);
            }
        }

        
        
        
        int p = parent[curr];
        int next_node = -1;
        bool parent_is_cand = false;
        
        for (int cand : candidates) {
            if (cand == p) parent_is_cand = true;
        }

        if (parent_is_cand && candidates.size() == 1) {
            next_node = p;
        } else {
            
            int best_child = 2000000000;
            for (int cand : candidates) {
                if (cand != p) {
                    best_child = min(best_child, cand);
                }
            }
            next_node = best_child;
        }

        curr = next_node;
        moves++;
        
        
        if (moves % 5 == 0) log_metrics();
    }

    return 0;
}


Adaptive interactor (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

static long long queries = 0;
static long long query_limit = 0;


void log_metrics() {
    try {
        tout << "queries=" << queries << endl;
        tout << "query_limit=" << query_limit << endl;
    } catch (...) {}
}


void finish(TResult verdict, const string& msg) {
    log_metrics();
    quitf(verdict, "%s", msg.c_str());
}


int n;
vector<int> p; 
vector<vector<int>> adj; 
vector<int> edge_col; 
int k_colors;


vector<int> candidates;




int get_current(int start, int steps) {
    int curr = start;
    for (int i = 0; i < steps; ++i) {
        if (curr == 1) return 1;
        curr = p[curr];
    }
    return curr;
}


vector<int> get_obs(int u) {
    vector<int> counts(k_colors + 1, 0);
    
    if (u != 1) {
        int c = edge_col[u];
        if (c >= 1 && c <= k_colors) counts[c]++;
    }
    
    for (int v : adj[u]) {
        int c = edge_col[v];
        if (c >= 1 && c <= k_colors) counts[c]++;
    }
    return counts;
}

int main(int argc, char** argv) {
    registerInteraction(argc, argv);
    atexit(log_metrics);

    
    
    n = inf.readInt(3, 100, "n");
    p.resize(n + 1);
    adj.resize(n + 1);
    for (int i = 2; i <= n; i++) {
        p[i] = inf.readInt(1, i - 1, "p_i");
        adj[p[i]].push_back(i);
    }
    
    
    query_limit = n; 
    
    
    cout << n << endl;
    for (int i = 2; i <= n; i++) {
        cout << p[i] << (i == n ? "" : " ");
    }
    cout << endl; 

    
    if (!(cin >> k_colors)) finish(_pe, "Failed to read k");
    if (k_colors < 1 || k_colors > n - 1) finish(_wa, "Invalid k");
    
    edge_col.resize(n + 1);
    for (int i = 2; i <= n; i++) {
        if (!(cin >> edge_col[i])) finish(_pe, "Failed to read colors");
        if (edge_col[i] < 1 || edge_col[i] > k_colors) finish(_wa, "Color out of range");
    }

    
    for (int i = 2; i <= n; i++) candidates.push_back(i);

    
    while (true) {
        
        vector<int> active;
        vector<int> winners;
        for (int s : candidates) {
            int curr = get_current(s, queries);
            if (curr == 1) winners.push_back(s);
            else active.push_back(s);
        }

        
        if (active.empty()) {
            if (!winners.empty()) {
                cout << "1" << endl;
                finish(_ok, "Solved");
            } else {
                
                cout << "-1" << endl;
                finish(_wa, "No valid candidates left");
            }
        }
        candidates = active;

        
        if (queries > 2 * n + 20) finish(_pe, "Query limit exceeded");

        
        map<vector<int>, vector<int>> groups;
        for (int s : candidates) {
            int curr = get_current(s, queries);
            groups[get_obs(curr)].push_back(s);
        }

        
        
        vector<int> best_obs;
        vector<int> best_group;
        for (auto& kv : groups) {
            if (kv.second.size() > best_group.size()) {
                best_group = kv.second;
                best_obs = kv.first;
            }
        }
        candidates = best_group;

        
        cout << "0" << endl;
        for (int i = 1; i <= k_colors; i++) {
            cout << best_obs[i] << (i == k_colors ? "" : " ");
        }
        cout << endl; 

        
        int c;
        if (!(cin >> c)) finish(_pe, "Failed to read color choice");
        if (c < 1 || c > k_colors) finish(_wa, "Invalid color choice");
        if (best_obs[c] == 0) finish(_wa, "Chosen color not in observation");

        
        
        
        
        vector<int> next_candidates;
        for (int s : candidates) {
            int curr = get_current(s, queries);
            
            
            int pc = edge_col[curr]; 
            bool parent_match = (pc == c);
            bool child_match = false;
            for (int v : adj[curr]) {
                if (edge_col[v] == c) {
                    child_match = true;
                    break;
                }
            }

            
            
            
            if (parent_match && !child_match) {
                next_candidates.push_back(s);
            }
        }

        if (next_candidates.empty()) {
            cout << "-1" << endl;
            finish(_wa, "Move leads to loss for all candidates (ambiguous or wrong direction)");
        }
        candidates = next_candidates;
        queries++;
    }

    return 0;
}


Test generator (C++):
#include "testlib.h"
#include <bits/stdc++.h>
using namespace std;

int main(int argc, char* argv[]) {
    registerGen(argc, argv, 1);

    
    string mode = opt<string>("mode", "non");
    ensuref(mode == "non" || mode == "adp", "Invalid mode: %s", mode.c_str());

    
    int seed_val = 0;
    if (argc > 1) {
        try {
            seed_val = stoi(argv[1]);
        } catch (...) {
            seed_val = 999;
        }
    }

    int n;
    vector<int> p; 

    
    
    auto edges_to_parents = [&](int size, const vector<pair<int,int>>& edges) {
        vector<vector<int>> adj(size + 1);
        for (auto& e : edges) {
            adj[e.first].push_back(e.second);
            adj[e.second].push_back(e.first);
        }

        vector<int> mapping(size + 1); 
        vector<int> result_p(size + 1);
        int timer = 0;
        queue<int> q;
        vector<bool> vis(size + 1, false);

        
        q.push(1);
        vis[1] = true;
        mapping[1] = ++timer;

        while (!q.empty()) {
            int u = q.front();
            q.pop();
            int u_label = mapping[u];

            for (int v : adj[u]) {
                if (!vis[v]) {
                    vis[v] = true;
                    mapping[v] = ++timer;
                    int v_label = mapping[v];
                    
                    result_p[v_label] = u_label;
                    q.push(v);
                }
            }
        }
        return result_p;
    };

    
    if (seed_val == 1) {
        
        n = 100;
        p.resize(n + 1);
        for (int i = 2; i <= n; i++) p[i] = 1;
    } else if (seed_val == 2) {
        
        n = 100;
        p.resize(n + 1);
        for (int i = 2; i <= n; i++) p[i] = i - 1;
    } else if (seed_val == 3) {
        
        n = 100;
        p.resize(n + 1);
        for (int i = 2; i <= n; i++) p[i] = i / 2;
    } else {
        
        n = rnd.next(3, 100);
        
        if (rnd.next(3) == 0) n = 100;

        int type = rnd.next(5);
        if (type == 0) {
            
            vector<int> prufer(n - 2);
            for (int i = 0; i < n - 2; i++) prufer[i] = rnd.next(1, n);

            vector<int> degree(n + 1, 1);
            for (int x : prufer) degree[x]++;

            set<int> leaves;
            for (int i = 1; i <= n; i++) if (degree[i] == 1) leaves.insert(i);

            vector<pair<int,int>> edges;
            for (int x : prufer) {
                int leaf = *leaves.begin();
                leaves.erase(leaves.begin());
                edges.push_back({leaf, x});
                degree[x]--;
                if (degree[x] == 1) leaves.insert(x);
            }
            edges.push_back({*leaves.begin(), *leaves.rbegin()});

            p = edges_to_parents(n, edges);

        } else if (type == 1) {
            
            int spine_len = rnd.next(n / 2, n - 1);
            p.resize(n + 1);
            
            for (int i = 2; i <= spine_len + 1; i++) p[i] = i - 1;
            
            for (int i = spine_len + 2; i <= n; i++) {
                p[i] = rnd.next(1, spine_len + 1);
            }

        } else if (type == 2) {
            
            p.resize(n + 1);
            for (int i = 2; i <= n; i++) {
                int k = rnd.next(1, min(i - 1, 5));
                p[i] = i - k;
                
                if (rnd.next(5) == 0) p[i] = rnd.next(1, i - 1);
            }

        } else if (type == 3) {
            
            p.resize(n + 1);
            for (int i = 2; i <= n; i++) {
                int limit = min(i - 1, 10);
                p[i] = rnd.next(1, limit);
            }

        } else {
            
            p.resize(n + 1);
            for (int i = 2; i <= n; i++) {
                p[i] = rnd.next(1, i - 1);
            }
        }
    }

    
    cout << n << endl;
    for (int i = 2; i <= n; i++) {
        cout << p[i] << (i == n ? "" : " ");
    }
    cout << endl;

    
    if (mode == "non") {
        
        int target = rnd.next(2, n);
        cout << target << endl;
    } 
    

    return 0;
}