#include <bits/stdc++.h>
const int MAXN = 3e5 + 5;
std::vector<int> G[MAXN];
int in[MAXN], out[MAXN], dep[MAXN], id[MAXN], ts;
int n;
inline void dfs(int v, int d) {
  in[v] = ++ts;
  id[ts] = v;
  dep[ts] = d;
  for (auto x : G[v]) dfs(x, d + 1);
  out[v] = ++ts;
  id[ts] = v;
  dep[ts] = d;
}
int f[MAXN], mn[MAXN], mx[MAXN], tag[MAXN], ch[MAXN][2], sz[MAXN];
inline void pushup(int x) {
  if (!x) return;
  mn[x] = std::min(dep[x], std::min(mn[(ch[x][0])], mn[(ch[x][1])]));
  mx[x] = std::max(dep[x], std::max(mx[(ch[x][0])], mx[(ch[x][1])]));
  sz[x] = sz[(ch[x][0])] + sz[(ch[x][1])] + 1;
}
inline void cover(int x, int d) {
  mn[x] += d;
  mx[x] += d;
  tag[x] += d;
  dep[x] += d;
}
inline void pushdown(int x) {
  if (tag[x]) {
    if ((ch[x][0])) cover((ch[x][0]), tag[x]);
    if ((ch[x][1])) cover((ch[x][1]), tag[x]);
    tag[x] = 0;
  }
}
inline void rotate(int x) {
  int y = f[x], z = f[y], k = ch[y][1] == x, w = ch[x][!k];
  ch[z][ch[z][1] == y] = x;
  f[x] = z;
  ch[x][!k] = y;
  f[y] = x;
  ch[y][k] = w;
  if (w) f[w] = y;
  pushup(y);
  pushup(x);
}
int rt;
int st[MAXN];
inline void splay(int x, int v = 0) {
  int y = x, z;
  st[z = 1] = y;
  while (f[y] != v) st[++z] = y = f[y];
  while (z) pushdown(st[z--]);
  while ((y = f[x]) != v) {
    if ((z = f[y]) != v) rotate((ch[z][1] == y) ^ (ch[y][1] == x) ? x : y);
    rotate(x);
  }
  if (!v) rt = x;
  pushup(x);
}
inline int getk(int k) {
  int x = rt;
  while (true) {
    pushdown(x);
    if (k <= sz[(ch[x][0])])
      x = (ch[x][0]);
    else if (k == sz[(ch[x][0])] + 1)
      return splay(x), x;
    else
      k -= sz[(ch[x][0])] + 1, x = (ch[x][1]);
  }
}
inline int pre(int x) {
  splay(x);
  x = (ch[x][0]);
  while ((ch[x][1])) x = (ch[x][1]);
  return x;
}
inline int suf(int x) {
  splay(x);
  x = (ch[x][1]);
  while ((ch[x][0])) x = (ch[x][0]);
  return x;
}
inline int split(int x, int y) {
  x = pre(x);
  y = suf(y);
  splay(x);
  splay(y, x);
  return ch[y][0];
}
inline int find(int x, int k) {
  pushdown(x);
  if (mn[(ch[x][1])] <= k && k <= mx[(ch[x][1])]) return find((ch[x][1]), k);
  if (dep[x] == k) return splay(x), x;
  return find((ch[x][0]), k);
}
inline void build(int f, int &x, int l, int r) {
  if (l > r) return;
  x = (l + r) >> 1;
  mn[x] = mx[x] = dep[x];
  sz[x] = 1;
  tag[x] = 0;
  ::f[x] = f;
  if (l == r) return;
  build(x, (ch[x][0]), l, x - 1);
  build(x, (ch[x][1]), x + 1, r);
  pushup(x);
}
inline void dfs(int x) {
  pushdown(x);
  if ((ch[x][0])) dfs((ch[x][0]));
  printf("(%d,%d)", id[x], dep[x]);
  if ((ch[x][1])) dfs((ch[x][1]));
  pushup(x);
}
int main() {
  mn[0] = 1e9;
  int m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    int k;
    scanf("%d", &k);
    while (k--) {
      int x;
      scanf("%d", &x);
      G[i].push_back(x);
    }
  }
  dfs(1, 1);
  build(0, rt, 1, ts);
  while (m--) {
    int opt;
    scanf("%d", &opt);
    if (opt == 1) {
      int u, v;
      scanf("%d%d", &u, &v);
      int res = 0;
      splay(in[u]);
      int rku = sz[ch[in[u]][0]] + 1;
      res += dep[in[u]];
      splay(in[v]);
      int rkv = sz[ch[in[v]][0]] + 1;
      res += dep[in[v]];
      if (rku > rkv) std::swap(u, v);
      int t = split(suf(in[u]), pre(out[v]));
      res -= 2 * (mn[t] - 1);
      printf("%d\n", res);
    }
    if (opt == 2) {
      int v, h;
      scanf("%d%d", &v, &h);
      splay(in[v]);
      int fa = id[find(ch[in[v]][0], dep[in[v]] - h)];
      int t = split(in[v], out[v]);
      pushdown(f[t]);
      ch[f[t]][0] = 0;
      pushup(f[t]);
      pushup(f[f[t]]);
      f[t] = 0;
      cover(t, 1 - h);
      int tt = pre(out[fa]);
      splay(tt);
      splay(out[fa], tt);
      pushdown(out[fa]);
      ch[out[fa]][0] = t;
      f[t] = out[fa];
      pushup(out[fa]);
      pushup(tt);
    }
    if (opt == 3) {
      int k;
      scanf("%d", &k);
      splay(1);
      ++k;
      printf("%d\n", id[find(1, k)]);
    }
  }
  return 0;
}
