#include <bits/stdc++.h>   using namespace std;   const int N = 200005;   int n, m, in[N], out[N], id[N], dep[N];   vector<int> v[N];   int idx;   void dfs(int pos, int dd) {     in[pos] = ++idx;     id[idx] = pos;     dep[idx] = dd;     for (auto &i : v[pos]) dfs(i, dd + 1);     out[pos] = ++idx;     id[idx] = pos;     dep[idx] = dd;   }   int fa[N], ch[N][2], mn[N], mx[N], val[N], sz[N];   inline void pushup(int x) {     sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;     mn[x] = mx[x] = dep[x];     mn[x] = min({mn[x], mn[ch[x][0]], mn[ch[x][1]]});     mx[x] = max({mx[x], mx[ch[x][0]], mx[ch[x][1]]});   }   int build(int l, int r) {     int mid = (l + r) >> 1, x = mid;     if (l < mid) ch[x][0] = build(l, mid - 1), fa[ch[x][0]] = x;     if (mid < r) ch[x][1] = build(mid + 1, r), fa[ch[x][1]] = x;     pushup(x);     return x;   }   inline void push(int x, int v) {     val[x] += v;     dep[x] += v;     mn[x] += v;     mx[x] += v;   }   inline void pushdown(int x) {     if (val[x]) {       if (ch[x][0]) push(ch[x][0], val[x]);       if (ch[x][1]) push(ch[x][1], val[x]);       val[x] = 0;     }   }   inline bool sd(int x) { return ch[fa[x]][1] == x; }   void rotate(int x) {     int y = fa[x], z = fa[y], k = sd(x);     if (z) ch[z][sd(y)] = x;     fa[x] = z;     fa[y] = x;     if (ch[x][!k]) fa[ch[x][!k]] = y;     ch[y][k] = ch[x][!k];     ch[x][!k] = y;     pushup(y);     pushup(x);   }   void splay(int x, int target = 0) {     static int stk[N], ptr;     stk[ptr = 1] = x;     int tmp = x;     while (fa[tmp] != target) stk[++ptr] = tmp = fa[tmp];     while (ptr) pushdown(stk[ptr--]);     while (fa[x] != target) {       int y = fa[x];       if (fa[y] != target) rotate(sd(x) == sd(y) ? y : x);       rotate(x);     }     pushup(x);   }   int kth(int x, int kk) {     pushdown(x);     if (mn[ch[x][1]] <= kk && mx[ch[x][1]] >= kk) return kth(ch[x][1], kk);     if (dep[x] == kk) {       splay(x);       return id[x];     }     return kth(ch[x][0], kk);   }   inline int split(int l, int r) {     splay(l);     splay(r, l);     return ch[r][0];   }   int pre(int x) {     splay(x);     x = ch[x][0];     while (ch[x][1]) x = ch[x][1];     splay(x);     return x;   }   int suf(int x) {     splay(x);     x = ch[x][1];     while (ch[x][0]) x = ch[x][0];     splay(x);     return x;   }   int erase(int l, int r) {     int lp = pre(l), rp = suf(r), p = split(lp, rp), v = fa[p];     ch[v][0] = fa[p] = 0;     return p;   }   int main() {     ios::sync_with_stdio(false);     cin >> n >> m;     for (int i = 1; i <= n; i++) {       int kk;       cin >> kk;       v[i].resize(kk);       for (int j = 0; j < kk; j++) cin >> v[i][j];     }     mn[0] = INT_MAX >> 1;     dfs(1, 0);     build(1, idx);     while (m--) {       int op;       cin >> op;       if (op == 1) {         int t1, t2;         cin >> t1 >> t2;         splay(in[t1]);         int rk1 = sz[ch[in[t1]][0]] + 1, ans = dep[in[t1]];         splay(in[t2]);         int rk2 = sz[ch[in[t2]][0]] + 1;         ans += dep[in[t2]];         if (rk1 > rk2) swap(t1, t2);         t1 = split(in[t1], out[t2]);         ans -= (mn[t1] - 1) * 2;         cout << ans << endl;       } else if (op == 2) {         int t1, t2;         cin >> t1 >> t2;         int val = t2 - 1;         splay(in[t1]);         t2 = kth(ch[in[t1]][0], dep[in[t1]] - t2);         t1 = erase(in[t1], out[t1]);         push(t1, -val);         int xx = pre(out[t2]);         splay(xx);         splay(out[t2], xx);         ch[out[t2]][0] = t1;         fa[t1] = out[t2];         pushup(out[t2]);         pushup(xx);       } else {         int k;         cin >> k;         splay(1);         cout << kth(1, k) << endl;       }     }     return 0;   }