#include <bits/stdc++.h>
using namespace std;
int N, M, R;
int num[200005], son[200005][2], fa[200005];
int D[200005], U[200005], T[200005], V[200005];
int S[200005][2], W, P[200005];
vector<int> dn[200005];
void Ud(int x) {
  T[x] = T[son[x][0]] + T[son[x][1]] + V[x];
  D[x] = min(D[son[x][0]], D[son[x][1]] + T[son[x][0]] + V[x]);
  D[x] = min(D[x], T[son[x][0]] + V[x]);
  U[x] = max(U[son[x][0]], U[son[x][1]] + T[son[x][0]] + V[x]);
  U[x] = max(U[x], T[son[x][0]] + V[x]);
}
void Ro(int x, int d) {
  int t = fa[x];
  son[t][d ^ 1] = son[x][d], fa[son[x][d]] = t;
  if (fa[t]) son[fa[t]][son[fa[t]][1] == t] = x;
  fa[x] = fa[t], fa[t] = x, son[x][d] = t;
  Ud(t), Ud(x);
}
void Sp(int x, int to) {
  int t, d1, d2;
  while ((t = fa[x]) - to) {
    if (fa[t] == to)
      Ro(x, son[t][0] == x);
    else if ((d1 = (son[fa[t]][0] == t)) ^ (d2 = (son[t][0] == x)))
      Ro(x, d2), Ro(x, d1);
    else
      Ro(t, d1), Ro(x, d2);
  }
  R = to ? R : x;
}
int Last(int x) {
  Sp(x, 0);
  for (x = son[x][0]; son[x][1]; x = son[x][1])
    ;
  return x;
}
int Next(int x) {
  Sp(x, 0);
  for (x = son[x][1]; son[x][0]; x = son[x][0])
    ;
  return x;
}
int De(int l, int r) {
  int t, tl, tr, f;
  tl = Last(l);
  tr = Next(r);
  if (!(tl + tr)) {
    return r;
  } else if (!tl || !tr) {
    f = (tr == 0), tr += tl;
    Sp(tr, 0), t = son[tr][f];
    son[tr][f] = fa[son[tr][f]] = 0, Ud(tr);
    return t;
  }
  Sp(tl, 0), Sp(tr, tl), t = son[tr][0];
  son[tr][0] = fa[son[tr][0]] = 0;
  Ud(tr), Ud(tl);
  return t;
}
void In(int x, int y) {
  if (!x) {
    R = y;
    return;
  }
  int t = Next(x);
  if (!t)
    son[x][1] = y, fa[y] = x, Ud(x);
  else {
    Sp(t, x);
    son[t][0] = y, fa[y] = t;
    Ud(t), Ud(x);
  }
  Sp(y, 0);
}
int Ask(int x, int k) {
  for (k++;;)
    if (D[son[x][1]] + T[son[x][0]] + V[x] <= k &&
        U[son[x][1]] + T[son[x][0]] + V[x] >= k)
      k -= T[son[x][0]] + V[x], x = son[x][1];
    else if (T[son[x][0]] + V[x] == k) {
      Sp(x, 0);
      return x == S[num[x]][0] ? num[x] : P[num[x]];
    } else
      x = son[x][0];
}
int Dis(int x, int y) {
  x = S[x][0], y = S[y][0];
  if (x == y) return 0;
  Sp(y, 0), Sp(x, y);
  if (x == son[y][1]) swap(x, y);
  Sp(y, 0), Sp(x, y);
  int t = min(T[son[x][0]] + V[x],
              min(D[son[x][1]] + T[son[x][0]] + V[x], T[x] + V[y]));
  return T[son[x][0]] + T[x] + V[x] + V[y] - t * 2;
}
void Tr(int x, int h) {
  int t = x;
  x = S[x][0], Sp(x, 0);
  int par = Ask(son[x][0], T[son[x][0]] + V[x] - h - 1);
  P[t] = par;
  t = De(S[t][0], S[t][1]);
  In(Last(S[par][1]), t);
}
void Dfs(int x) {
  S[x][0] = ++W, num[W] = x;
  V[W] = T[W] = D[W] = U[W] = 1, In(R, W);
  for (int i = 0; i < dn[x].size(); i++) P[dn[x][i]] = x, Dfs(dn[x][i]);
  S[x][1] = ++W, num[W] = x;
  V[W] = T[W] = D[W] = U[W] = -1, In(R, W);
}
int main() {
  int i, j, t, get, type, fr, to;
  scanf("%d %d", &N, &M);
  memset(D, 62, sizeof(D));
  for (i = 0; i <= 200000; i++) U[i] = -2 * N - 2, D[i] = 2 * N + 2;
  for (i = 1; i <= N; i++) {
    scanf("%d", &j);
    while (j--) scanf("%d", &t), dn[i].push_back(t);
  }
  for (i = 1, Dfs(1); i <= M; i++) {
    scanf("%d", &type);
    if (type == 1)
      scanf("%d %d", &fr, &to), printf("%d\n", Dis(fr, to));
    else if (type == 2)
      scanf("%d %d", &fr, &to), Tr(fr, to);
    else
      scanf("%d", &fr), printf("%d\n", Ask(R, fr));
  }
  return 0;
}
