#include #include #include using namespace std; const int NMAX = 100010, INF = 0x3f3f3f3f; int N, M, Type, X, Y, Level[NMAX], Ancestor[20][NMAX], Root; vector G[NMAX]; bool Used[NMAX]; void DFS(int Node, int Father) { Used[Node] = 1; Level[Node] = Level[Father] + 1; Ancestor[0][Node] = Father; for(int i = 0; i < G[Node].size(); ++ i) if(!Used[ G[Node][i] ]) DFS(G[Node][i], Node); } void Build_Ancestors() { for(int i = 1; (1 << i) <= N; ++ i) for(int j = 1; j <= N; ++ j) Ancestor[i][j] = Ancestor[i - 1][Ancestor[i - 1][j]]; } int Get_Initial_LCA(int X, int Y) { if(Level[X] < Level[Y]) swap(X, Y); int StepX, StepY; for(StepX = 0; (1 << StepX) <= Level[X]; StepX ++); for(StepY = 0; (1 << StepY) <= Level[Y]; StepY ++); for(; StepX >= 0; StepX --) if(Level[X] - (1 << StepX) >= Level[Y]) X = Ancestor[StepX][X]; if(X == Y) return X; for(; StepY >= 0; StepY --) if(Ancestor[StepY][X] && Ancestor[StepY][X] != Ancestor[StepY][Y]) { X = Ancestor[StepY][X]; Y = Ancestor[StepY][Y]; } return Ancestor[0][X]; } int Find_Current_Level(int X) { return Level[X] + Level[Root] - 2 * Level[Get_Initial_LCA(X, Root)]; } int Find_Current_Ancestor(int Node, int IndexAnc) { int DistToRoot = Level[Node] - Level[ Get_Initial_LCA(Node, Root) ]; if(DistToRoot >= IndexAnc) { for(int i = 0; i < 20; ++ i) if(IndexAnc & (1 << i)) Node = Ancestor[i][Node]; return Node; }else { IndexAnc -= DistToRoot; IndexAnc = Level[Root] - Level[ Get_Initial_LCA(Node, Root) ] - IndexAnc; if(IndexAnc < 0) return 0; Node = Root; for(int i = 0; i < 20; ++ i) if(IndexAnc & (1 << i)) Node = Ancestor[i][Node]; return Node; } } int Find_Current_LCA(int X, int Y) { int LX, LY; LX = Find_Current_Level(X); LY = Find_Current_Level(Y); if(LX < LY) swap(X, Y), swap(LX, LY); int StepX, StepY; for(StepX = 0; (1 << StepX) <= LX; StepX ++); for(StepY = 0; (1 << StepY) <= LY; StepY ++); for(; StepX >= 0; StepX --) if(LX - (1 << StepX) >= LY) { LX -= (1 << StepX); X = Find_Current_Ancestor(X, (1 << StepX)); } if(X == Y) return X; for(; StepY >= 0; -- StepY) { int AncX = Find_Current_Ancestor(X, (1 << StepY)); int AncY = Find_Current_Ancestor(Y, (1 << StepY)); if(AncX && AncX != AncY) { X = AncX; Y = AncY; LX -= (1 << StepY); LY -= (1 << StepY); } } return Find_Current_Ancestor(X, 1); } int main() { // freopen("d.in", "r", stdin); // freopen("d.out", "w", stdout); scanf("%i %i", &N, &M); for(int i = 1; i < N; ++ i) { scanf("%i %i", &X, &Y); G[X].push_back(Y); G[Y].push_back(X); } Root = 1; DFS(1, 0); Build_Ancestors(); for(int i = 1; i <= M; ++ i) { scanf("%i", &Type); if(Type == 1) { scanf("%i", &X); Root = X; }else { scanf("%i %i", &X, &Y); int LCA = Find_Current_LCA(X, Y); if(LCA == X || LCA == Y) printf("-1\n"); else printf("%i\n", LCA); } } }