#include <bits/stdc++.h>   using namespace std;   #pragma GCC optimize( O3 )   mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());   int get_random() {     static uniform_int_distribution<int> dist(0, 1e9 + 6);     return dist(rng);   }   template <class T>   void make_unique(T& v) {     sort(v.begin(), v.end());     v.erase(unique(v.begin(), v.end()), v.end());   }   int geti() {     int x;     cin >> x;     return x;   }   long long getll() {     long long x;     cin >> x;     return x;   }   double getd() {     double x;     cin >> x;     return x;   }   const int MAXN = 5e5 + 100;   void solve(int tt) {}   template <class S, S (*op)(S, S), S (*e)(), class F, S (*mapping)(F, S),             F (*composition)(F, F), F (*id)()>   struct segment_tree {     int _l, _r;     vector<S> a;     vector<S> tree;     vector<F> lazy;     void push(int l, int r, int node) {       if (lazy[node] != id()) {         int mid = (l + r) / 2;         int rnode = node + (mid - l + 1) * 2;         tree[node + 1] = mapping(lazy[node], tree[node + 1]);         lazy[node + 1] = composition(lazy[node], lazy[node + 1]);         tree[rnode] = mapping(lazy[node], tree[rnode]);         lazy[rnode] = composition(lazy[node], lazy[rnode]);         lazy[node] = id();       }     }     void build(int l, int r, int node) {       if (l == r)         tree[node] = a[l];       else {         int mid = l + (r - l) / 2;         int rnode = node + (mid - l + 1) * 2;         build(l, mid, node + 1);         build(mid + 1, r, rnode);         tree[node] = op(tree[node + 1], tree[rnode]);       }     }     void update(F v, int left, int right, int l, int r, int node) {       if (left > right) return;       if (right < l || r < left) return;       if (left <= l && r <= right) {         tree[node] = mapping(v, tree[node]);         lazy[node] = composition(v, lazy[node]);       } else {         push(l, r, node);         int mid = l + (r - l) / 2;         int rnode = node + (mid - l + 1) * 2;         update(v, left, right, l, mid, node + 1);         update(v, left, right, mid + 1, r, rnode);         tree[node] = op(tree[node + 1], tree[rnode]);       }     }     S query(int left, int right, int l, int r, int node) {       if (left > right) return e();       if (right < l || r < left) return e();       if (left <= l && r <= right) return tree[node];       push(l, r, node);       int mid = l + (r - l) / 2;       int rnode = node + (mid - l + 1) * 2;       S r1 = query(left, right, l, mid, node + 1);       S r2 = query(left, right, mid + 1, r, rnode);       return op(r1, r2);     }     vector<S> get_tree() {       vector<S> res;       for (int i = _l; i <= _r; i++) {         res.push_back(query(i, i));       }       return res;     }     void init(int l, int r) {       _l = l;       _r = r;       a.assign(r + 1, e());       tree.assign(2 * r + 1, e());       lazy.assign(2 * r + 1, id());     }     S& operator[](int idx) { return a[idx]; }     void build() { build(_l, _r, 0); }     void update(F v, int left, int right) { update(v, left, right, _l, _r, 0); }     S query(int left, int right) { return query(left, right, _l, _r, 0); }   };   long long zero() { return 0; }   long long int_max() { return INT_MAX; }   long long int_min() { return INT_MIN; }   long long get_min(long long x, long long y) { return min(x, y); }   long long get_max(long long x, long long y) { return max(x, y); }   long long add(long long x, long long y) { return x + y; }   long long mul(long long x, long long y) { return x * y; }   pair<int, int> f1(pair<int, int> x, pair<int, int> y) {     return pair<int, int>({min(x.first, y.first), max(x.second, y.second)});   };   pair<int, int> f2() { return pair<int, int>({1e9, -1e9}); };   pair<int, int> f3(int x, pair<int, int> y) {     return pair<int, int>(         {min(y.second * x, y.first * x), max(y.second * x, y.first * x)});   };   int f4(int x, int y) { return x * y; };   int f5() { return 1; };   segment_tree<pair<int, int>, f1, f2, int, f3, f4, f5> segt;   vector<int> graph1[MAXN];   vector<int> graph2[MAXN];   int in[MAXN], out[MAXN], level[MAXN], t = 1;   int cnt[MAXN];   int n;   void dfs(int i, int p, int c, int l) {     ;     ;     in[i] = t++;     cnt[in[i]] = c;     segt[in[i]] = (c % 2 ? pair<int, int>({-l, -l}) : pair<int, int>({l, l}));     level[i] = l;     for (auto j : graph1[i]) {       if (j == p) continue;       dfs(j, i, c, l + 1);     }     for (auto j : graph2[i]) {       if (j == p) continue;       dfs(j, i, c + 1, l + 1);     }     out[i] = t;   }   pair<int, int> find_root() {     queue<int> q({1});     vector<int> vis(n + 1);     vis[1] = 1;     int res1 = 1;     while (q.size()) {       int len = q.size();       while (len--) {         auto f = q.front();         q.pop();         for (auto p : graph1[f]) {           if (!vis[p]) {             q.push(p);             res1 = p;             vis[p] = 1;           }         }         for (auto p : graph2[f]) {           if (!vis[p]) {             q.push(p);             res1 = p;             vis[p] = 1;           }         }       }     }     int res2 = res1;     q.push(res1);     vis = vector<int>(n + 1);     vis[res1] = 1;     while (q.size()) {       int len = q.size();       while (len--) {         auto f = q.front();         q.pop();         for (auto p : graph1[f]) {           if (!vis[p]) {             q.push(p);             res2 = p;             vis[p] = 1;           }         }         for (auto p : graph2[f]) {           if (!vis[p]) {             q.push(p);             res2 = p;             vis[p] = 1;           }         }       }     }     return {res1, res2};   }   int main(int argc, char* argv[]) {     ios::sync_with_stdio(false);     cin.tie(nullptr);     cout.tie(nullptr);     cin >> n;     int u, v, tp;     vector<int> us, vs;     for (auto i = (0); i < (n - 1); i++) {       cin >> u >> v >> tp;       if (tp == 0) {         graph1[u].push_back(v);         graph1[v].push_back(u);       } else {         graph2[u].push_back(v);         graph2[v].push_back(u);       }       us.push_back(u);       vs.push_back(v);     }     pair<int, int> roots = find_root();     segt.init(1, n);     t = 1;     dfs(roots.first, -1, 0, 0);     segt.build();     int m;     cin >> m;     vector<int> idxs;     for (auto i = (0); i < (m); i++) {       int idx;       cin >> idx;       idx--;       idxs.push_back(idx);     }     vector<int> res1(m), res2(m);     for (auto i = (0); i < (m); i++) {       int idx = idxs[i];       u = us[idx], v = vs[idx];       if (level[u] > level[v]) swap(u, v);       ;       ;       segt.update(-1, in[v], out[v] - 1);       res1[i] = segt.query(1, n).second;     }     segt.init(1, n);     t = 1;     dfs(roots.second, -1, 0, 0);     segt.build();     ;     ;     ;     ;     for (auto i = (0); i < (m); i++) {       int idx = idxs[i];       u = us[idx], v = vs[idx];       if (level[u] > level[v]) swap(u, v);       ;       ;       segt.update(-1, in[v], out[v] - 1);       res2[i] = segt.query(1, n).second;     }     for (auto i = (0); i < (m); i++) {       cout << max(res1[i], res2[i]) << endl;     }     return 0;   }