#include <bits/stdc++.h>
using namespace std;
const int maxn = 800001;
int *s[maxn], *m[maxn], T1[4 * maxn], T2[4 * maxn],
    *nowS = T1, *nowM = T2, S, M, u, v, t, n, i, Lca, dep[maxn], own[maxn],
    l[maxn], Pson[maxn], f[maxn], son[maxn], nowU, d[maxn];
char cmd[100];
struct O {
  int x, y;
} p[maxn];
struct Graph {
  int y[2 * maxn], next[2 * maxn], f[2 * maxn], T;
  inline void init() {
    memset(f, 0, sizeof(f));
    T = 0;
  }
  inline void Add(int u, int v) {
    y[++T] = v;
    next[T] = f[u];
    f[u] = T;
  }
} g;
inline void DFS_chain(int u, int F) {
  for (int j = g.f[u]; j; j = g.next[j])
    if (g.y[j] != F) {
      if (g.y[j] != Pson[u])
        own[g.y[j]] = g.y[j];
      else
        own[g.y[j]] = own[u];
      DFS_chain(g.y[j], u);
    }
}
inline void DFS(int u, int F) {
  son[u] = 1, l[u] = 1;
  int p, Max = 0;
  for (int j = g.f[u]; j; j = g.next[j])
    if (g.y[j] != F) {
      dep[g.y[j]] = dep[u] + 1;
      f[g.y[j]] = u;
      DFS(g.y[j], u);
      son[u] += son[g.y[j]];
      if (Max < son[g.y[j]]) {
        Max = son[g.y[j]];
        p = g.y[j];
      }
    }
  if (Max) Pson[u] = p, l[u] = l[p] + 1;
}
inline void DFS_Heavy_chain(int u, int p, int l, int r) {
  if (l == r) {
    s[u][p] = d[nowU], m[u][p] = d[nowU];
    nowU = Pson[nowU], M = max(M, p);
    return;
  }
  DFS_Heavy_chain(u, p + p, l, ((l + r) >> 1));
  DFS_Heavy_chain(u, p + p + 1, ((l + r) >> 1) + 1, r);
  s[u][p] = s[u][p + p] + s[u][p + p + 1];
  m[u][p] = max(m[u][p + p], m[u][p + p + 1]);
}
inline void build(int u) {
  s[u] = nowS;
  m[u] = nowM;
  nowU = u;
  M = 0;
  DFS_Heavy_chain(u, 1, 1, l[u]);
  nowS = nowS + M;
  nowM = nowM + M;
}
inline void Change(int u, int p, int l, int r, int k, int val) {
  if (l == r) {
    s[u][p] = val;
    m[u][p] = val;
    return;
  }
  if (k <= ((l + r) >> 1))
    Change(u, p + p, l, ((l + r) >> 1), k, val);
  else
    Change(u, p + p + 1, ((l + r) >> 1) + 1, r, k, val);
  s[u][p] = s[u][p + p] + s[u][p + p + 1];
  m[u][p] = max(m[u][p + p], m[u][p + p + 1]);
}
inline void Get(int u, int p, int l, int r, int a, int b) {
  if (l == a && r == b) {
    S = S + s[u][p];
    M = max(M, m[u][p]);
    return;
  }
  if (b <= ((l + r) >> 1))
    Get(u, p + p, l, ((l + r) >> 1), a, b);
  else if (a > ((l + r) >> 1))
    Get(u, p + p + 1, ((l + r) >> 1) + 1, r, a, b);
  else {
    Get(u, p + p, l, ((l + r) >> 1), a, ((l + r) >> 1));
    Get(u, p + p + 1, ((l + r) >> 1) + 1, r, ((l + r) >> 1) + 1, b);
  }
}
inline void Query(int u, int v) {
  while (1) {
    if (own[u] == own[v]) {
      if (dep[u] > dep[v]) swap(u, v);
      Lca = u;
      if (u != v)
        Get(own[u], 1, 1, l[own[u]], dep[u] - dep[own[u]] + 2,
            dep[v] - dep[own[v]] + 1);
      break;
    } else {
      if (dep[own[u]] > dep[own[v]]) swap(u, v);
      Get(own[v], 1, 1, l[own[v]], 1, dep[v] - dep[own[v]] + 1);
      v = f[own[v]];
    }
  }
}
int main() {
  cin >> n;
  g.init();
  for (i = 1; i < n; i++) {
    scanf("%d %d", &u, &v);
    p[i].x = u;
    p[i].y = v;
    g.Add(u, v);
    g.Add(v, u);
  }
  for (i = 2; i <= n; i++) d[i] = 1;
  dep[1] = 1;
  DFS(1, 0);
  own[1] = 1;
  DFS_chain(1, 0);
  for (i = 1; i <= n; i++)
    if (own[i] == i) build(i);
  for (scanf("%d\n", &t); t; t--) {
    int ty, tot;
    scanf("%d", &ty);
    if (ty != 3) {
      scanf("%d", &tot);
      int v = 0;
      if (dep[p[tot].x] > dep[p[tot].y])
        v = p[tot].x;
      else
        v = p[tot].y;
      d[v] = 1 - d[v];
      Change(own[v], 1, 1, l[own[v]], dep[v] - dep[own[v]] + 1, d[v]);
    } else {
      scanf("%d %d", &u, &v);
      S = 0;
      M = -999999999;
      Lca = 0;
      Query(u, v);
      if (S == dep[u] + dep[v] - 2 * dep[Lca])
        printf("%d\n", S);
      else
        printf("-1\n");
    }
  }
  return 0;
}
