#include <bits/stdc++.h>
using namespace std;
int getint() {
  unsigned int c;
  int x = 0;
  while (((c = getchar()) - '0') >= 10) {
    if (c == '-') return -getint();
    if (!~c) exit(0);
  }
  do {
    x = (x << 3) + (x << 1) + (c - '0');
  } while (((c = getchar()) - '0') < 10);
  return x;
}
template <class T>
struct FenwickTree {
  vector<T> data;
  void init(int size, T u = 0) { data.assign(size, u); }
  T sum(int srt, int end) { return sum(end) - sum(srt - 1); }
  T sum(int end) {
    T s = 0;
    for (; end >= 0; end = (end & end + 1) - 1) s += data[end];
    return s;
  }
  void add(int pos, T val) {
    for (; pos < data.size(); pos |= pos + 1) data[pos] += val;
  }
};
const int N = 100000;
vector<int> graph[N];
pair<int, int> es[N];
int n, degree[N], crit, depthFromCrit[N], pathLen[N], kind[N];
int dfs(int u, int par, int depth, int npath) {
  depthFromCrit[u] = depth;
  kind[u] = npath;
  for (int i = 0; i < graph[u].size(); i++) {
    int v = graph[u][i];
    if (v == par) continue;
    return dfs(v, u, depth + 1, npath) + 1;
  }
  return 1;
}
int main() {
  int i, j, tcc, tc = 1 << 28;
  for (tcc = 0; tcc < tc; tcc++) {
    n = getint();
    memset(degree, 0, sizeof(degree));
    for (i = 0; i < n - 1; i++) {
      int u = getint() - 1, v = getint() - 1;
      graph[u].push_back(v);
      graph[v].push_back(u);
      es[i] = make_pair(u, v);
      degree[u]++, degree[v]++;
    }
    crit = 0;
    for (i = 0; i < n; i++)
      if (degree[crit] < degree[i]) crit = i;
    memset(depthFromCrit, ~0, sizeof(depthFromCrit));
    for (i = 0; i < graph[crit].size(); i++) {
      pathLen[i] = dfs(graph[crit][i], crit, 1, i);
    }
    vector<FenwickTree<int> > bits(degree[crit]);
    for (i = 0; i < bits.size(); i++) {
      bits[i].init(pathLen[i] + 1);
      for (j = 1; j < pathLen[i] + 1; j++) bits[i].add(j, 1);
    }
    int q = getint(), d, u, v, t;
    while (q--) {
      t = getint();
      if (t == 1) {
        d = getint() - 1, u = es[d].first, v = es[d].second;
        if (v == crit) swap(u, v);
        if (u == crit)
          bits[kind[v]].add(1, -1);
        else
          bits[kind[u]].add(max(depthFromCrit[u], depthFromCrit[v]), -1);
      }
      if (t == 2) {
        d = getint() - 1, u = es[d].first, v = es[d].second;
        if (v == crit) swap(u, v);
        if (u == crit)
          bits[kind[v]].add(1, 1);
        else
          bits[kind[u]].add(max(depthFromCrit[u], depthFromCrit[v]), 1);
      }
      if (t == 3) {
        int u = getint() - 1, v = getint() - 1;
        if (u == v) {
          puts("0");
          continue;
        }
        if (v == crit) swap(u, v);
        if (u == crit) {
          int needDepth = depthFromCrit[v];
          if (bits[kind[v]].sum(depthFromCrit[v]) == needDepth)
            printf("%d\n", needDepth);
          else
            puts("-1");
        } else if (kind[u] == kind[v]) {
          if (depthFromCrit[u] > depthFromCrit[v]) swap(u, v);
          int needDepth = depthFromCrit[v] - depthFromCrit[u];
          if (bits[kind[u]].sum(depthFromCrit[u] + 1, depthFromCrit[v]) !=
              needDepth)
            puts("-1");
          else
            printf("%d\n", needDepth);
        } else {
          int needDepth1 = depthFromCrit[u], needDepth2 = depthFromCrit[v],
              ok = 1;
          if (bits[kind[u]].sum(needDepth1) != needDepth1) ok = 0;
          if (bits[kind[v]].sum(needDepth2) != needDepth2) ok = 0;
          if (ok)
            printf("%d\n", needDepth1 + needDepth2);
          else
            puts("-1");
        }
      }
    }
  }
  return 0;
}
