#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
int n, m, in[N], out[N], id[N], dep[N];
vector<int> v[N];
int idx;
void dfs(int pos, int dd) {
  in[pos] = ++idx;
  id[idx] = pos;
  dep[idx] = dd;
  for (auto &i : v[pos]) dfs(i, dd + 1);
  out[pos] = ++idx;
  id[idx] = pos;
  dep[idx] = dd;
}
int fa[N], ch[N][2], mn[N], mx[N], val[N], sz[N];
inline void pushup(int x) {
  sz[x] = sz[ch[x][0]] + sz[ch[x][1]] + 1;
  mn[x] = mx[x] = dep[x];
  mn[x] = min({mn[x], mn[ch[x][0]], mn[ch[x][1]]});
  mx[x] = max({mx[x], mx[ch[x][0]], mx[ch[x][1]]});
}
int build(int l, int r) {
  int mid = (l + r) >> 1, x = mid;
  if (l < mid) ch[x][0] = build(l, mid - 1), fa[ch[x][0]] = x;
  if (mid < r) ch[x][1] = build(mid + 1, r), fa[ch[x][1]] = x;
  pushup(x);
  return x;
}
inline void push(int x, int v) {
  val[x] += v;
  dep[x] += v;
  mn[x] += v;
  mx[x] += v;
}
inline void pushdown(int x) {
  if (val[x]) {
    if (ch[x][0]) push(ch[x][0], val[x]);
    if (ch[x][1]) push(ch[x][1], val[x]);
    val[x] = 0;
  }
}
inline bool sd(int x) { return ch[fa[x]][1] == x; }
void rotate(int x) {
  int y = fa[x], z = fa[y], k = sd(x);
  if (z) ch[z][sd(y)] = x;
  fa[x] = z;
  fa[y] = x;
  if (ch[x][!k]) fa[ch[x][!k]] = y;
  ch[y][k] = ch[x][!k];
  ch[x][!k] = y;
  pushup(y);
  pushup(x);
}
void splay(int x, int target = 0) {
  static int stk[N], ptr;
  stk[ptr = 1] = x;
  int tmp = x;
  while (fa[tmp] != target) stk[++ptr] = tmp = fa[tmp];
  while (ptr) pushdown(stk[ptr--]);
  while (fa[x] != target) {
    int y = fa[x];
    if (fa[y] != target) rotate(sd(x) == sd(y) ? y : x);
    rotate(x);
  }
  pushup(x);
}
int kth(int x, int kk) {
  pushdown(x);
  if (mn[ch[x][1]] <= kk && mx[ch[x][1]] >= kk) return kth(ch[x][1], kk);
  if (dep[x] == kk) {
    splay(x);
    return id[x];
  }
  return kth(ch[x][0], kk);
}
inline int split(int l, int r) {
  splay(l);
  splay(r, l);
  return ch[r][0];
}
int pre(int x) {
  splay(x);
  x = ch[x][0];
  while (ch[x][1]) x = ch[x][1];
  splay(x);
  return x;
}
int suf(int x) {
  splay(x);
  x = ch[x][1];
  while (ch[x][0]) x = ch[x][0];
  splay(x);
  return x;
}
int erase(int l, int r) {
  int lp = pre(l), rp = suf(r), p = split(lp, rp), v = fa[p];
  ch[v][0] = fa[p] = 0;
  return p;
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    int kk;
    cin >> kk;
    v[i].resize(kk);
    for (int j = 0; j < kk; j++) cin >> v[i][j];
  }
  mn[0] = INT_MAX >> 1;
  dfs(1, 0);
  build(1, idx);
  while (m--) {
    int op;
    cin >> op;
    if (op == 1) {
      int t1, t2;
      cin >> t1 >> t2;
      splay(in[t1]);
      int rk1 = sz[ch[in[t1]][0]] + 1, ans = dep[in[t1]];
      splay(in[t2]);
      int rk2 = sz[ch[in[t2]][0]] + 1;
      ans += dep[in[t2]];
      if (rk1 > rk2) swap(t1, t2);
      t1 = split(in[t1], out[t2]);
      ans -= (mn[t1] - 1) * 2;
      cout << ans << endl;
    } else if (op == 2) {
      int t1, t2;
      cin >> t1 >> t2;
      int val = t2 - 1;
      splay(in[t1]);
      t2 = kth(ch[in[t1]][0], dep[in[t1]] - t2);
      t1 = erase(in[t1], out[t1]);
      push(t1, -val);
      int xx = pre(out[t2]);
      splay(xx);
      splay(out[t2], xx);
      ch[out[t2]][0] = t1;
      fa[t1] = out[t2];
      pushup(out[t2]);
      pushup(xx);
    } else {
      int k;
      cin >> k;
      splay(1);
      cout << kth(1, k) << endl;
    }
  }
  return 0;
}
