#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10, INF = 0x3f3f3f3f;
template <class T>
inline T Read(T &r) {
  int b = 1, c = getchar();
  r = 0;
  while (c < '0' || '9' < c) b = c == '-' ? -1 : b, c = getchar();
  while ('0' <= c && c <= '9')
    r = (r << 1) + (r << 3) + (c ^ '0'), c = getchar();
  return r *= b;
}
struct GRAPH {
  int head[N], to[N << 1], nxt[N << 1], ncnt;
  GRAPH() { ncnt = 1; }
  void AddEdge(const int &u, const int &v) {
    int p = ++ncnt, q = ++ncnt;
    to[p] = v, nxt[p] = head[u], head[u] = p;
    to[q] = u, nxt[q] = head[v], head[v] = q;
  }
  inline int operator[](const int &u) { return head[u]; }
} Gr;
int n, nary, m;
bool typ[N];
int dep[N], dcnt[N], clo[N], ope[N], ary[N << 1], gto[N];
struct DATA {
  int omxd, omnd, emxd, emnd, omxLM, omxMR, emxLM, emxMR, omx, emx;
  inline friend DATA operator+(const DATA &L, const DATA &R) {
    return (DATA){
        max(L.omxd, R.omxd),
        min(L.omnd, R.omnd),
        max(L.emxd, R.emxd),
        min(L.emnd, R.emnd),
        max(max(L.omxLM, R.omxLM), L.omxd - 2 * min(R.omnd, R.emnd)),
        max(max(L.omxMR, R.omxMR), R.omxd - 2 * min(L.omnd, L.emnd)),
        max(max(L.emxLM, R.emxLM), L.emxd - 2 * min(R.omnd, R.emnd)),
        max(max(L.emxMR, R.emxMR), R.emxd - 2 * min(L.omnd, L.emnd)),
        max(max(L.omx, R.omx), max(max(L.omxd + R.emxMR, L.emxd + R.omxMR),
                                   max(L.omxLM + R.emxd, L.emxLM + R.omxd))),
        max(max(L.emx, R.emx), max(max(L.emxd + R.emxMR, L.omxd + R.omxMR),
                                   max(L.emxLM + R.emxd, L.omxLM + R.omxd)))};
  }
  inline DATA operator~() const {
    return (DATA){emxd, emnd, omxd, omnd, emxLM, emxMR, omxLM, omxMR, omx, emx};
  }
};
struct SEGTREE {
  DATA seg[N << 2];
  bool rev[N << 2];
  inline void InitOdd(const int &u, const int &d) {
    seg[u] = (DATA){d, d, -INF, INF, -d, -d, -INF, -INF, -INF, 0};
  }
  inline void InitEve(const int &u, const int &d) {
    seg[u] = (DATA){-INF, INF, d, d, -INF, -INF, -d, -d, -INF, 0};
  }
  void PushUp(const int &le, const int &ri) {
    int mi = (le + ri) >> 1;
    seg[(((le) + (ri)) | ((le) != (ri)))] =
        seg[(((le) + (mi)) | ((le) != (mi)))] +
        seg[(((mi + 1) + (ri)) | ((mi + 1) != (ri)))];
  }
  void Update(const int &u) { rev[u] = !rev[u], seg[u] = ~seg[u]; }
  void PushDown(const int &le, const int &ri) {
    if (!rev[(((le) + (ri)) | ((le) != (ri)))]) return;
    int mi = (le + ri) >> 1;
    Update((((le) + (mi)) | ((le) != (mi)))),
        Update((((mi + 1) + (ri)) | ((mi + 1) != (ri))));
    rev[(((le) + (ri)) | ((le) != (ri)))] = false;
  }
  void Build(const int &le, const int &ri) {
    if (le == ri) {
      int v = ary[le];
      if (dcnt[v] & 1)
        InitOdd((((le) + (ri)) | ((le) != (ri))), dep[v]);
      else
        InitEve((((le) + (ri)) | ((le) != (ri))), dep[v]);
      return;
    }
    int mi = (le + ri) >> 1;
    Build(le, mi), Build(mi + 1, ri);
    PushUp(le, ri);
  }
  void Reverse(const int &le, const int &ri, const int &Le, const int &Ri) {
    if (Le <= le && ri <= Ri) {
      Update((((le) + (ri)) | ((le) != (ri))));
      return;
    }
    PushDown(le, ri);
    int mi = (le + ri) >> 1;
    if (Le <= mi) Reverse(le, mi, Le, Ri);
    if (mi < Ri) Reverse(mi + 1, ri, Le, Ri);
    PushUp(le, ri);
  }
  int Root() { return seg[(((1) + (nary)) | ((1) != (nary)))].emx; }
} Se;
void DFS(const int &u, const int &fa) {
  dep[ary[ope[u] = clo[u] = ++nary] = u] = dep[fa] + 1;
  for (int it = Gr[u]; it; it = Gr.nxt[it]) {
    int v = Gr.to[it];
    if (v == fa) continue;
    dcnt[v] = dcnt[u] + typ[it >> 1];
    gto[it >> 1] = v;
    DFS(v, u);
    ary[clo[u] = ++nary] = u;
  }
}
int main() {
  Read(n);
  for (int i = 1, u, v; i < n; i++) {
    Read(u), Read(v), Read(typ[i]);
    Gr.AddEdge(u, v);
  }
  DFS(1, 0);
  Se.Build(1, nary);
  Read(m);
  while (m--) {
    int it, u;
    Read(it), u = gto[it];
    Se.Reverse(1, nary, ope[u], clo[u]);
    printf("%d\n", Se.Root());
  }
  return 0;
}
