#include <bits/stdc++.h>   using namespace std;   const int N = 2e5 + 100;   int p[N];   vector<int> G[N];   int mn[N], mx[N], val[N], sum[N], s[N][2], c[N][2], fa[N], mp[N];   int head;   void upd(int x) {     sum[x] = sum[c[x][1]] + sum[c[x][0]] + val[x];     mn[x] = min(mn[c[x][0]],                 min(sum[c[x][0]] + val[x], sum[c[x][0]] + val[x] + mn[c[x][1]]));     mx[x] = max(mx[c[x][0]],                 max(sum[c[x][0]] + val[x], sum[c[x][0]] + val[x] + mx[c[x][1]]));   }   void rot(int x, int d) {     int f = fa[x];     c[f][d ^ 1] = c[x][d];     fa[c[x][d]] = f;     if (fa[f]) c[fa[f]][(c[fa[f]][1] == f)] = x;     fa[x] = fa[f];     c[x][d] = f;     fa[f] = x;     upd(f);     upd(x);   }   void splay(int x, int stop) {     int t, d1, d2;     while ((t = fa[x]) - stop) {       if (fa[t] == stop)         rot(x, (c[fa[x]][0] == x));       else if ((d1 = (c[fa[t]][0] == t)) ^ (d2 = (c[fa[x]][0] == x)))         rot(x, d2), rot(x, d1);       else         rot(t, d1), rot(x, d2);     }     head = stop ? head : x;   }   int Next(int x) {     splay(x, 0);     for (x = c[x][1]; c[x][0]; x = c[x][0])       ;     return x;   }   int Prev(int x) {     splay(x, 0);     for (x = c[x][0]; c[x][1]; x = c[x][1])       ;     return x;   }   void ins(int r, int x) {     if (!r) {       head = x;       return;     }     int f = Next(r);     if (!f) {       fa[x] = r;       c[r][1] = x;       upd(r);     } else {       splay(f, r);       fa[x] = f;       c[f][0] = x;       upd(f);       upd(r);     }     splay(x, 0);   }   int cut(int l, int r) {     int tl = Prev(l), tr = Next(r);     if (!tl && !tr)       return r;     else if (!tl || !tr) {       int d = !tr, f = tr + tl;       splay(f, 0);       int u = c[f][d];       fa[u] = c[f][d] = 0;       upd(f);       return u;     } else {       splay(tr, 0);       splay(tl, tr);       int u = c[tl][1];       fa[u] = c[tl][1] = 0;       upd(tl);       upd(tr);       return u;     }   }   int lasth(int x, int h) {     for (h++;;) {       if (sum[c[x][0]] + val[x] + mx[c[x][1]] >= h &&           sum[c[x][0]] + val[x] + mn[c[x][1]] <= h) {         h -= sum[c[x][0]] + val[x];         x = c[x][1];       } else if (sum[c[x][0]] + val[x] == h)         return (x == s[mp[x]][0] ? mp[x] : p[mp[x]]);       else         x = c[x][0];     }   }   int dis(int a, int b) {     if (a == b) return 0;     int u = s[a][0], v = s[b][0];     splay(v, 0);     splay(u, v);     if ((c[fa[u]][1] == u) == 1) {       swap(u, v);       splay(v, 0);       splay(u, v);     }     int lcah = min(sum[c[u][0]] + val[u],                    min(sum[u] + val[v], sum[c[u][0]] + val[u] + mn[c[u][1]]));     return sum[u] + sum[c[u][0]] + val[u] + val[v] - 2 * lcah;   }   void reorder(int u, int h) {     int x = s[u][0];     splay(x, 0);     int f = lasth(c[x][0], sum[c[x][0]] + val[x] - h - 1);     p[u] = f;     int cuted = cut(s[u][0], s[u][1]);     ins(Prev(s[f][1]), cuted);   }   int T = 0;   void build(int u) {     s[u][0] = ++T;     mp[T] = u;     sum[T] = val[T] = mn[T] = mx[T] = 1;     ins(head, T);     for (int v : G[u]) build(v);     s[u][1] = ++T;     mp[T] = u;     sum[T] = val[T] = mn[T] = mx[T] = -1;     ins(head, T);   }   int main() {     int n, m;     scanf( %d%d , &n, &m);     memset(mx, -63, sizeof mx);     memset(mn, 63, sizeof mn);     for (int i = 0; i < n; i++) {       int sz = 0;       scanf( %d , &sz);       for (int j = 0; j < sz; j++) {         int v;         scanf( %d , &v);         v--;         G[i].push_back(v);         p[v] = i;       }     }     build(0);     for (int i = 0; i < m; i++) {       int c;       scanf( %d , &c);       if (c == 1) {         int u, v;         scanf( %d%d , &u, &v);         u--;         v--;         printf( %d n , dis(u, v));       } else if (c == 2) {         int u, h;         scanf( %d%d , &u, &h);         u--;         reorder(u, h);       } else {         int h;         scanf( %d , &h);         printf( %d n , lasth(head, h) + 1);       }     }   }