#include <bits/stdc++.h>
using namespace std;
const int bz = 10240;
char bf[bz + 1], *ppp = bf;
int ch, sg, bt = 0;
struct Arco {
  int v;
  Arco(int v) : v(v){};
};
vector<Arco> ady[100003];
int N, T[100003], P[100003][25], L[100003], DIST[100003];
void DFS(int v, int p = -1) {
  T[v] = p;
  for (int i = ady[v].size() - 1; i >= 0; i--) {
    int u = ady[v][i].v;
    if (u == p) continue;
    DIST[u] = 1 + DIST[v];
    L[u] = 1 + L[v];
    DFS(u, v);
  }
}
void Preprocesar(int *T) {
  for (int i = 0; i < N; i++)
    for (int j = 0; 1 << j < N; j++) P[i][j] = -1;
  for (int i = 0; i < N; i++) P[i][0] = T[i];
  for (int j = 1; 1 << j < N; j++)
    for (int i = 0; i < N; i++)
      if (P[i][j - 1] != -1) P[i][j] = P[P[i][j - 1]][j - 1];
}
int QUERY(int p, int q) {
  int log = 1;
  if (L[p] < L[q]) swap(p, q);
  while (1 << log <= L[p]) log++;
  log--;
  for (int i = log; i >= 0; i--)
    if (L[p] - (1 << i) >= L[q]) p = P[p][i];
  if (p == q) return p;
  for (int i = log; i >= 0; i--)
    if (P[p][i] != -1 && P[p][i] != P[q][i]) p = P[p][i], q = P[q][i];
  return T[p];
}
struct RangeTree {
  vector<long long> tree;
  int N;
  RangeTree() {}
  RangeTree(int n) {
    N = 1;
    while (N < n) N <<= 1;
    tree = vector<long long>(N << 1);
    N = n;
    CREATE(1, 1, N);
  }
  void CREATE(int n, int a, int b) {
    if (a == b) {
      tree[n] = 1;
      return;
    }
    int m = (a + b) / 2;
    CREATE(2 * n, a, m);
    CREATE(2 * n + 1, m + 1, b);
    tree[n] = tree[2 * n] + tree[2 * n + 1];
  }
  void UPDATE(int n, int a, int b, int c, int d, int k) {
    if (a > d || b < c) return;
    if (c <= a && b <= d) {
      tree[n] = k;
      return;
    }
    int m = (a + b) / 2;
    UPDATE(2 * n, a, m, c, d, k);
    UPDATE(2 * n + 1, m + 1, b, c, d, k);
    tree[n] = tree[2 * n] + tree[2 * n + 1];
  }
  long long QUERY(int n, int a, int b, int c, int d) {
    if (a > d || b < c) return 0;
    if (c <= a && b <= d) return tree[n];
    int m = (a + b) / 2;
    return QUERY(2 * n, a, m, c, d) + QUERY(2 * n + 1, m + 1, b, c, d);
  }
  void UPDATE(int p, int k) { UPDATE(1, 1, N, p, p, k); }
  long long QUERY(int a, int b) { return QUERY(1, 1, N, a, b); }
};
vector<RangeTree> tree;
int pos[100003][2];
int heavy[100003], padre[100003];
int cadena, num, aux[100003];
int explore(int v, int p = -1) {
  heavy[v] = -1;
  int x = 0;
  for (int i = ady[v].size() - 1; i >= 0; i--) {
    int u = ady[v][i].v;
    if (u == p) continue;
    int y = explore(u, v);
    if (y > x) x = y, heavy[v] = u;
  }
  return x + 1;
}
void HLD(int v, int p = -1) {
  if (p == -1) cadena = num = 0, explore(1);
  pos[v][0] = cadena, pos[v][1] = ++num;
  if (heavy[v] != -1)
    HLD(heavy[v], v);
  else
    tree.push_back(RangeTree(num));
  for (int i = ady[v].size() - 1; i >= 0; i--) {
    int u = ady[v][i].v;
    if (u == p || u == heavy[v]) continue;
    padre[++cadena] = v, num = 0;
    HLD(u, v);
  }
}
long long SEARCH(int a, int b) {
  long long sol = 0;
  while (pos[a][0] != pos[b][0]) {
    sol += tree[pos[a][0]].QUERY(1, pos[a][1]);
    a = padre[pos[a][0]];
  }
  if (a != b) sol += tree[pos[a][0]].QUERY(pos[b][1] + 1, pos[a][1]);
  return sol;
}
int arcos[100003][2], sol;
int main() {
  int v, u, i, op, q;
  scanf("%d", &N);
  for (i = 1; i < N; i++) {
    scanf("%d%d", &v, &u);
    arcos[i][0] = v, arcos[i][1] = u;
    ady[v].push_back(Arco(u));
    ady[u].push_back(Arco(v));
  }
  N++;
  DIST[1] = 0;
  DFS(1);
  Preprocesar(T);
  HLD(1);
  scanf("%d", &q);
  while (q--) {
    scanf("%d%d", &op, &v);
    if (op == 3) {
      scanf("%d", &u);
      i = QUERY(v, u);
      sol = SEARCH(v, i) + SEARCH(u, i);
      if (sol != (DIST[v] + DIST[u] - 2 * DIST[i]))
        printf("-1\n");
      else
        cout << sol << endl;
    } else {
      if (op == 1)
        u = 1;
      else
        u = 0;
      if (L[arcos[v][0]] > L[arcos[v][1]])
        v = arcos[v][0];
      else
        v = arcos[v][1];
      tree[pos[v][0]].UPDATE(pos[v][1], u);
    }
  }
  return 0;
}
