#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, q;
vector<int> a[N];
pair<int, int> edge[N];
bool col[N];
int par[N], sz[N], h[N];
struct LCA {
  int ti;
  int beg[N];
  int mi[N << 1][19];
  void dfs(int first) {
    mi[++ti][0] = first;
    if (!beg[first]) beg[first] = ti;
    for (int second : a[first])
      if (second != par[first]) dfs(second), mi[++ti][0] = first;
  }
  void solve() {
    fill(beg, beg + n + 1, 0);
    ti = 0;
    dfs(1);
    int Log = 31 - __builtin_clz(ti);
    for (int j = 1; j <= Log; ++j)
      for (int i = 0; i <= ti - (1 << j) + 1; ++i) {
        if (h[mi[i][j - 1]] < h[mi[i + (1 << j - 1)][j - 1]])
          mi[i][j] = mi[i][j - 1];
        else
          mi[i][j] = mi[i + (1 << j - 1)][j - 1];
      }
  }
  int lca(int first, int second) {
    int L = beg[first], R = beg[second];
    if (L > R) swap(L, R);
    int Log = 31 - __builtin_clz(R - L + 1);
    if (h[mi[L][Log]] < h[mi[R - (1 << Log) + 1][Log]]) return mi[L][Log];
    return mi[R - (1 << Log) + 1][Log];
  }
} LCA;
struct Seg {
  bool it[N << 2];
  int L[N << 2], R[N << 2];
  void build(int id, int l, int r) {
    it[id] = 1;
    if ((L[id] = l) == (R[id] = r)) return;
    int mid = l + r >> 1;
    build(id << 1, l, mid);
    build(id << 1 | 1, mid + 1, r);
  }
  void update(int id, int pos, bool val) {
    if (L[id] == pos && pos == R[id]) {
      it[id] = val;
      return;
    }
    update(id << 1 | ((L[id] + R[id] >> 1) < pos), pos, val);
    it[id] = it[id << 1] & it[id << 1 | 1];
  }
  bool get(int id, int l, int r) {
    if (l > R[id] || L[id] > r) return 1;
    if (l <= L[id] && R[id] <= r) return it[id];
    bool left = get(id << 1, l, r);
    bool right = get(id << 1 | 1, l, r);
    return left & right;
  }
} it;
void dfs(int first) {
  sz[first] = 1;
  int *ptr = nullptr;
  for (int &second : a[first])
    if (second != par[first]) {
      par[second] = first;
      h[second] = h[first] + 1;
      dfs(second);
      sz[first] += sz[second];
      if (ptr == nullptr || sz[*ptr] < sz[second]) ptr = &second;
    }
  if (ptr != nullptr) swap(a[first][0], *ptr);
}
int m, nchain;
int pos[N];
int head[N], in[N];
void hld(int first, int chain) {
  if (!head[chain]) head[chain] = first;
  pos[first] = ++m;
  in[first] = chain;
  bool ok = 0;
  for (int second : a[first])
    if (second != par[first]) {
      !ok ? hld(second, chain) : hld(second, ++nchain);
      ok = 1;
    }
}
int dist(int first, int second) {
  int z = LCA.lca(first, second);
  return h[first] + h[second] - h[z] * 2;
}
bool Get(int first, int second) {
  int z = LCA.lca(first, second);
  bool res = 1;
  while (in[first] != in[z] && res) {
    res &= it.get(1, pos[head[in[first]]], pos[first]);
    first = par[head[in[first]]];
  }
  if (first != z && res) res &= it.get(1, pos[z] + 1, pos[first]);
  while (in[second] != in[z] && res) {
    res &= it.get(1, pos[head[in[second]]], pos[second]);
    second = par[head[in[second]]];
  }
  if (second != z && res) res &= it.get(1, pos[z] + 1, pos[second]);
  return res;
}
int main() {
  ios ::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  for (int i = 1; i <= n - 1; ++i) {
    cin >> edge[i].first >> edge[i].second;
    a[edge[i].first].push_back(edge[i].second);
    a[edge[i].second].push_back(edge[i].first);
    col[i] = 1;
  }
  par[1] = h[1] = 0;
  dfs(1);
  for (int i = 1; i <= n - 1; ++i)
    if (par[edge[i].first] == edge[i].second)
      swap(edge[i].first, edge[i].second);
  LCA.solve();
  hld(1, ++nchain);
  it.build(1, 1, n);
  cin >> q;
  while (q--) {
    int type, first, second;
    cin >> type;
    if (type == 1 || type == 2) {
      int id;
      cin >> id;
      col[id] = !col[id];
      it.update(1, pos[edge[id].second], col[id]);
    } else {
      cin >> first >> second;
      cout << (Get(first, second) ? dist(first, second) : -1) << '\n';
    }
  }
  return 0;
}
