#include <bits/stdc++.h>
using namespace std;
const int N = 200100;
int depth[N], size[N], top[N], son[N];
int father[N], pre[N * 2];
int index1, loc, val[N], num[N << 2];
char com[10];
int sans;
struct E {
  int v, next, w;
} edge[N * 2];
struct Edge {
  int x, y, id, w;
} tt[N];
void init(int n) {
  memset(pre, -1, sizeof(pre));
  memset(num, 0, sizeof(num));
  index1 = 0;
  loc = 0;
}
void add_edge(int x, int y, int w) {
  edge[index1].v = y;
  edge[index1].w = w;
  edge[index1].next = pre[x];
  pre[x] = index1++;
}
void dfs(int x, int fa, int dep) {
  size[x] = 0;
  son[x] = 0;
  depth[x] = dep + 1;
  for (int i = pre[x]; i != -1; i = edge[i].next) {
    int u = edge[i].v;
    if (u != fa) {
      father[u] = x;
      dfs(u, x, dep + 1);
      if (size[u] > size[son[x]]) {
        son[x] = u;
      }
      size[x] += size[u];
    }
  }
  size[x]++;
}
void find_link(int x, int tp) {
  top[x] = tp;
  val[x] = ++loc;
  if (son[x] != 0) {
    find_link(son[x], tp);
  }
  for (int i = pre[x]; i != -1; i = edge[i].next) {
    int u = edge[i].v;
    if (u != son[x] && father[u] == x) {
      find_link(u, u);
    }
  }
}
void update(int left, int right, int id, int c, int idx) {
  if (left == right) {
    num[idx] = c;
    return;
  }
  int mid = (left + right) >> 1;
  if (mid < id) {
    update(mid + 1, right, id, c, idx << 1 | 1);
  } else {
    update(left, mid, id, c, idx << 1);
  }
  num[idx] = num[idx << 1] + num[idx << 1 | 1];
}
int query(int left, int right, int L, int R, int idx) {
  if (left >= L && right <= R) {
    return num[idx];
  }
  int mid = (left + right) >> 1;
  if (mid < L) {
    return query(mid + 1, right, L, R, idx << 1 | 1);
  } else if (mid >= R) {
    return query(left, mid, L, R, idx << 1);
  } else {
    return query(left, mid, L, mid, idx << 1) +
           query(mid + 1, right, mid + 1, R, idx << 1 | 1);
  }
}
int find(int va, int vb) {
  int f1 = top[va], f2 = top[vb], tmp = 0;
  while (f1 != f2) {
    if (depth[f1] < depth[f2]) {
      swap(f1, f2);
      swap(va, vb);
    }
    sans += depth[va] - depth[father[f1]];
    tmp += query(1, loc, val[f1], val[va], 1);
    va = father[f1];
    f1 = top[va];
  }
  if (va == vb) return tmp;
  if (depth[va] > depth[vb]) swap(va, vb);
  sans += depth[vb] - depth[va];
  return tmp + query(1, loc, val[va] + 1, val[vb], 1);
}
int main(void) {
  int T, n, x, y;
  scanf("%d", &n);
  init(n);
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &tt[i].x, &tt[i].y);
    tt[i].w = 1;
    tt[i].id = i;
    add_edge(tt[i].x, tt[i].y, 1);
    add_edge(tt[i].y, tt[i].x, 1);
  }
  dfs(1, -1, 0);
  find_link(1, 1);
  for (int i = 1; i < n; i++) {
    if (depth[tt[i].x] > depth[tt[i].y]) {
      update(1, loc, val[tt[i].x], 1, 1);
    } else {
      update(1, loc, val[tt[i].y], 1, 1);
    }
  }
  int op, m;
  scanf("%d", &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d", &op);
    if (op == 1) {
      scanf("%d", &x);
      if (depth[tt[x].x] > depth[tt[x].y]) {
        update(1, loc, val[tt[x].x], 1, 1);
      } else {
        update(1, loc, val[tt[x].y], 1, 1);
      }
    } else if (op == 2) {
      scanf("%d", &x);
      if (depth[tt[x].x] > depth[tt[x].y]) {
        update(1, loc, val[tt[x].x], 0, 1);
      } else {
        update(1, loc, val[tt[x].y], 0, 1);
      }
    } else if (op == 3) {
      scanf("%d%d", &x, &y);
      sans = 0;
      int ans = find(x, y);
      if (sans == ans) {
        printf("%d\n", ans);
      } else {
        printf("-1\n");
      }
    }
  }
  return 0;
}
