#include <bits/stdc++.h>
using namespace std;
const int inf = 100010;
const int N = 100010;
struct e {
  int v;
  e *nxt;
} es[N << 1], *fir[N];
map<pair<int, int>, int> mp;
struct node {
  int ls, rs;
  int l, r;
  int sum;
  int mid() { return (l + r) >> 1; }
} nodes[N << 2];
int n, en, val[N];
int que[N], par[N], dep[N], root[N], seg[N], st[N], ed[N], top[N], sons[N],
    id[N];
int ln, cnt, tr;
inline void init() {
  en = 0;
  memset(fir, 0, sizeof(fir));
}
inline void add_e(int u, int v) {
  es[en].v = v;
  es[en].nxt = fir[u];
  fir[u] = &es[en++];
}
inline void newNode(int &id, int l, int r) {
  nodes[cnt].ls = nodes[cnt].rs = -1;
  nodes[cnt].l = l;
  nodes[cnt].r = r;
  id = cnt++;
}
void build(int &id, int l, int r) {
  newNode(id, l, r);
  if (l + 1 >= r) {
    nodes[id].sum = 1;
    return;
  }
  int mid = (l + r) >> 1;
  build(nodes[id].ls, l, mid);
  build(nodes[id].rs, mid, r);
  nodes[id].sum = nodes[nodes[id].ls].sum + nodes[nodes[id].rs].sum;
}
void initTree() {
  int l, r, u, v, i;
  e *cur;
  l = r = 0;
  tr = 1;
  que[r++] = tr;
  par[tr] = -1;
  dep[tr] = 0;
  while (l != r) {
    u = que[l++];
    for (cur = fir[u]; cur; cur = cur->nxt) {
      if ((v = cur->v) != par[u]) {
        que[r++] = v;
        par[v] = u;
        dep[v] = dep[u] + 1;
      }
    }
  }
  for (i = 1; i <= n; i++) {
    sons[i] = 1;
    id[i] = -1;
  }
  for (i = r - 1; i >= 0; i--) {
    u = que[i];
    if (par[u] >= 0) {
      sons[par[u]] += sons[u];
    }
  }
  l = r = 0;
  que[r++] = tr;
  ln = cnt = 0;
  while (l != r) {
    u = que[l++];
    st[ln] = dep[u];
    top[ln] = u;
    while (u >= 0) {
      id[u] = ln;
      ed[ln] = dep[u];
      seg[dep[u]] = u;
      int best;
      for (cur = fir[u], best = -1; cur; cur = cur->nxt) {
        if (id[v = cur->v] == -1) {
          if (best == -1 || (best >= 0 && sons[v] > sons[best])) {
            best = v;
          }
        }
      }
      if (best >= 0) {
        for (cur = fir[u]; cur; cur = cur->nxt) {
          if (id[v = cur->v] == -1 && best != v) {
            que[r++] = v;
          }
        }
      }
      u = best;
    }
    root[ln] = -1;
    build(root[ln], st[ln], ed[ln]);
    ln++;
  }
}
int S;
void lqry(int &id, int ql, int qr) {
  if (id == -1) return;
  if (ql == qr) return;
  if (ql <= nodes[id].l && nodes[id].r <= qr) {
    S += nodes[id].sum;
    if (S > inf) S = inf;
    return;
  }
  if (nodes[id].l + 1 == nodes[id].r) {
    S += nodes[id].sum;
    if (S > inf) S = inf;
    return;
  }
  int mid = (nodes[id].l + nodes[id].r) >> 1;
  if (ql < mid) {
    lqry(nodes[id].ls, ql, qr);
  }
  if (qr > mid) {
    lqry(nodes[id].rs, ql, qr);
  }
}
void update(int id, int x, int y, int val) {
  if (id == -1) return;
  if (nodes[id].l + 1 == nodes[id].r) {
    nodes[id].sum = val;
    return;
  }
  int mid = (nodes[id].l + nodes[id].r) >> 1;
  if (mid <= x)
    update(nodes[id].rs, x, y, val);
  else if (mid >= y)
    update(nodes[id].ls, x, y, val);
  nodes[id].sum = nodes[nodes[id].ls].sum + nodes[nodes[id].rs].sum;
  if (nodes[id].sum > inf) nodes[id].sum = inf;
}
void qry(int u, int v) {
  while (id[u] != id[v]) {
    if (id[u] > id[v]) {
      swap(u, v);
    }
    int b = id[v];
    lqry(root[b], st[b], dep[v]);
    v = par[top[b]];
    if (mp.find(make_pair(top[b], par[top[b]])) != mp.end())
      S += val[mp[make_pair(top[b], par[top[b]])]];
    else
      S += val[mp[make_pair(par[top[b]], top[b])]];
    if (S > inf) S = inf;
  }
  if (dep[u] > dep[v]) {
    swap(u, v);
  }
  lqry(root[id[u]], dep[u], dep[v]);
}
struct ee {
  int x, y;
} edge[100010];
int main() {
  int m, x, y, ty;
  scanf("%d", &n);
  init();
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &x, &y);
    mp[make_pair(x, y)] = i;
    val[i] = 1;
    edge[i].x = x;
    edge[i].y = y;
    add_e(x, y);
    add_e(y, x);
  }
  initTree();
  scanf("%d", &m);
  for (int i = 0; i < m; i++) {
    scanf("%d", &ty);
    if (ty == 3) {
      scanf("%d%d", &x, &y);
      S = 0;
      qry(x, y);
      if (S >= inf)
        printf("-1\n");
      else
        printf("%d\n", S);
    } else if (ty == 1) {
      scanf("%d", &x);
      int u = edge[x].x;
      int v = edge[x].y;
      val[x] = 1;
      if (dep[u] > dep[v]) {
        swap(u, v);
      }
      if (id[u] == id[v]) update(root[id[u]], dep[u], dep[u], 1);
    } else {
      scanf("%d", &x);
      int u = edge[x].x;
      int v = edge[x].y;
      val[x] = inf;
      if (dep[u] > dep[v]) {
        swap(u, v);
      }
      if (id[u] == id[v]) update(root[id[u]], dep[u], dep[v], inf);
    }
  }
}
