#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e5 + 10;
int n, head[MAXN], siz[MAXN], f[MAXN], dep[MAXN], son[MAXN];
int rak[MAXN], top[MAXN], dfn[MAXN], cnt, tim;
pair<int, int> e[MAXN];
struct Edge {
  int v, next;
} edge[MAXN * 2];
struct Node {
  int l, r;
  long long s;
} node[MAXN * 4];
void add(int u, int v) {
  cnt++;
  edge[cnt].v = v;
  edge[cnt].next = head[u];
  head[u] = cnt;
}
void dfs1(int u, int fa, int s) {
  f[u] = fa;
  dep[u] = s;
  siz[u] = 1;
  for (int i = head[u]; ~i; i = edge[i].next) {
    int v = edge[i].v;
    if (v == fa) continue;
    dfs1(v, u, s + 1);
    siz[u] += siz[v];
    if (siz[v] > siz[son[u]]) son[u] = v;
  }
}
void dfs2(int u, int t) {
  top[u] = t;
  dfn[u] = ++tim;
  rak[tim] = u;
  if (!son[u]) return;
  dfs2(son[u], t);
  for (int i = head[u]; ~i; i = edge[i].next) {
    int v = edge[i].v;
    if (v != son[u] && v != f[u]) dfs2(v, v);
  }
}
inline void up(int rt) {
  node[rt].s = node[(rt << 1)].s + node[(rt << 1 | 1)].s;
}
void build(int rt, int l, int r) {
  node[rt].l = l, node[rt].r = r;
  if (l == r) {
    node[rt].s = 1;
    return;
  }
  int mid = ((l + r) >> 1);
  build((rt << 1), l, mid);
  build((rt << 1 | 1), mid + 1, r);
  up(rt);
}
void update(int rt, int x, long long k) {
  if (node[rt].l == node[rt].r) {
    node[rt].s = k;
    return;
  }
  int mid = ((node[rt].l + node[rt].r) >> 1);
  if (x <= mid)
    update((rt << 1), x, k);
  else
    update((rt << 1 | 1), x, k);
  up(rt);
}
long long query(int rt, int l, int r) {
  if (node[rt].l == l && node[rt].r == r) return node[rt].s;
  int mid = ((node[rt].l + node[rt].r) >> 1);
  if (r <= mid)
    return query((rt << 1), l, r);
  else if (l > mid)
    return query((rt << 1 | 1), l, r);
  else
    return query((rt << 1), l, mid) + query((rt << 1 | 1), mid + 1, r);
}
long long sum(int u, int v) {
  long long ret = 0;
  while (top[u] != top[v]) {
    if (dep[top[u]] < dep[top[v]]) swap(u, v);
    ret += query(1, dfn[top[u]], dfn[u]);
    u = f[top[u]];
  }
  if (u == v) return ret;
  if (dep[u] > dep[v]) swap(u, v);
  ret += query(1, dfn[son[u]], dfn[v]);
  return ret;
}
int main() {
  memset(head, -1, sizeof head);
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    add(x, y);
    add(y, x);
    e[i] = pair<int, int>(x, y);
  }
  dfs1(1, 1, 1);
  dfs2(1, 1);
  build(1, 1, n);
  int m, opt;
  cin >> m;
  while (m--) {
    scanf("%d", &opt);
    if (opt == 3) {
      int a, b;
      scanf("%d%d", &a, &b);
      long long ans = sum(a, b);
      if (ans >= INF)
        printf("-1\n");
      else
        printf("%d\n", ans);
    } else {
      int a;
      scanf("%d", &a);
      int u = e[a].first;
      int v = e[a].second;
      if (dep[u] < dep[v]) swap(u, v);
      if (opt == 1)
        update(1, dfn[u], 1);
      else
        update(1, dfn[u], INF);
    }
  }
  return 0;
}
