#include <bits/stdc++.h>
using namespace std;
const int MAX = 100010;
const int MAXQ = 300000;
const int MAXE = (MAX + MAXQ) * 2;
const int MAXS = 262144;
struct box {
  int to, id;
  box *next;
} edge[MAXE], *h[MAX], *qH[MAX];
struct Query {
  int x, y;
  char type;
} query[MAXQ];
struct Seg {
  int s, t, r;
} seg[MAXS];
int dis[MAX], s[MAX], LCA[MAXQ], a[MAX], cnt, eNum, qNum;
int fa[MAX], dP[MAX], rF[MAX], pE[MAX], root[MAX], pre[MAX];
void addEdge(int x, int y, int id, box *h[]) {
  box *p = &edge[eNum++];
  box *q = &edge[eNum++];
  p->to = y, q->to = x;
  p->id = q->id = id;
  p->next = h[x], q->next = h[y];
  h[x] = p, h[y] = q;
}
void build(int c, int s, int t) {
  Seg &p = seg[c];
  p.s = s, p.t = t;
  p.r = t - s + 1;
  if (s == t) return;
  int d = (s + t) >> 1, nc = c << 1;
  build(nc, s, d), build(nc + 1, d + 1, t);
}
void reverse(int c, int x) {
  Seg &p = seg[c];
  if (p.s == p.t) {
    p.r ^= 1;
    return;
  }
  int d = (p.s + p.t) >> 1, nc = c << 1;
  reverse(nc + (x > d), x);
  p.r = seg[nc].r + seg[nc + 1].r;
}
int read(int c, int s, int t) {
  Seg &p = seg[c];
  if (p.s == s && p.t == t) return p.r;
  int d = (p.s + p.t) >> 1, nc = c << 1;
  int c1 = 0, c2 = 0;
  if (t <= d)
    c1 = read(nc, s, t);
  else if (s > d)
    c2 = read(nc + 1, s, t);
  else
    c1 = read(nc, s, d), c2 = read(nc + 1, d + 1, t);
  return c1 + c2;
}
int find_fa(int x) {
  if (fa[x] == 0) return x;
  return fa[x] = find_fa(fa[x]);
}
void getSize(int x, int f) {
  s[x] = 1;
  for (box *p = h[x]; p != NULL; p = p->next)
    if (p->to != f) {
      getSize(p->to, x);
      s[x] += s[p->to];
      dP[p->to] = p->id, rF[p->to] = x;
      pE[p->id] = p->to;
      fa[p->to] = x;
    }
  for (box *p = qH[x]; p != NULL; p = p->next)
    if (fa[p->to] != 0) LCA[p->id] = find_fa(p->to);
}
void dfs(int x) {
  if (root[x] == 0) root[x] = x;
  pre[x] = ++cnt;
  int max = -1, maxy;
  for (box *p = h[x]; p != NULL; p = p->next)
    if (pre[p->to] == 0 && s[p->to] > max) max = s[p->to], maxy = p->to;
  if (max == -1) return;
  root[maxy] = root[x];
  dfs(maxy);
  a[pre[maxy]] = dis[dP[maxy]];
  for (box *p = h[x]; p != NULL; p = p->next)
    if (pre[p->to] == 0) dfs(p->to);
}
int read(int x, int y) {
  int r = 0, cx = x, d;
  while (cx != y)
    if (root[cx] == cx) {
      if (dis[dP[cx]] == 0) return -1;
      r += dis[dP[cx]];
      cx = rF[cx];
    } else {
      if (pre[root[cx]] < pre[y]) {
        d = read(1, pre[y] + 1, pre[cx]);
        if (d < pre[cx] - pre[y]) return -1;
        cx = y;
      } else {
        d = read(1, pre[root[cx]] + 1, pre[cx]);
        if (d < pre[cx] - pre[root[cx]]) return -1;
        cx = root[cx];
      }
      r += d;
    }
  return r;
}
int main() {
  for (int N; scanf("%d", &N) != EOF;) {
    memset(root, 0, sizeof(root));
    memset(pre, 0, sizeof(pre));
    memset(fa, 0, sizeof(fa));
    memset(qH, 0, sizeof(qH));
    memset(a, 0, sizeof(a));
    memset(h, 0, sizeof(h));
    eNum = 0;
    for (int i = 1; i < N; i++) {
      int x, y;
      scanf("%d%d", &x, &y);
      dis[i] = 1;
      addEdge(x, y, i, h);
    }
    scanf("%d", &qNum);
    for (int cq = 0; cq < qNum; cq++) {
      Query &q = query[cq];
      scanf("%d", &q.type);
      if (q.type == 3) {
        scanf("%d%d", &q.x, &q.y);
        addEdge(q.x, q.y, cq, qH);
      } else {
        scanf("%d", &q.x);
      }
    }
    getSize(1, -1);
    cnt = 0;
    dfs(1);
    build(1, 2, N);
    for (int cq = 0; cq < qNum; cq++) {
      Query &q = query[cq];
      if (q.type == 3) {
        if (q.x == q.y) {
          puts("0");
        } else {
          int dx = read(q.x, LCA[cq]);
          int dy = read(q.y, LCA[cq]);
          printf("%d\n", (dx > -1 && dy > -1) ? dx + dy : -1);
        }
      } else {
        if (root[pE[q.x]] == pE[q.x])
          dis[q.x] ^= 1;
        else
          reverse(1, pre[pE[q.x]]);
      }
    }
  }
  return 0;
}
