#include <bits/stdc++.h>
using namespace std;
const int N = 200000 + 5, E = N * 2;
int par[N], sz[N], dpth[N], pos[N], chhead[N], HeavyCh[N], head[N], nxt[E],
    to[E], edjcnt;
int n, t, curpos;
pair<int, int> seg[4 * N + 5];
pair<int, int> mrg(pair<int, int> l, pair<int, int> r) {
  return {l.first + r.first, (l.second < r.second ? l.second : r.second)};
}
void build(int nd = 0, int ns = 0, int ne = n - 1) {
  if (ns == ne) {
    seg[nd] = {1, 1};
    return;
  }
  int l = 2 * nd + 1;
  int r = l + 1;
  int mid = ns + (ne - ns) / 2;
  build(l, ns, mid);
  build(r, mid + 1, ne);
  seg[nd] = mrg(seg[l], seg[r]);
}
void update(int pos, int nd = 0, int ns = 0, int ne = n - 1) {
  if (pos > ne || pos < ns) return;
  if (ns == ne) {
    seg[nd] = {1 - seg[nd].first, 1 - seg[nd].first};
    return;
  }
  int l = 2 * nd + 1;
  int r = l + 1;
  int mid = ns + (ne - ns) / 2;
  update(pos, l, ns, mid);
  update(pos, r, mid + 1, ne);
  seg[nd] = mrg(seg[l], seg[r]);
}
pair<int, int> query(int qs, int qe, int nd = 0, int ns = 0, int ne = n - 1) {
  if (qs > ne || qe < ns) return {0, 1};
  if (ns >= qs && ne <= qe) return seg[nd];
  int l = 2 * nd + 1;
  int r = l + 1;
  int mid = ns + (ne - ns) / 2;
  return mrg(query(qs, qe, l, ns, mid), query(qs, qe, r, mid + 1, ne));
}
void addEdge(int a, int b) {
  nxt[edjcnt] = head[a];
  head[a] = edjcnt;
  to[edjcnt++] = b;
}
void addBiEdge(int a, int b) {
  addEdge(a, b);
  addEdge(b, a);
}
void init() {
  curpos = 0;
  par[0] = -1;
  memset(head, -1, n * sizeof(head[0]));
  edjcnt = 0;
}
void calcsz(int u = 0) {
  HeavyCh[u] = -1;
  int mx = 0;
  int mxv;
  sz[u] = 1;
  for (int e = head[u], v; ~e && ((v = to[e]), 1); e = nxt[e]) {
    if (par[u] == v) continue;
    par[v] = u;
    dpth[v] = dpth[u] + 1;
    calcsz(v);
    sz[u] += sz[v];
    if (sz[v] > mx) {
      mx = sz[v];
      mxv = v;
    }
  }
  if (mx * 2 > sz[u]) HeavyCh[u] = mxv;
}
void HLD(int u = 0, int c = 0) {
  if (u == -1) return;
  pos[u] = curpos++;
  chhead[u] = c;
  HLD(HeavyCh[u], c);
  for (int e = head[u], v; ~e && ((v = to[e]), 1); e = nxt[e]) {
    if (par[u] == v || v == HeavyCh[u]) continue;
    HLD(v, v);
  }
}
pair<int, int> getans(int u, int v) {
  pair<int, int> p = {0, 1};
  while (chhead[u] != chhead[v]) {
    if (dpth[chhead[v]] > dpth[chhead[u]]) {
      swap(u, v);
    }
    p = mrg(p, query(pos[chhead[u]], pos[u]));
    u = par[chhead[u]];
  }
  if (dpth[u] > dpth[v]) swap(u, v);
  p = mrg(p, query(pos[u] + 1, pos[v]));
  return p;
}
int m, q;
int u, v;
long long c;
int ty;
int main() {
  scanf("%d", &n);
  init();
  for (int i = 0; i < n - 1; i++) {
    scanf("%d%d", &u, &v);
    addBiEdge(--u, --v);
  }
  calcsz();
  HLD();
  build();
  scanf("%d", &m);
  int a, b;
  long long x;
  while (m--) {
    scanf("%d", &ty);
    if (ty == 3) {
      scanf("%d%d", &a, &b);
      pair<int, int> res = getans(a - 1, b - 1);
      if (!res.second)
        printf("-1\n");
      else
        printf("%d\n", res.first);
    } else {
      scanf("%d", &a);
      a--;
      a *= 2;
      int chld;
      if (par[to[a]] == to[a ^ 1])
        chld = to[a];
      else
        chld = to[a ^ 1];
      update(pos[chld]);
    }
  }
  return 0;
}
