#include <bits/stdc++.h>
using namespace std;
template <class T>
inline void umax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
inline void umin(T &a, T b) {
  if (a > b) a = b;
}
template <class T>
inline T abs(T a) {
  return a > 0 ? a : -a;
}
template <class T>
inline T gcd(T a, T b) {
  return __gcd(a, b);
}
template <class T>
inline T lcm(T a, T b) {
  return a / gcd(a, b) * b;
}
const int inf = 1e9 + 143;
const long long longinf = 1e18 + 143;
inline int read() {
  int x;
  scanf(" %d", &x);
  return x;
}
const int N = 1 << 17;
int n;
int up[N];
int a[N], d[N], sz[N], par[N];
int tin[N], tout[N], ptr = 0;
vector<pair<int, int> > g[N];
bool isanc(int p, int u) { return tin[p] <= tin[u] && tin[u] <= tout[p]; }
int get_lca(int u, int v) {
  if (!u) return v;
  if (!v) return u;
  for (;;) {
    if (isanc(u, v)) return u;
    if (isanc(v, u)) return v;
    int hu = up[u] ? up[u] : par[u];
    int hv = up[v] ? up[v] : par[v];
    if (d[hu] >= d[hv]) {
      u = hu;
    } else {
      v = hv;
    }
  }
}
namespace lca_tree {
int tree[N << 1];
void add(int x) {
  tree[x + N - 1] = x;
  x += N - 1;
  while (x > 1) {
    x >>= 1;
    tree[x] = get_lca(tree[x + x], tree[x + x + 1]);
  }
}
void del(int x) {
  tree[x += N - 1] = 0;
  while (x > 1) {
    x >>= 1;
    tree[x] = get_lca(tree[x + x], tree[x + x + 1]);
  }
}
};  // namespace lca_tree
namespace Magic_Tree {
struct info {
  int minv;
  long long sum, all;
};
info tree[N << 1];
int add[N << 1];
inline void push(int x) {
  if (add[x]) {
    add[x + x] += add[x];
    add[x + x + 1] += add[x];
    add[x] = 0;
  }
}
inline info apply(int x) {
  return (info){tree[x].minv + add[x], tree[x].sum, tree[x].all};
}
inline info merge(const info &a, const info &b) {
  info res;
  res.minv = min(a.minv, b.minv);
  res.all = a.all + b.all;
  res.sum = 0ll;
  if (a.minv == res.minv) res.sum += a.sum;
  if (b.minv == res.minv) res.sum += b.sum;
  return res;
}
inline void relax(int x) { tree[x] = merge(apply(x + x), apply(x + x + 1)); }
void init() {
  for (int i = 1; i <= n; i++) tree[tin[i] + N - 1] = (info){0, a[i], a[i]};
  for (int i = N - 1; i > 0; i--) tree[i] = merge(tree[i + i], tree[i + i + 1]);
  memset(add, 0, sizeof add);
}
void update(int x, int l, int r, int x1, int x2, int val) {
  if (l > x2 || r < x1) return;
  if (l >= x1 && r <= x2) {
    add[x] += val;
    return;
  }
  push(x);
  int m = (l + r) >> 1;
  update(x + x, l, m, x1, x2, val);
  update(x + x + 1, m + 1, r, x1, x2, val);
  relax(x);
}
info get(int x, int l, int r, int x1, int x2) {
  if (l > x2 || r < x1) return (info){0, 0, 0};
  if (l >= x1 && r <= x2) return apply(x);
  int m = (l + r) >> 1;
  push(x);
  info L = get(x + x, l, m, x1, x2);
  info R = get(x + x + 1, m + 1, r, x1, x2);
  relax(x);
  return merge(L, R);
}
long long getsum(int l, int r) {
  info t = get(1, 1, N, l, r);
  if (t.minv > 0) return t.all;
  return t.all - t.sum;
}
};  // namespace Magic_Tree
void dfs1(int u, int p) {
  sz[u] = 1;
  for (__typeof((g[u]).begin()) it = (g[u]).begin(); it != (g[u]).end(); it++) {
    int v = it->first;
    int c = it->second;
    if (v != p) {
      d[v] = d[u] + 1;
      a[v] = c;
      par[v] = u;
      dfs1(v, u);
      sz[u] += sz[v];
    }
  }
}
void dfs2(int u, int p) {
  tin[u] = ++ptr;
  int hv = -1;
  for (__typeof((g[u]).begin()) it = (g[u]).begin(); it != (g[u]).end(); it++) {
    int v = it->first;
    int c = it->second;
    if (v != p && (hv == -1 || sz[hv] < sz[v])) hv = v;
  }
  if (hv != -1) {
    up[hv] = up[u] ? up[u] : u;
    dfs2(hv, u);
  }
  for (__typeof((g[u]).begin()) it = (g[u]).begin(); it != (g[u]).end(); it++) {
    int v = it->first;
    int c = it->second;
    if (v != p && v != hv) {
      up[v] = 0;
      dfs2(v, u);
    }
  }
  tout[u] = ptr;
}
int main() {
  n = read();
  for (int i = 1; i < n; i++) {
    int u = read(), v = read(), c = read();
    g[u].push_back(pair<int, int>(v, c));
    g[v].push_back(pair<int, int>(u, c));
  }
  par[1] = 0;
  dfs1(1, 0);
  dfs2(1, 0);
  Magic_Tree::init();
  int q = read();
  while (q--) {
    char foo;
    scanf(" %c", &foo);
    if (foo == '?') {
      int lca = lca_tree::tree[1];
      0;
      if (lca == 0) {
        puts("0");
      } else {
        printf("%I64d\n", Magic_Tree::getsum(tin[lca] + 1, tout[lca]));
      }
    } else {
      int u = read();
      if (foo == '+')
        lca_tree::add(u);
      else
        lca_tree::del(u);
      0;
      int delta = (foo == '+') ? +1 : -1;
      while (u > 0) {
        if (up[u]) {
          Magic_Tree::update(1, 1, N, tin[up[u]] + 1, tin[u], delta);
          u = up[u];
        } else {
          Magic_Tree::update(1, 1, N, tin[u], tin[u], delta);
          u = par[u];
        }
      }
    }
  }
  return 0;
}
