#include <bits/stdc++.h>
using namespace std;
unsigned int my_rand() { return rand() + rand() * RAND_MAX; }
class CT {
 public:
  CT *l, *r, *p;
  int data, y, count;
  CT(int data) : data(data), l(NULL), r(NULL), y(my_rand()), count(1) {}
};
void print(CT *tree) {
  if (!tree) return;
  cout << '(';
  print(tree->l);
  cout << tree->data;
  print(tree->r);
  cout << ')';
}
inline void up(CT *tree) {
  if (!tree) return;
  tree->count = 1;
  if (tree->l) {
    tree->l->p = tree;
    tree->count += tree->l->count;
  }
  if (tree->r) {
    tree->r->p = tree;
    tree->count += tree->r->count;
  }
}
void split(CT *tree, CT **l, CT **r, int k) {
  if (!tree) {
    *l = *r = NULL;
    return;
  }
  int lcount = 0;
  if (tree->l) lcount = tree->l->count;
  if (lcount < k) {
    *l = tree;
    split((*l)->r, &((*l)->r), r, k - lcount - 1);
    if (*r) (*r)->p = NULL;
    up(*l);
  } else {
    *r = tree;
    split((*r)->l, l, &((*r)->l), k);
    if (*l) (*l)->p = NULL;
    up(*r);
  }
}
void merge(CT **tree, CT *l, CT *r) {
  if (!l) {
    *tree = r;
    return;
  } else if (!r) {
    *tree = l;
    return;
  }
  if (l->y < r->y) {
    *tree = l;
    merge(&(*tree)->r, (*tree)->r, r);
  } else {
    *tree = r;
    merge(&(*tree)->l, l, (*tree)->l);
  }
  up(*tree);
}
int getnum(CT *tree) {
  int res = 0;
  if (tree->l) res = tree->l->count;
  while (1) {
    if (tree->p && tree->p->r == tree) res++;
    if (tree->p && tree->p->r == tree && tree->p->l) {
      res += tree->p->l->count;
    }
    if (tree->p)
      tree = tree->p;
    else
      break;
  }
  return res;
}
CT *getroot(CT *tree) {
  while (tree->p != NULL) tree = tree->p;
  return tree;
}
vector<vector<int> > gr, pr, elist;
vector<int> order, height, st2, used;
vector<vector<CT *> > posv;
void dfs(int u) {
  if (used[u]) return;
  used[u] = 1;
  order.push_back(u);
  for (int i = 0; i < gr[u].size(); i++) {
    int v = gr[u][i];
    if (used[v]) continue;
    height[v] = height[u] + 1;
    pr[v][0] = u;
    dfs(v);
  }
  order.push_back(u);
}
int lift(int u, int len) {
  for (int i = 0; len; i++) {
    if (len & 1) {
      u = pr[u][i];
    }
    len /= 2;
  }
  return u;
}
int lca(int u, int v) {
  if (height[u] < height[v])
    v = lift(v, height[v] - height[u]);
  else
    u = lift(u, height[u] - height[v]);
  if (u == v) return u;
  for (int i = st2.size() - 1; i >= 0; i--) {
    if (pr[u][i] != pr[v][i]) {
      u = pr[u][i];
      v = pr[v][i];
    }
  }
  return pr[u][0];
}
int main() {
  int n, m;
  cin >> n;
  gr.assign(n, vector<int>());
  height.assign(n, 0);
  used.assign(n, 0);
  elist.assign(n - 1, vector<int>(2, 0));
  st2.push_back(1);
  while (st2.back() < n) st2.push_back(st2.back() * 2);
  pr.assign(n, vector<int>(st2.size(), 0));
  posv.assign(n, vector<CT *>());
  for (int i = 0; i < n - 1; i++) {
    int x, y;
    cin >> x >> y;
    x--;
    y--;
    elist[i][0] = x;
    elist[i][1] = y;
    gr[x].push_back(y);
    gr[y].push_back(x);
  }
  dfs(0);
  CT *tree = NULL;
  for (int i = 0; i < order.size(); i++) {
    CT *node = new CT(order[i]);
    posv[order[i]].push_back(node);
    merge(&tree, tree, node);
  }
  for (int d = 1; d < st2.size(); d++) {
    for (int v = 1; v < n; v++) {
      pr[v][d] = pr[pr[v][d - 1]][d - 1];
    }
  }
  cin >> m;
  for (int i = 0; i < m; i++) {
    int type;
    cin >> type;
    if (type == 1) {
      int ed;
      cin >> ed;
      ed--;
      int u = elist[ed][0], v = elist[ed][1];
      if (pr[u][0] == v) swap(u, v);
      CT *ut = getroot(posv[u][0]), *vt = getroot(posv[v][0]);
      CT *l, *r;
      split(ut, &l, &r, getnum(posv[u][0]) + 1);
      merge(&l, l, vt);
      merge(&ut, l, r);
    } else if (type == 2) {
      int ed;
      cin >> ed;
      ed--;
      int u = elist[ed][0], v = elist[ed][1];
      if (pr[u][0] == v) swap(u, v);
      CT *ut = getroot(posv[u][0]), *vt;
      CT *l, *r;
      split(ut, &l, &r, getnum(posv[v][0]));
      split(r, &vt, &r, getnum(posv[v][1]) + 1);
      merge(&ut, l, r);
    } else {
      int u, v;
      cin >> u >> v;
      u--;
      v--;
      if (getroot(posv[u][0]) == getroot(posv[v][0])) {
        cout << height[u] + height[v] - 2 * height[lca(u, v)] << endl;
      } else {
        cout << -1 << endl;
      }
    }
  }
}
