#include <bits/stdc++.h>
using namespace std;
struct tree {
  int l, r;
  int sum;
} t[100010 << 2];
void pushup(int p) { t[p].sum = t[(p << 1)].sum + t[((p << 1) | 1)].sum; }
void build(int p, int l, int r) {
  t[p].l = l, t[p].r = r, t[p].sum = 0;
  if (l == r) return;
  build((p << 1), l, ((t[p].l + t[p].r) >> 1));
  build(((p << 1) | 1), ((t[p].l + t[p].r) >> 1) + 1, r);
}
void add(int p, int x, int val) {
  if (t[p].l == t[p].r) {
    t[p].sum += val;
    return;
  }
  if (x <= ((t[p].l + t[p].r) >> 1))
    add((p << 1), x, val);
  else
    add(((p << 1) | 1), x, val);
  pushup(p);
}
int query(int p, int l, int r) {
  if (t[p].l == l && t[p].r == r) {
    return t[p].sum;
  }
  if (l > ((t[p].l + t[p].r) >> 1))
    return query(((p << 1) | 1), l, r);
  else if (r <= ((t[p].l + t[p].r) >> 1))
    return query((p << 1), l, r);
  else
    return query((p << 1), l, ((t[p].l + t[p].r) >> 1)) +
           query(((p << 1) | 1), ((t[p].l + t[p].r) >> 1) + 1, r);
}
int siz[100010], top[100010], son[100010], dep[100010], w[100010], fa[100010];
struct edge {
  int to;
  int next;
} e[100010 << 1];
int box[100010], cnt, tot;
void init() {
  tot = 0;
  son[0] = dep[0] = 0;
  memset(box, -1, sizeof(box));
  cnt = 0;
}
void add(int from, int to) {
  e[cnt].to = to;
  e[cnt].next = box[from];
  box[from] = cnt++;
}
void dfs(int now, int pre) {
  siz[now] = 1;
  fa[now] = pre;
  son[now] = 0;
  dep[now] = dep[pre] + 1;
  int t, v;
  for (t = box[now]; t + 1; t = e[t].next) {
    v = e[t].to;
    if (v != pre) {
      dfs(v, now);
      siz[now] += siz[v];
      if (siz[son[now]] < siz[v]) {
        son[now] = v;
      }
    }
  }
}
void dfs2(int now, int tp) {
  w[now] = ++tot;
  top[now] = tp;
  if (son[now]) dfs2(son[now], top[now]);
  int t, v;
  for (t = box[now]; t + 1; t = e[t].next) {
    v = e[t].to;
    if (v != fa[now] && v != son[now]) dfs2(v, v);
  }
}
int solve(int a, int b) {
  int f1 = top[a], f2 = top[b], dist = 0;
  while (f1 != f2) {
    if (dep[f1] < dep[f2]) {
      swap(f1, f2);
      swap(a, b);
    }
    dist += w[a] - w[f1] + 1;
    int tmp = query(1, w[f1], w[a]);
    if (tmp) return -1;
    a = fa[f1];
    f1 = top[a];
  }
  if (a == b)
    return dist;
  else {
    if (dep[a] > dep[b]) swap(a, b);
    int tmp = query(1, w[son[a]], w[b]);
    if (tmp) return -1;
    return dist + w[b] - w[a];
  }
}
int Edge[100010][2];
int main() {
  int n, q, i, a, b;
  scanf("%d", &n);
  init();
  for (i = 1; i < n; i++) {
    scanf("%d%d", &Edge[i][0], &Edge[i][1]);
    add(Edge[i][0], Edge[i][1]);
    add(Edge[i][1], Edge[i][0]);
  }
  build(1, 1, n);
  dfs(1, 0);
  dfs2(1, 1);
  scanf("%d", &q);
  while (q--) {
    int k;
    scanf("%d", &k);
    if (k == 3) {
      scanf("%d%d", &a, &b);
      printf("%d\n", solve(a, b));
    } else {
      scanf("%d", &i);
      int tmp;
      if (dep[Edge[i][0]] > dep[Edge[i][1]])
        tmp = Edge[i][0];
      else
        tmp = Edge[i][1];
      if (k == 1)
        add(1, w[tmp], -1);
      else
        add(1, w[tmp], 1);
    }
  }
  return 0;
}
