#include <bits/stdc++.h>
using namespace std;
vector<int> v[100005];
struct muchii {
  int x, y;
} muc[100005];
int n, innod[100005], inpath[100005], viz[100005];
vector<int> aib[100005];
int query(int k, int x) {
  int ans = 0;
  for (; x; x -= ((x ^ (x - 1)) & x)) ans += aib[k][x];
  return ans;
}
void update(int k, int x, int val) {
  for (; x < aib[k].size(); x += ((x ^ (x - 1)) & x)) aib[k][x] += val;
}
int main() {
  int i, tata, indnod, x, y, rad = 1, nrq, tip, ind, ind2;
  cin >> n;
  for (i = 1; i < n; i++) {
    cin >> x >> y;
    v[x].push_back(y);
    v[y].push_back(x);
    muc[i].x = x;
    muc[i].y = y;
  }
  for (i = 2; i <= n; i++)
    if (v[i].size() > 2) {
      rad = i;
      break;
    }
  int cntpath = 1, aux;
  for (auto nodinceput : v[rad]) {
    indnod = 1;
    tata = rad;
    for (y = nodinceput;;) {
      inpath[y] = cntpath;
      innod[y] = indnod;
      indnod++;
      if (v[y].size() == 1) break;
      aux = tata;
      tata = y;
      y = v[tata][0];
      if (y == aux) y = v[tata][1];
    }
    aib[cntpath].resize(indnod + 2);
    cntpath++;
  }
  cin >> nrq;
  while (nrq--) {
    cin >> tip >> ind;
    if (tip == 1) {
      update(max(inpath[muc[ind].x], inpath[muc[ind].y]),
             max(innod[muc[ind].x], innod[muc[ind].y]), -1);
    } else if (tip == 2) {
      update(max(inpath[muc[ind].x], inpath[muc[ind].y]),
             max(innod[muc[ind].x], innod[muc[ind].y]), 1);
    } else {
      cin >> ind2;
      if (inpath[ind] == inpath[ind2]) {
        if (query(inpath[ind], innod[ind]) == query(inpath[ind2], innod[ind2]))
          cout << abs(innod[ind] - innod[ind2]) << "\n";
        else
          cout << -1 << "\n";
      } else {
        if (query(inpath[ind], innod[ind]) + query(inpath[ind2], innod[ind2]) >
            0)
          cout << -1 << "\n";
        else
          cout << innod[ind] + innod[ind2] << "\n";
      }
    }
  }
  return 0;
}
