#include <bits/stdc++.h>
using namespace std;
vector<int> E[100010];
int cmp[100010];
int depth[100010];
int sz[100010];
void dfs(int i, int d, int c) {
  depth[i] = d;
  cmp[i] = c;
  sz[c]++;
  int numE = E[i].size();
  for (int x = 0; x < numE; x++) {
    int j = E[i][x];
    if (depth[j] < depth[i]) continue;
    dfs(j, d + 1, c);
  }
}
pair<int, int> edge_list[100010];
struct node {
  int val;
  node* left;
  node* right;
  void init(int a, int b) {
    val = 0;
    left = NULL;
    right = NULL;
    if (a == b) return;
    int mid = (a + b) / 2;
    left = new node();
    left->init(a, mid);
    right = new node();
    right->init(mid + 1, b);
  }
  void add(int idx, int a, int b) {
    if (idx < a) return;
    if (idx > b) return;
    val++;
    if (a == b) return;
    int mid = (a + b) / 2;
    left->add(idx, a, mid);
    right->add(idx, mid + 1, b);
  }
  void remove(int idx, int a, int b) {
    if (idx < a) return;
    if (idx > b) return;
    val--;
    if (a == b) return;
    int mid = (a + b) / 2;
    left->remove(idx, a, mid);
    right->remove(idx, mid + 1, b);
  }
  int search(int idxmin, int idxmax, int a, int b) {
    if (idxmin > b) return 0;
    if (idxmax < a) return 0;
    assert(a <= b);
    assert(idxmin <= idxmax);
    if (idxmin <= a && b <= idxmax) {
      return val;
    }
    if (a == b) return 0;
    int mid = (a + b) / 2;
    int ans = 0;
    ans += left->search(idxmin, idxmax, a, mid);
    ans += right->search(idxmin, idxmax, mid + 1, b);
    return ans;
  }
};
node T[100010];
int main() {
  int N;
  cin >> N;
  int best = -1;
  for (int i = 0; i < (N - 1); i++) {
    int a, b;
    cin >> a >> b;
    E[a].push_back(b);
    E[b].push_back(a);
    edge_list[i + 1] = make_pair(a, b);
    if (best == -1 || E[a].size() > E[best].size()) best = a;
    if (best == -1 || E[b].size() > E[best].size()) best = b;
  }
  int root = best;
  for (int i = 1; i <= N; i++) {
    depth[i] = 1000000;
  }
  depth[root] = 0;
  cmp[root] = 0;
  int numE = E[root].size();
  int C = numE;
  for (int x = 0; x < numE; x++) {
    int i = E[root][x];
    dfs(i, 1, x + 1);
  }
  for (int c = 1; c <= C; c++) {
    T[c].init(0, sz[c] - 1);
  }
  T[0].init(0, 0);
  int M;
  cin >> M;
  for (int req = 0; req < M; req++) {
    int t, id;
    cin >> t;
    if (t == 1) {
      cin >> id;
      int a = edge_list[id].first;
      int b = edge_list[id].second;
      assert((cmp[a] == cmp[b]) || (cmp[a] == 0) || (cmp[b] == 0));
      int c = max(cmp[a], cmp[b]);
      int e = min(depth[a], depth[b]);
      T[c].remove(e, 0, sz[c] - 1);
    } else if (t == 2) {
      cin >> id;
      int a = edge_list[id].first;
      int b = edge_list[id].second;
      assert((cmp[a] == cmp[b]) || (cmp[a] == 0) || (cmp[b] == 0));
      int c = max(cmp[a], cmp[b]);
      int e = min(depth[a], depth[b]);
      T[c].add(e, 0, sz[c] - 1);
    } else {
      int a, b;
      cin >> a >> b;
      int c = cmp[a];
      int d = cmp[b];
      if (c != d) {
        bool good = true;
        if (T[c].search(0, depth[a] - 1, 0, sz[c] - 1) > 0) good = false;
        if (T[d].search(0, depth[b] - 1, 0, sz[d] - 1) > 0) good = false;
        if (!good) {
          cout << -1 << endl;
        } else {
          cout << (depth[a] + depth[b]) << endl;
        }
      } else {
        if (depth[a] > depth[b]) {
          int temp = a;
          a = b;
          b = temp;
        }
        if (a == b) {
          cout << 0 << endl;
        } else {
          int x = depth[a];
          int y = depth[b] - 1;
          if (T[c].search(x, y, 0, sz[c] - 1) > 0) {
            cout << -1 << endl;
          } else {
            int dist = depth[b] - depth[a];
            cout << abs(dist) << endl;
          }
        }
      }
    }
  }
}
