#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
typedef struct a {
  int l, r, num;
} per;
typedef struct b {
  int to, next;
} node;
per tree[maxn * 4];
node si[maxn * 2];
int n, m, ctt, head[maxn], points[maxn], cnt, fa[maxn], top[maxn], size[maxn],
    dep[maxn], id[maxn], son[maxn];
void add(int u, int v) {
  si[++ctt].next = head[u];
  si[ctt].to = v;
  head[u] = ctt;
}
void dfs(int now, int fa) {
  for (int i = head[now]; i != -1; i = si[i].next) {
    int to = si[i].to;
    if (to != fa) {
      if (i & 1)
        points[(i + 1) / 2] = to;
      else
        points[i / 2] = to;
      dfs(to, now);
    }
  }
}
void dfs1(int x, int f) {
  fa[x] = f;
  dep[x] = dep[f] + 1;
  size[x] = 1;
  int maxson = -1;
  for (int i = head[x]; i != -1; i = si[i].next) {
    int to = si[i].to;
    if (to != f) {
      dfs1(to, x);
      size[x] += size[to];
      if (size[to] > maxson) {
        maxson = size[to];
        son[x] = to;
      }
    }
  }
}
void dfs2(int x, int t) {
  id[x] = ++cnt;
  top[x] = t;
  if (!son[x]) return;
  dfs2(son[x], t);
  for (int i = head[x]; i != -1; i = si[i].next) {
    int to = si[i].to;
    if (to != son[x] && fa[x] != to) {
      dfs2(to, to);
    }
  }
}
void update(int p) {
  if (tree[p * 2].num == -1 || tree[p * 2 + 1].num == -1)
    tree[p].num = -1;
  else
    tree[p].num = tree[p * 2].num + tree[p * 2 + 1].num;
}
void build(int p, int l, int r) {
  tree[p].l = l;
  tree[p].r = r;
  if (l == r) {
    tree[p].num = 1;
    return;
  }
  build(p * 2, l, (tree[p].l + tree[p].r) / 2);
  build(p * 2 + 1, (tree[p].l + tree[p].r) / 2 + 1, r);
  update(p);
}
void change(int p, int pos, int num) {
  if (tree[p].l == tree[p].r) {
    if (num == 0)
      tree[p].num = 1;
    else
      tree[p].num = -1;
    return;
  }
  if (pos <= (tree[p].l + tree[p].r) / 2)
    change(p * 2, pos, num);
  else
    change(p * 2 + 1, pos, num);
  update(p);
}
int query(int p, int l, int r) {
  if (l > r) return 0;
  if (tree[p].l >= l && tree[p].r <= r) {
    return tree[p].num;
  }
  int tans = 0;
  if (l <= (tree[p].l + tree[p].r) / 2) tans = query(p * 2, l, r);
  if (tans == -1 || r <= (tree[p].l + tree[p].r) / 2) return tans;
  if (r > (tree[p].l + tree[p].r) / 2) {
    int temp = query(p * 2 + 1, l, r);
    if (temp == -1)
      return -1;
    else {
      return temp + tans;
    }
  }
}
void print() {
  cout << "TEST\n";
  for (int i = 1; i <= 5; ++i) {
    cout << tree[i].l << ' ' << tree[i].r << ' ' << tree[i].num << "\n";
  }
  cout << "********************\n";
}
int main() {
  cin >> n;
  int sign, u, v;
  memset(head, -1, sizeof(head));
  for (int i = 1; i < n; ++i) {
    scanf("%d%d", &u, &v);
    add(u, v);
    add(v, u);
  }
  dfs1(1, 0);
  dfs2(1, 1);
  dfs(1, 0);
  build(1, 1, n);
  cin >> m;
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d", &sign, &u);
    if (sign == 1)
      change(1, id[points[u]], 0);
    else if (sign == 2)
      change(1, id[points[u]], 1);
    else {
      scanf("%d", &v);
      int ans = 0;
      while (top[u] != top[v]) {
        if (dep[top[u]] < dep[top[v]]) swap(u, v);
        int temp = query(1, id[top[u]], id[u]);
        if (temp == -1) {
          ans = -1;
          break;
        } else
          ans += temp;
        u = fa[top[u]];
      }
      if (ans == -1)
        printf("-1\n");
      else {
        if (dep[u] > dep[v]) swap(u, v);
        int temp = query(1, id[u] + 1, id[v]);
        if (temp == -1)
          printf("-1\n");
        else
          printf("%d\n", temp + ans);
      }
    }
  }
  return 0;
}
