#include <bits/stdc++.h>
using namespace std;
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  os << '{';
  string sep;
  for (const auto &x : v) os << sep << x, sep = ", ";
  return os << '}';
}
template <typename T, size_t size>
ostream &operator<<(ostream &os, const array<T, size> &arr) {
  os << '{';
  string sep;
  for (const auto &x : arr) os << sep << x, sep = ", ";
  return os << '}';
}
template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) {
  return os << '(' << p.first << ", " << p.second << ')';
}
void dbg_out() { cerr << endl; }
template <typename Head, typename... Tail>
void dbg_out(Head H, Tail... T) {
  cerr << ' ' << H;
  dbg_out(T...);
}
template <typename T, bool maximum_mode = false>
struct RMQ {
  int n = 0;
  vector<T> values;
  vector<vector<int>> range_low;
  RMQ(const vector<T> &_values = {}) {
    if (!_values.empty()) build(_values);
  }
  static int largest_bit(int x) { return x == 0 ? -1 : 31 - __builtin_clz(x); }
  int better_index(int a, int b) const {
    return (maximum_mode ? values[b] < values[a] : values[a] < values[b]) ? a
                                                                          : b;
  }
  void build(const vector<T> &_values) {
    values = _values;
    n = int(values.size());
    int levels = largest_bit(n) + 1;
    range_low.resize(levels);
    for (int k = 0; k < levels; k++) range_low[k].resize(n - (1 << k) + 1);
    for (int i = 0; i < n; i++) range_low[0][i] = i;
    for (int k = 1; k < levels; k++)
      for (int i = 0; i <= n - (1 << k); i++)
        range_low[k][i] = better_index(range_low[k - 1][i],
                                       range_low[k - 1][i + (1 << (k - 1))]);
  }
  int query_index(int a, int b) const {
    assert(0 <= a && a < b && b <= n);
    int level = largest_bit(b - a);
    return better_index(range_low[level][a],
                        range_low[level][b - (1 << level)]);
  }
  T query_value(int a, int b) const { return values[query_index(a, b)]; }
};
struct LCA {
  int n = 0;
  vector<vector<int>> adj;
  vector<int> parent, depth, subtree_size;
  vector<int> euler, first_occurrence;
  vector<int> tour_start, tour_end, postorder;
  vector<int> tour_list, rev_tour_list;
  vector<int> heavy_root;
  RMQ<int> rmq;
  bool built;
  LCA(int _n = 0) { init(_n); }
  LCA(const vector<vector<int>> &_adj) { init(_adj); }
  void init(int _n) {
    n = _n;
    adj.assign(n, {});
    parent.resize(n);
    depth.resize(n);
    subtree_size.resize(n);
    first_occurrence.resize(n);
    tour_start.resize(n);
    tour_end.resize(n);
    postorder.resize(n);
    tour_list.resize(n);
    heavy_root.resize(n);
    built = false;
  }
  void init(const vector<vector<int>> &_adj) {
    init(int(_adj.size()));
    adj = _adj;
  }
  void add_edge(int a, int b) {
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  int degree(int v) const {
    return int(adj[v].size()) + (built && parent[v] >= 0);
  }
  void dfs(int node, int par) {
    parent[node] = par;
    depth[node] = par < 0 ? 0 : depth[par] + 1;
    subtree_size[node] = 1;
    adj[node].erase(remove(adj[node].begin(), adj[node].end(), par),
                    adj[node].end());
    for (int child : adj[node]) {
      dfs(child, node);
      subtree_size[node] += subtree_size[child];
    }
    sort(adj[node].begin(), adj[node].end(),
         [&](int a, int b) { return subtree_size[a] > subtree_size[b]; });
  }
  int tour, post_tour;
  void tour_dfs(int node, bool heavy) {
    heavy_root[node] = heavy ? heavy_root[parent[node]] : node;
    first_occurrence[node] = int(euler.size());
    euler.push_back(node);
    tour_list[tour] = node;
    tour_start[node] = tour++;
    bool heavy_child = true;
    for (int child : adj[node]) {
      tour_dfs(child, heavy_child);
      euler.push_back(node);
      heavy_child = false;
    }
    tour_end[node] = tour;
    postorder[node] = post_tour++;
  }
  void build(int root = -1) {
    parent.assign(n, -1);
    if (0 <= root && root < n) dfs(root, -1);
    for (int i = 0; i < n; i++)
      if (i != root && parent[i] < 0) dfs(i, -1);
    tour = post_tour = 0;
    euler.clear();
    euler.reserve(2 * n);
    for (int i = 0; i < n; i++)
      if (parent[i] < 0) {
        tour_dfs(i, false);
        euler.push_back(-1);
      }
    rev_tour_list = tour_list;
    reverse(rev_tour_list.begin(), rev_tour_list.end());
    assert(int(euler.size()) == 2 * n);
    vector<int> euler_depths;
    euler_depths.reserve(euler.size());
    for (int node : euler)
      euler_depths.push_back(node < 0 ? node : depth[node]);
    rmq.build(euler_depths);
    built = true;
  }
  pair<int, int> find_farthest(int node, int par, int path) const {
    pair<int, int> current = {path, node};
    for (int neighbor : adj[node])
      if (neighbor != par)
        current = max(current, find_farthest(neighbor, node, path + 1));
    return current;
  }
  pair<int, array<int, 2>> get_diameter() const {
    int u = find_farthest(0, -1, 0).second;
    pair<int, int> farthest = find_farthest(u, -1, 0);
    int v = farthest.second;
    return {farthest.first, {u, v}};
  }
  int get_lca(int a, int b) const {
    a = first_occurrence[a];
    b = first_occurrence[b];
    if (a > b) swap(a, b);
    return euler[rmq.query_index(a, b + 1)];
  }
  bool is_ancestor(int a, int b) const {
    return tour_start[a] <= tour_start[b] && tour_start[b] < tour_end[a];
  }
  bool on_path(int x, int a, int b) const {
    return (is_ancestor(x, a) || is_ancestor(x, b)) &&
           is_ancestor(get_lca(a, b), x);
  }
  int get_dist(int a, int b) const {
    return depth[a] + depth[b] - 2 * depth[get_lca(a, b)];
  }
  int child_ancestor(int a, int b) const {
    assert(a != b);
    assert(is_ancestor(a, b));
    int child =
        euler[rmq.query_index(first_occurrence[a], first_occurrence[b] + 1) +
              1];
    assert(parent[child] == a);
    assert(is_ancestor(child, b));
    return child;
  }
  int get_kth_ancestor(int a, int k) const {
    while (a >= 0) {
      int root = heavy_root[a];
      if (depth[root] <= depth[a] - k) return tour_list[tour_start[a] - k];
      k -= depth[a] - depth[root] + 1;
      a = parent[root];
    }
    return a;
  }
  int get_kth_node_on_path(int a, int b, int k) const {
    int anc = get_lca(a, b);
    int first_half = depth[a] - depth[anc];
    int second_half = depth[b] - depth[anc];
    assert(0 <= k && k <= first_half + second_half);
    if (k < first_half)
      return get_kth_ancestor(a, k);
    else
      return get_kth_ancestor(b, first_half + second_half - k);
  }
  int get_common_node(int a, int b, int c) const {
    int x = get_lca(a, b);
    int y = get_lca(b, c);
    int z = get_lca(c, a);
    if (depth[y] > depth[x]) x = y;
    if (depth[z] > depth[x]) x = z;
    return x;
  }
  vector<pair<int, int>> compress_tree(vector<int> nodes) const {
    if (nodes.empty()) return {};
    auto &&compare_tour = [&](int a, int b) {
      return tour_start[a] < tour_start[b];
    };
    sort(nodes.begin(), nodes.end(), compare_tour);
    int k = int(nodes.size());
    for (int i = 0; i < k - 1; i++)
      nodes.push_back(get_lca(nodes[i], nodes[i + 1]));
    sort(nodes.begin() + k, nodes.end(), compare_tour);
    inplace_merge(nodes.begin(), nodes.begin() + k, nodes.end(), compare_tour);
    nodes.erase(unique(nodes.begin(), nodes.end()), nodes.end());
    vector<pair<int, int>> result = {{nodes[0], -1}};
    for (int i = 1; i < int(nodes.size()); i++)
      result.emplace_back(nodes[i], get_lca(nodes[i], nodes[i - 1]));
    return result;
  }
};
const int INF = 1e9 + 5;
struct segment_change {
  bool flip;
  segment_change(bool _flip = false) : flip(_flip) {}
  void reset() { flip = false; }
  bool has_change() const { return flip; }
  segment_change combine(const segment_change &other) const {
    return segment_change(flip ^ other.flip);
  }
};
struct segment {
  int deepest[2] = {-INF, -INF};
  void apply(int, const segment_change &change) {
    if (change.flip) swap(deepest[0], deepest[1]);
  }
  void join(const segment &other) {
    for (int r = 0; r < 2; r++) deepest[r] = max(deepest[r], other.deepest[r]);
  }
  void join(const segment &a, const segment &b) {
    *this = a;
    join(b);
  }
};
pair<int, int> right_half[32];
struct seg_tree {
  int tree_n = 0;
  vector<segment> tree;
  vector<segment_change> changes;
  seg_tree(int n = -1) {
    if (n >= 0) init(n);
  }
  void init(int n) {
    tree_n = 1;
    while (tree_n < n) tree_n *= 2;
    tree.assign(2 * tree_n, segment());
    changes.assign(tree_n, segment_change());
  }
  void build(const vector<segment> &initial) {
    int n = int(initial.size());
    init(n);
    assert(n <= tree_n);
    for (int i = 0; i < n; i++) tree[tree_n + i] = initial[i];
    for (int position = tree_n - 1; position > 0; position--)
      tree[position].join(tree[2 * position], tree[2 * position + 1]);
  }
  void apply_and_combine(int position, int length,
                         const segment_change &change) {
    tree[position].apply(length, change);
    if (position < tree_n)
      changes[position] = changes[position].combine(change);
  }
  void push_down(int position, int length) {
    if (changes[position].has_change()) {
      apply_and_combine(2 * position, length / 2, changes[position]);
      apply_and_combine(2 * position + 1, length / 2, changes[position]);
      changes[position].reset();
    }
  }
  void push_all(int a, int b) {
    assert(0 <= a && a < b && b <= tree_n);
    a += tree_n;
    b += tree_n - 1;
    for (int up = 31 - __builtin_clz(tree_n); up > 0; up--) {
      int x = a >> up, y = b >> up;
      push_down(x, 1 << up);
      if (x != y) push_down(y, 1 << up);
    }
  }
  void join_and_apply(int position, int length) {
    tree[position].join(tree[2 * position], tree[2 * position + 1]);
    tree[position].apply(length, changes[position]);
  }
  void join_all(int a, int b) {
    assert(0 <= a && a < b && b <= tree_n);
    a += tree_n;
    b += tree_n - 1;
    int length = 1;
    while (a > 1) {
      a /= 2;
      b /= 2;
      length *= 2;
      join_and_apply(a, length);
      if (a != b) join_and_apply(b, length);
    }
  }
  template <typename T_range_op>
  void process_range(int a, int b, bool needs_join, T_range_op &&range_op) {
    if (a == b) return;
    push_all(a, b);
    int original_a = a, original_b = b;
    int length = 1, r_size = 0;
    for (a += tree_n, b += tree_n; a < b; a /= 2, b /= 2, length *= 2) {
      if (a & 1) range_op(a++, length);
      if (b & 1) right_half[r_size++] = {--b, length};
    }
    for (int i = r_size - 1; i >= 0; i--)
      range_op(right_half[i].first, right_half[i].second);
    if (needs_join) join_all(original_a, original_b);
  }
  segment query(int a, int b) {
    assert(0 <= a && a <= b && b <= tree_n);
    segment answer;
    process_range(a, b, false,
                  [&](int position, int) { answer.join(tree[position]); });
    return answer;
  }
  void update(int a, int b, const segment_change &change) {
    assert(0 <= a && a <= b && b <= tree_n);
    process_range(a, b, true, [&](int position, int length) {
      apply_and_combine(position, length, change);
    });
  }
  vector<segment> to_array() {
    for (int i = 1; i < tree_n; i++)
      push_down(i, tree_n >> (31 - __builtin_clz(i)));
    vector<segment> segs(tree_n);
    for (int i = 0; i < tree_n; i++) segs[i] = tree[tree_n + i];
    return segs;
  }
  void update_single(int index, const segment &seg);
  template <typename T_bool>
  int find_last_prefix(int n, T_bool &&should_join);
  template <typename T_bool>
  int find_last_subarray(int n, int start, T_bool &&should_join);
};
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  int N;
  cin >> N;
  LCA lca[2] = {LCA(N), LCA(N)};
  vector<array<int, 2>> edges(N - 1);
  vector<bool> status(N - 1);
  for (int e = 0; e < N - 1; e++) {
    int u, v, s;
    cin >> u >> v >> s;
    u--;
    v--;
    edges[e] = {u, v};
    status[e] = s;
    for (int t = 0; t < 2; t++) lca[t].add_edge(u, v);
  }
  array<int, 2> diameter = lca[0].get_diameter().second;
  for (int t = 0; t < 2; t++) lca[t].build(diameter[t]);
  seg_tree tree[2] = {seg_tree(N), seg_tree(N)};
  for (int t = 0; t < 2; t++) {
    vector<segment> initial(N);
    for (int node = 0; node < N; node++)
      initial[lca[t].tour_start[node]].deepest[0] = lca[t].depth[node];
    tree[t].build(initial);
  }
  auto query = [&] {
    return max(tree[0].tree[1].deepest[0], tree[1].tree[1].deepest[0]);
  };
  auto flip_edge = [&](int a, int b) {
    for (int t = 0; t < 2; t++) {
      int v = lca[t].depth[a] > lca[t].depth[b] ? a : b;
      tree[t].update(lca[t].tour_start[v], lca[t].tour_end[v],
                     segment_change(true));
    }
  };
  for (int e = 0; e < N - 1; e++)
    if (status[e]) flip_edge(edges[e][0], edges[e][1]);
  int M;
  cin >> M;
  for (int q = 0; q < M; q++) {
    int id;
    cin >> id;
    id--;
    flip_edge(edges[id][0], edges[id][1]);
    cout << query() << '\n';
  }
}
