import std; void main () { int N = readln.split[0].to!int; // 覚えるために必要な技->覚えられる技 へと有向辺を張る int[][] vertex = new int[][](N, 0); int[] L; L ~= 0; foreach (i; 1..N) { auto buf = readln.split.to!(int[]); L ~= buf[0]; buf[1] -= 1; vertex[buf[1]] ~= i; } int Q = readln.split[0].to!int; solve(N, L, vertex, Q); } void solve (int N, int[] L, int[][] vertex, int Q) { // 技i(0<=i<=N-1)を覚えるために必要なコスト -1は覚えられない(依存関係がループしている) int[] cost = new int[](N); cost[0] = 0, cost[1..$] = -1; // BFS巡回 DList!int Que; Que.insertBack(0); while (!Que.empty) { int begin = Que.front; Que.removeFront; foreach (x; vertex[begin]) { if (cost[x] == -1) { cost[x] = max(L[x], cost[begin]); Que.insertBack(x); } } } int[] merge; foreach (x; cost) { if (x != -1) { merge ~= x; } } merge.sort; foreach (_; 0..Q) { auto buf = readln.split.to!(int[]); int query = buf[0], z = buf[1]; if (query == 1) { int left = 0, right = cast(int)merge.length; while (right - left != 1) { int center = (left + right) / 2; if (z < merge[center]) { right = center; } else { left = center; } } writeln(right); } else { writeln(cost[z-1]); } } }