#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)]);
  }
}
