#include <bits/stdc++.h>
using namespace std;
int N, M, R, num[200005], Z[200005][2], fa[200005];
int D[200005], U[200005], T[200005], V[200005], S[200005][2], W, P[200005];
vector<int> dn[200005];
void Ud(int x) {
  T[x] = T[Z[x][0]] + T[Z[x][1]] + V[x];
  D[x] =
      min(T[Z[x][0]] + V[x], min(D[Z[x][0]], D[Z[x][1]] + T[Z[x][0]] + V[x]));
  U[x] =
      max(T[Z[x][0]] + V[x], max(U[Z[x][0]], U[Z[x][1]] + T[Z[x][0]] + V[x]));
}
void Ro(int x, int d) {
  int t = fa[x];
  Z[t][d ^ 1] = Z[x][d], fa[Z[x][d]] = t;
  if (fa[t]) Z[fa[t]][Z[fa[t]][1] == t] = x;
  fa[x] = fa[t], fa[t] = x, Z[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, Z[t][0] == x);
    else if ((d1 = (Z[fa[t]][0] == t)) ^ (d2 = (Z[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 = Z[x][0]; Z[x][1]; x = Z[x][1])
    ;
  return x;
}
int Next(int x) {
  Sp(x, 0);
  for (x = Z[x][1]; Z[x][0]; x = Z[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), tr += tl;
    Sp(tr, 0), t = Z[tr][f];
    Z[tr][f] = fa[Z[tr][f]] = 0, Ud(tr);
    return t;
  }
  Sp(tl, 0), Sp(tr, tl), t = Z[tr][0];
  Z[tr][0] = fa[Z[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)
    Z[x][1] = y, fa[y] = x, Ud(x);
  else
    Sp(t, x), Z[t][0] = y, fa[y] = t, Ud(t), Ud(x);
  Sp(y, 0);
}
int Ask(int x, int k) {
  for (k++;;)
    if (D[Z[x][1]] + T[Z[x][0]] + V[x] <= k &&
        U[Z[x][1]] + T[Z[x][0]] + V[x] >= k)
      k -= T[Z[x][0]] + V[x], x = Z[x][1];
    else if (T[Z[x][0]] + V[x] == k) {
      Sp(x, 0);
      return x == S[num[x]][0] ? num[x] : P[num[x]];
    } else
      x = Z[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 == Z[y][1]) swap(x, y);
  Sp(y, 0), Sp(x, y);
  int t =
      min(T[Z[x][0]] + V[x], min(D[Z[x][1]] + T[Z[x][0]] + V[x], T[x] + V[y]));
  return T[Z[x][0]] + T[x] + V[x] + V[y] - t * 2;
}
void Tr(int x, int h) {
  int t = x, par;
  x = S[x][0], Sp(x, 0), par = Ask(Z[x][0], T[Z[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, tp, fr, to;
  scanf("%d", &N), scanf("%d", &M);
  for (i = 0; i <= 200005 - 5; i++) U[i] = -200005, D[i] = 200005;
  for (i = 1; i <= N && scanf("%d", &j); i++)
    while (j--) scanf("%d", &t), dn[i].push_back(t);
  for (i = 1, Dfs(1); i <= M && scanf("%d", &tp); i++)
    if (tp == 1)
      scanf("%d", &fr), scanf("%d", &to), printf("%d\n", Dis(fr, to));
    else if (tp == 2)
      scanf("%d", &fr), scanf("%d", &to), Tr(fr, to);
    else
      scanf("%d", &fr), printf("%d\n", Ask(R, fr));
  return 0;
}
