#include <bits/stdc++.h>
using namespace std;
const int N = 200005, INF = 0x3f3f3f3f;
int n, m, sign, a[N], fa[N], v[N];
int root;
struct SPLAY {
  int ch[2], fa, v, sum, mx, mi, id;
} s[N << 1];
vector<int> to[N];
void dfs(int x) {
  a[++sign] = x;
  s[x].v = 1;
  s[x].id = x;
  for (int i = 0; i < to[x].size(); i++) {
    fa[to[x][i]] = x;
    dfs(to[x][i]);
  }
  a[++sign] = x + n;
  s[x + n].v = -1;
  s[x + n].id = x;
}
void pushup(int x) {
  int sl = s[x].ch[0], sr = s[x].ch[1];
  s[x].sum = s[sl].sum + s[sr].sum + s[x].v;
  s[x].mx = max(s[sl].mx, s[sl].sum + s[x].v + max(s[sr].mx, 0));
  s[x].mi = min(s[sl].mi, s[sl].sum + s[x].v + min(s[sr].mi, 0));
}
int build(int L, int R) {
  int mid = L + R >> 1;
  int x = a[mid];
  if (L < mid) {
    s[x].ch[0] = build(L, mid - 1);
    s[s[x].ch[0]].fa = x;
  }
  if (mid < R) {
    s[x].ch[1] = build(mid + 1, R);
    s[s[x].ch[1]].fa = x;
  }
  pushup(x);
  return x;
}
void Rotate(int x) {
  int f = s[x].fa, ff = s[f].fa;
  int t1 = s[f].ch[1] == x, t2 = s[ff].ch[1] == f, S = s[x].ch[!t1];
  if (ff) s[ff].ch[t2] = x;
  s[x].fa = ff;
  s[x].ch[!t1] = f;
  s[f].fa = x;
  s[f].ch[t1] = S;
  s[S].fa = f;
  pushup(f);
  pushup(x);
  return;
}
void Splay(int x, int goal) {
  for (; s[x].fa != goal; Rotate(x))
    if (s[s[x].fa].fa != goal)
      Rotate((s[s[s[x].fa].fa].ch[1] == (s[x].fa)) == (s[s[x].fa].ch[1] == (x))
                 ? s[x].fa
                 : x);
  if (!goal) root = x;
}
void Dis() {
  int x, y, dx, dy, dl;
  scanf("%d%d", &x, &y);
  Splay(x, 0);
  dx = s[s[x].ch[0]].sum + s[x].v;
  Splay(y, 0);
  dy = s[s[y].ch[0]].sum + s[y].v;
  Splay(x, 0);
  Splay(y, x);
  dl = min(dx, dy);
  if (s[x].ch[0] == y)
    dl = min(dl, s[s[y].ch[0]].sum + s[y].v + s[s[y].ch[1]].mi);
  else
    dl = min(dl, s[s[x].ch[0]].sum + s[x].v + s[s[y].ch[0]].mi);
  cout << (dx + dy - (dl << 1)) << '\n';
}
int Find(int x, int d) {
  int sr = s[x].ch[1], sl = s[x].ch[0];
  if (s[sr].mx >= d - s[sl].sum - s[x].v && s[sr].mi <= d - s[sl].sum - s[x].v)
    return Find(sr, d - s[sl].sum - s[x].v);
  if (s[sl].sum + s[x].v == d) return (x <= n) ? x : fa[x - n];
  return Find(sl, d);
}
int left(int x) {
  Splay(x, 0);
  x = s[x].ch[0];
  while (s[x].ch[1]) x = s[x].ch[1];
  return x;
}
int right(int x) {
  Splay(x, 0);
  x = s[x].ch[1];
  while (s[x].ch[0]) x = s[x].ch[0];
  return x;
}
void Change() {
  int x, h, L, R, rt;
  scanf("%d%d", &x, &h);
  Splay(x, 0);
  fa[x] = Find(s[x].ch[0], s[s[x].ch[0]].sum + s[x].v - h);
  L = left(x);
  R = right(x + n);
  Splay(L, 0);
  Splay(R, L);
  rt = s[R].ch[0];
  s[R].ch[0] = 0;
  pushup(R);
  pushup(L);
  L = left(fa[x] + n);
  R = fa[x] + n;
  Splay(L, 0);
  Splay(R, L);
  s[R].ch[0] = rt;
  s[rt].fa = R;
  pushup(R);
  pushup(L);
}
void Print() {
  int st[100], top = 1;
  st[1] = root;
  cout << "---------A Tree----------\n";
  for (int i = 1; i <= top; i++) {
    int x = st[i];
    cout << x << ' ' << s[x].ch[0] << ' ' << s[x].ch[1] << ' ' << s[x].id << ' '
         << s[x].sum << '\n';
    if (s[x].ch[0]) st[++top] = s[x].ch[0];
    if (s[x].ch[1]) st[++top] = s[x].ch[1];
  }
  cout << "-------------------------\n";
}
int main() {
  int x, l;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &l);
    for (int j = 1; j <= l; j++) {
      scanf("%d", &x);
      to[i].push_back(x);
    }
  }
  dfs(1);
  s[0].mx = -INF;
  s[0].mi = INF;
  root = build(1, n << 1);
  int tp, d;
  for (int i = 1; i <= m; i++) {
    scanf("%d", &tp);
    switch (tp) {
      case 1:
        Dis();
        break;
      case 2:
        Change();
        break;
      case 3:
        scanf("%d", &d);
        cout << Find(root, d + 1) << '\n';
        break;
    }
  }
  return 0;
}
