#include <bits/stdc++.h>
using namespace std;
const int MaxN = int(1e5) + 10;
struct edge {
  int v, num;
  edge() {}
  edge(int a, int b) { v = a, num = b; }
};
inline int get_pow(int n) {
  int t = 1;
  while (t < n) t <<= 1;
  return t;
}
struct SegTree {
  vector<int> t;
  int size;
  inline void build_tree(const vector<int> &a) {
    int maxx = get_pow((int)a.size());
    size = maxx;
    t.resize(2 * maxx);
    for (int i = maxx; i < 2 * maxx; i++) t[i] = (i < maxx + (int)a.size());
    for (int i = maxx - 1; i >= 1; i--) t[i] = t[i << 1] + t[(i << 1) + 1];
  }
  inline void update(int v, int x) {
    t[v] = x;
    v >>= 1;
    while (v) t[v] = t[v << 1] + t[(v << 1) + 1], v >>= 1;
  }
  inline int get(int v, int a, int b, int l, int r) {
    if (r < a || b < l) return 0;
    if (l <= a && b <= r) return t[v];
    int m = (a + b) >> 1;
    return get(v << 1, a, m, l, r) + get((v << 1) + 1, m + 1, b, l, r);
  }
  inline int get(int l, int r) {
    return get(1, size, 2 * size - 1, size + l, size + r);
  }
};
int n, root = 0, num;
vector<edge> gr[MaxN];
pair<int, int> edges[4 * MaxN];
vector<int> path[MaxN];
bool was[MaxN];
SegTree trees[MaxN];
int number[MaxN], depth[MaxN];
inline void dfs(int v, int dep) {
  number[v] = num;
  depth[v] = dep;
  was[v] = 1;
  for (int i = 0; i < (int)gr[v].size(); i++) {
    edge u = gr[v][i];
    if (!was[u.v]) {
      path[num].push_back(u.num);
      edges[u.num] = make_pair(num, dep + 1);
      dfs(u.v, dep + 1);
    }
  }
}
int main() {
  while (scanf("%d", &n) == 1) {
    for (int i = 0; i < n - 1; i++) {
      int a, b;
      scanf("%d%d", &a, &b);
      gr[a].push_back(edge(b, i));
      gr[b].push_back(edge(a, i));
    }
    root = 0;
    int maxx = 0;
    for (int i = 1; i <= n; i++)
      if (maxx < (int)gr[i].size()) maxx = (int)gr[i].size(), root = i;
    num = 0;
    was[root] = 1;
    for (int i = 0; i < (int)gr[root].size(); i++) {
      edge u = gr[root][i];
      path[num].clear();
      path[num].push_back(u.num);
      edges[u.num] = make_pair(num, 0);
      dfs(u.v, 0);
      ++num;
    }
    for (int i = 0; i < num; i++) trees[i].build_tree(path[i]);
    int q;
    scanf("%d", &q);
    for (int i = 0; i < q; i++) {
      int type;
      scanf("%d", &type);
      if (type <= 2) {
        int id;
        scanf("%d", &id);
        pair<int, int> tmp = edges[--id];
        trees[tmp.first].update(trees[tmp.first].size + tmp.second, type % 2);
      } else {
        int a, b;
        scanf("%d%d", &a, &b);
        if (a == b) {
          puts("0");
          continue;
        } else if (a == root) {
          int sum = trees[number[b]].get(0, depth[b]);
          printf("%d\n", (sum == depth[b] + 1) ? depth[b] + 1 : -1);
        } else if (b == root) {
          int sum = trees[number[a]].get(0, depth[a]);
          printf("%d\n", (sum == depth[a] + 1) ? depth[a] + 1 : -1);
        } else if (number[a] == number[b]) {
          int sum = trees[number[a]].get(min(depth[a], depth[b]) + 1,
                                         max(depth[a], depth[b]));
          printf("%d\n",
                 (sum == (((depth[a] - depth[b]) < 0) ? -(depth[a] - depth[b])
                                                      : (depth[a] - depth[b])))
                     ? (((depth[a] - depth[b]) < 0) ? -(depth[a] - depth[b])
                                                    : (depth[a] - depth[b]))
                     : -1);
        } else {
          int sum = trees[number[a]].get(0, depth[a]) +
                    trees[number[b]].get(0, depth[b]);
          printf("%d\n", (sum == depth[a] + depth[b] + 2)
                             ? (depth[a] + depth[b] + 2)
                             : -1);
        }
      }
    }
  }
  return 0;
}
