#include <bits/stdc++.h>   using namespace std;   int N, Q, C, Rt, L[200005], R[200005], G[200005], F[200005], ch[200005][2];   struct Nod {     int Now, Max, Min, Laz;     Nod() {       Min = 1 << 30;       Max = -Min;     }   } T[200005];   vector<int> son[200005];   void Upd(int x, int k) {     if (x) T[x].Now += k, T[x].Max += k, T[x].Min += k, T[x].Laz += k;   }   void Up(int x) {     int l = ch[x][0], r = ch[x][1];     T[x].Max = max(T[x].Now, max(T[l].Max, T[r].Max));     T[x].Min = min(T[x].Now, min(T[l].Min, T[r].Min));   }   void Dn(int x) {     int k = T[x].Laz;     if (k) Upd(ch[x][0], k), Upd(ch[x][1], k), T[x].Laz = 0;   }   void Rot(int x) {     int y = F[x], z = F[y], k = ch[y][0] == x, t;     if (t = ch[y][!k] = ch[x][k]) F[t] = y;     if (F[x] = z) ch[z][ch[z][1] == y] = x;     ch[F[y] = x][k] = y;     Up(y);   }   void Splay(int x, int Aim) {     for (Dn(x); F[x] ^ Aim; Rot(x)) {       int y = F[x], z = F[y];       Dn(z);       Dn(y);       Dn(x);       if (F[y] ^ Aim) (ch[z][0] == y ^ ch[y][0] == x) ? Rot(x) : Rot(y);     }     Up(x);     if (!Aim) Rt = x;   }   void DFS(int u, int d) {     L[u] = ++C;     G[C] = u;     T[C].Now = d;     for (int i = 1, lim = son[u].size(); i <= lim; i++) DFS(son[u][i - 1], d + 1);     R[u] = ++C;     G[C] = u;     T[C].Now = d;   }   void Build(int& u, int l, int r, int fa) {     F[u = l + r >> 1] = fa;     if (l < u) Build(ch[u][0], l, u - 1, u);     if (u < r) Build(ch[u][1], u + 1, r, u);     Up(u);   }   int Find(int x, int k) {     int l = ch[x][0], r = ch[x][1];     Dn(x);     if (T[r].Min <= k && k <= T[r].Max) return Find(r, k);     return T[x].Now == k ? x : Find(l, k);   }   int Pre(int x) {     Splay(x, 0);     x = ch[x][0];     for (; ch[x][1]; x = ch[x][1]) Dn(x);     return x;   }   int Suf(int x) {     Splay(x, 0);     x = ch[x][1];     for (; ch[x][0]; x = ch[x][0]) Dn(x);     return x;   }   void Get(int x, int y) {     Splay(x, 0);     Splay(y, x);   }   int main() {     scanf( %d%d , &N, &Q);     for (int i = 1, lim = N; i <= lim; i++) {       int x, t;       scanf( %d , &x);       for (; x--;) scanf( %d , &t), son[i].push_back(t);     }     C++;     DFS(1, 1);     C++;     Build(Rt, 1, C, 0);     for (int k, x, y, z, l, r, w, t; Q--;) {       scanf( %d , &k);       if (k == 1) {         scanf( %d%d , &x, &y);         if (x == y)           puts( 0 );         else {           x = L[x];           y = L[y];           Get(x, y);           z = (ch[x][0] == y ? T[ch[y][1]] : T[ch[y][0]]).Min;           printf( %d n ,                  T[x].Now + T[y].Now - 2 * min(z - 1, min(T[x].Now, T[y].Now)));         }       } else if (k == 2) {         scanf( %d%d , &x, &y);         Get(1, L[x]);         w = G[Find(ch[L[x]][0], T[L[x]].Now - y)];         l = Pre(L[x]);         r = Suf(R[x]);         Get(l, r);         t = ch[r][0];         ch[r][0] = 0;         Up(r);         Up(l);         r = R[w];         l = Pre(r);         Get(l, r);         ch[r][0] = t;         F[t] = r;         Upd(t, -y + 1);         Splay(t, 0);       } else         scanf( %d , &x), printf( %d n , G[Find(Rt, x + 1)]);     }   }   