#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:66777216")
using namespace std;
long long inf = 1e9 + 7;
long long INF = 1e18;
int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
struct stree {
  int inf = (int)1e9;
  int n;
  vector<int> t;
  stree() = default;
  stree(vector<int> a) {
    n = 1;
    while (n < a.size()) n *= 2;
    t.assign(n + n, 0);
    for (int i = 0; i < a.size(); i++) t[n + i] = a[i];
    for (int i = n - 1; i > 0; i--) t[i] = t[i + i] + t[i + i + 1];
  }
  void change(int x, int i) {
    t[i += n] = x;
    for (i /= 2; i > 0; i /= 2) t[i] = t[i + i] + t[i + i + 1];
  }
  int sum(int l, int r) {
    int res = 0;
    for (l += n, r += n; r >= l; l /= 2, r /= 2) {
      if (l % 2 == 1) res += t[l++];
      if (r % 2 == 0) res += t[r--];
    }
    return res;
  }
};
struct chain {
  int v;
  int n;
  stree tree;
  chain(int v, int n = 0) : v(v), n(n) {}
  void build() { tree = stree(vector<int>(n)); }
};
vector<int> p[100000];
vector<pair<int, int> > g[100000];
vector<chain> C;
int I[100000], J[100000];
int sz[100000], dep[100000], r[100000];
int root;
int ConstMax = 19;
void dfs(int v, int par, int rib) {
  if (rib != -1) r[rib] = v;
  sz[v] = 1;
  if (par != -1) dep[v] = dep[par] + 1;
  p[v][0] = max(par, 0);
  for (int i = 1; i < ConstMax; i++) p[v][i] = p[p[v][i - 1]][i - 1];
  for (int i = 0; i < g[v].size(); i++) {
    if (g[v][i].first != par) {
      dfs(g[v][i].first, v, g[v][i].second);
      sz[v] += sz[g[v][i].first];
    }
  }
}
int parent(int v, int h) {
  for (int i = 0; i < ConstMax; i++)
    if (((h) & (1 << i)) != 0) v = p[v][i];
  return v;
}
int LCA(int a, int b) {
  if (dep[a] < dep[b]) swap(a, b);
  a = parent(a, dep[a] - dep[b]);
  if (a == b) return a;
  for (int i = ConstMax - 1; i >= 0; i--) {
    if (p[a][i] != p[b][i]) {
      a = p[a][i];
      b = p[b][i];
    }
  }
  return p[a][0];
}
int dist(int a, int b) { return abs(dep[b] - dep[a]); }
void hl(int v, int par) {
  if (par != -1 && sz[v] * 2 >= sz[par]) {
    I[v] = I[par];
    J[v] = J[par] + 1;
    C[I[v]].n++;
  } else {
    I[v] = C.size();
    J[v] = 0;
    C.push_back(chain(par, 1));
  }
  for (int i = 0; i < g[v].size(); i++)
    if (g[v][i].first != par) hl(g[v][i].first, v);
}
void color(int rib, int c) {
  int v = r[rib];
  C[I[v]].tree.change(c, J[v]);
}
int count(int v, int s) {
  if (s == v) return 0;
  int sum = 0;
  s = parent(v, dist(v, s) - 1);
  while (I[v] != I[s]) {
    sum += C[I[v]].tree.sum(0, J[v]);
    v = parent(v, C[I[v]].n - J[v]);
  }
  sum += C[I[v]].tree.sum(min(J[s], J[v]), max(J[v], J[s]));
  return sum;
}
int main() {
  ios_base::sync_with_stdio(false);
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) p[i] = vector<int>(ConstMax, 0);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g[a].push_back({b, i});
    g[b].push_back({a, i});
  }
  root = 0;
  for (int i = 0; i < n; i++)
    if (g[i].size() > g[root].size()) root = i;
  dfs(root, -1, -1);
  hl(root, -1);
  for (int i = 0; i < C.size(); i++) C[i].build();
  int m;
  cin >> m;
  for (int i = 0; i < m; i++) {
    int type;
    cin >> type;
    if (type == 1) {
      int rib;
      cin >> rib;
      rib--;
      color(rib, 0);
    } else if (type == 2) {
      int rib;
      cin >> rib;
      rib--;
      color(rib, 1);
    } else {
      int a, b;
      cin >> a >> b;
      a--;
      b--;
      int c;
      if (I[a] != I[b])
        c = root;
      else
        c = LCA(a, b);
      int sum = count(a, c) + count(b, c);
      if (sum == 0)
        cout << dist(a, c) + dist(b, c) << "\n";
      else
        cout << -1 << "\n";
    }
  }
  return 0;
}
