#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;
}
