#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int n, m, u, v;
string op;
#define rep for (int i = head[u]; i; i = G[i].nex)
struct {
int to, wt, nex;
} G[N * 2];
int head[N], tot = 1;
void add(int u, int v, int w) {
G[++tot] = {v, w, head[u]};
head[u] = tot;
}
int fa[N], d[N], son[N], tp[N], sz[N], dfn[N], nfd[N], cnt, w[N], dir[N];
void dfs1(int u) {
sz[u] = 1;
rep {
int v = G[i].to;
if (v ^ fa[u])
fa[v] = u, d[v] = d[u] + 1, dfs1(v), sz[u] += sz[v],
sz[son[u]] < sz[v] && (son[u] = v);
}
}
void dfs2(int u, int top) {
printf("dfs2 %d %d\n", u, top);
nfd[dfn[u] = ++cnt] = u;
if (!son[u])
return;
tp[u] = top;
dfs2(son[u], top);
rep {
int v = G[i].to;
if (v != son[u] && v != fa[u])
::w[v] = G[i].wt, dir[i / 2] = v, dfs2(v, v);
}
}
struct sgttree {
#define ls h * 2
#define rs ls | 1
#define mid (l + r >> 1)
#define lson ls, l, mid
#define rson rs, mid + 1, r
#define Tree int h, int l, int r
#define sum(x) t[x].sum
#define rev(x) t[x].rev
#define mx(x) t[x].mx
#define mn(x) t[x].mn
struct node {
int sum, rev, mx, mn;
node operator+(node a) {
return {sum + a.sum, 0, max(mx, a.mx), min(mn, a.mn)};
}
} t[N << 2];
void pushup(int h) {
sum(h) = sum(ls) + sum(rs);
mx(h) = max(mx(ls), mx(rs));
mn(h) = min(mn(ls), mn(rs));
}
void pushdown(int h) {
if (rev(h)) {
rev(ls) ^= 1, rev(rs) ^= 1;
sum(ls) = -sum(ls);
sum(rs) = -sum(rs);
int tmp = mx(ls);
mx(ls) = -mn(ls);
mn(ls) = -tmp;
tmp = mx(rs);
mx(rs) = -mn(rs);
mn(rs) = -tmp;
rev(h) = 0;
}
}
void build(Tree) {
if (l == r) {
sum(h) = mx(h) = mn(h) = w[nfd[l]];
return;
}
build(lson);
build(rson);
pushup(h);
}
void modify(Tree, int x, int y) {
if (l == r) {
sum(h) = mx(h) = mn(h) = y;
rev(h) = 0;
return;
}
pushdown(h);
if (x <= mid)
modify(lson, x, y);
else
modify(rson, x, y);
pushup(h);
}
void update(Tree, int x, int y) {
printf("update %d %d\n", l, r);
if (x <= l && r <= y) {
sum(h) = -sum(h);
int tmp = mx(h);
mx(h) = -mn(h);
mn(h) = -tmp;
rev(h) ^= 1;
return;
}
pushdown(h);
if (x <= mid)
update(lson, x, y);
if (y > mid)
update(rson, x, y);
pushup(h);
}
node query(Tree, int x, int y) {
if (x <= l && r <= y)
return t[h];
pushdown(h);
if (y <= mid)
return query(lson, x, y);
if (x > mid)
return query(rson, x, y);
return query(lson, x, y) + query(rson, x, y);
}
void updateChain(int u, int v) {
for (; tp[u] ^ tp[v]; u = fa[tp[u]]) {
if (d[tp[u]] < d[tp[v]])
swap(u, v);
update(1, 1, n, dfn[tp[u]], dfn[u]);
}
if (d[u] < d[v])
swap(u, v);
update(1, 1, n, dfn[v] + 1, dfn[u]);
}
int queryChain(int u, int v, int op) {
int ans = op == 3 ? 1001 : 0;
for (; tp[u] ^ tp[v]; u = fa[tp[u]]) {
if (d[tp[u]] < d[tp[v]])
swap(u, v);
node res = query(1, 1, n, dfn[tp[u]], dfn[u]);
if (op == 1)
ans += res.sum;
else if (op == 2)
ans = max(ans, res.mx);
else if (op == 3)
ans = min(ans, res.mn);
}
if (d[u] < d[v])
swap(u, v);
node res = query(1, 1, n, dfn[v] + 1, dfn[u]);
if (op == 1)
ans += res.sum;
else if (op == 2)
ans = max(ans, res.mx);
else if (op == 3)
ans = min(ans, res.mn);
return ans;
}
} sgt;
main() {
cin >> n;
for (int u, v, w, i = 1; i < n; ++i) {
cin >> u >> v >> w;
++u, ++v;
add(u, v, w);
add(v, u, w);
}
dfs1(1), dfs2(1, 1);
cout << "w[i]=";
for (int i = 1; i <= n; ++i)
cout << w[i] << " \n"[i == n];
cout << "dir[i]=";
for (int i = 1; i <= n; ++i)
cout << dir[i] << " \n"[i == n];
cout << "dfn[i]=";
for (int i = 1; i <= n; ++i)
cout << dfn[i] << " \n"[i == n];
cout << "nfd[i]=";
for (int i = 1; i <= n; ++i)
cout << nfd[i] << " \n"[i == n];
sgt.build(1, 1, n);
for (cin >> m; m--;) {
cin >> op >> u >> v;
if (op[0] == 'C')
sgt.modify(1, 1, n, dfn[dir[u]], v);
else {
if (u == v)
continue;
++u, ++v;
if (op[0] == 'N')
sgt.updateChain(u, v);
else {
int op1 = op[0] == 'S' ? 1 : op[1] == 'A' ? 2 : 3;
cout << sgt.queryChain(u, v, op1) << '\n';
}
}
}
}