#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int INF = 1e9 + 7;
int cnt, n, m, pos, q, step, ans, fk;
int dep[N], si[N], son[N], top[N], w[N], fa[N];
int head[N];
struct node {
  int u, v, w;
  int next;
} edge[N * 2];
void add(int u, int v, int w) {
  edge[cnt].u = u, edge[cnt].v = v, edge[cnt].w = w;
  edge[cnt].next = head[u];
  head[u] = cnt++;
}
struct tree {
  int l, r, mid;
  int sum, co;
  int fl;
} t[N << 2];
void dfs1(int u, int fat, int de) {
  dep[u] = de;
  fa[u] = fat;
  si[u] = 1;
  son[u] = 0;
  for (int i = head[u]; i != -1; i = edge[i].next) {
    int v = edge[i].v;
    if (v == fa[u]) continue;
    dfs1(v, u, de + 1);
    si[u] += si[v];
    if (son[v] == -1 || (si[son[u]] < si[v])) son[u] = v;
  }
  return;
}
void dfs2(int u, int tp) {
  top[u] = tp;
  w[u] = ++step;
  if (son[u] > 0) dfs2(son[u], tp);
  for (int i = head[u]; i != -1; i = edge[i].next) {
    int v = edge[i].v;
    if (v == fa[u] || v == son[u]) continue;
    dfs2(v, v);
  }
}
void pushup(int rt) {
  t[rt].sum = t[rt << 1].sum + t[rt << 1 | 1].sum;
  t[rt].fl = t[rt << 1].fl | t[rt << 1 | 1].fl;
}
void build(int l, int r, int rt) {
  int m = (l + r) >> 1;
  t[rt].l = l, t[rt].r = r;
  t[rt].mid = m;
  if (l == r) {
    t[rt].fl = 0;
    t[rt].co = 1;
    t[rt].sum = 1;
    return;
  }
  build(l, m, rt << 1);
  build(m + 1, r, rt << 1 | 1);
  pushup(rt);
}
void query(int p, int q, int rt) {
  if (t[rt].l >= p && t[rt].r <= q) {
    fk = fk | t[rt].fl;
    ans += t[rt].sum;
    return;
  }
  if (p <= t[rt].mid) query(p, q, rt << 1);
  if (q > t[rt].mid) query(p, q, rt << 1 | 1);
}
void update(int pos, int flag, int rt) {
  if (t[rt].l == t[rt].r) {
    t[rt].co = flag;
    t[rt].sum = t[rt].co;
    if (t[rt].co == 0)
      t[rt].fl = 1;
    else
      t[rt].fl = 0;
    return;
  }
  if (pos <= t[rt].mid) update(pos, flag, rt << 1);
  if (pos > t[rt].mid) update(pos, flag, rt << 1 | 1);
  pushup(rt);
}
void vs(int u, int v) {
  int f1 = top[u], f2 = top[v];
  ans = 0, fk = 0;
  while (f1 != f2) {
    if (dep[f2] > dep[f1]) {
      swap(f1, f2);
      swap(u, v);
    }
    query(w[f1], w[u], 1);
    u = fa[f1];
    f1 = top[u];
  }
  if (u == v) {
    if (fk) ans = -1;
    printf("%d\n", ans);
  } else {
    if (dep[u] > dep[v]) swap(u, v);
    query(w[son[u]], w[v], 1);
    if (fk) ans = -1;
    printf("%d\n", ans);
  }
}
void slove() {
  build(0, step, 1);
  for (int i = 0; i < n - 1; i++) {
    if (dep[edge[i * 2].u] > dep[edge[i * 2].v])
      swap(edge[i * 2].u, edge[i * 2].v);
    update(w[edge[i * 2].v], edge[i * 2].w, 1);
  }
  scanf("%d", &m);
  int s, p, q;
  while (m--) {
    scanf("%d", &s);
    if (s == 1 || s == 2) {
      scanf("%d", &p);
      if (s == 1) update(w[edge[(p - 1) * 2].v], 1, 1);
      if (s == 2) {
        update(w[edge[(p - 1) * 2].v], 0, 1);
      }
    }
    if (s == 3) {
      scanf("%d%d", &p, &q);
      vs(p, q);
    }
  }
}
int main() {
  cnt = 0;
  step = 0;
  memset(head, -1, sizeof head);
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    add(u, v, 1);
    add(v, u, 1);
  }
  dfs1(1, 0, 1);
  dfs2(1, 1);
  slove();
}
