#include<bits/stdc++.h>
using namespace std;
namespace IO{
static char* p1, * p2, buf[1 << 22];
#define getchar() (p1==p2 && (p2=(p1=buf)+fread(buf,1,1<<22,stdin),p1==p2)?EOF:*p1++)
#define putchar putchar_unlocked
template <typename T>
inline bool read(T& x){
x = 0;
bool y(false);
char ch = getchar();
while (ch < '0' || ch>'9'){
y |= ch == '-';
if (ch == -1) return false;
ch = getchar();
}
while (ch >= '0' && ch <= '9'){
x = x * 10 + (ch ^ 48);
ch = getchar();
}
if (ch ^ '.')return x = y ? -x : x, true;
T f = 0.1;
ch = getchar();
while (ch >= '0' && ch <= '9'){
x = x + (ch ^ 48) * f;
f = f * 0.1;
ch = getchar();
}
return x = y ? -x : x, true;
}
template <typename T>
inline void print(T x){
x < 0 ? x = -x, putchar('-') : 0;
static short Stack[128], top(0);
do Stack[++top] = x % 10, x /= 10; while (x);
while (top) putchar(Stack[top--] | 48);
return;
}
inline int gc(){
char ch = getchar();
while (ch == ' ' || ch == '\r' || ch == '\n') ch = getchar();
return ch;
}
inline bool read(char& x){ return (x = gc()) == -1 ? false : true; }
template<typename T>
inline int read(T* x){
T ch = gc();
int cnt = 0;
while (ch ^ ' ' && ch ^ '\r' && ch ^ '\n' && ~ch){
*x++ = ch;
cnt++;
ch = getchar();
}
*x++ = '\0';
return cnt;
}
int read(string& ans){
ans = "";
int cnt = 0;
char tmp = gc();
while (!(tmp == '\n' || tmp == '\r' || tmp == EOF || tmp == ' ')){
ans.push_back(tmp); cnt++;
tmp = getchar();
}
return cnt;
}
inline int read(){ int x = 0; read(x); return x; }
inline void print(const char ch){ return putchar(ch), void(); }
inline void print(const char* ch){ while (*ch)putchar(*ch++); return; }
inline void print(char* ch){ while (*ch)putchar(*ch++); return; }
template<typename T>
inline void print(T* x){ while (*x) print(*x++); }
inline void print(string x){ for (const auto& i : x)print(i); }
template <typename T, typename... Args>
inline bool read(T& t, Args&... args){ read(t); return read(args...); }
template <typename T, typename... Args>
inline void print(T t, Args... args){ print(t); print(args...); }
struct i_stream{
bool flag = true;
template<typename T>
inline i_stream operator>>(T* x){ return flag &= read(x), *this; }
template<typename T>
inline i_stream operator>>(T& x){ return flag &= read(x), *this; }
operator bool(){ return flag; }
}Cin;
struct o_stream{
template<typename T>
inline o_stream operator<<(T* x){ return print(x), * this; }
template<typename T>
inline o_stream operator<<(T x){ return print(x), * this; }
}Cout;
}
using namespace IO;
const int N = 2e5 + 10;
int n;
struct edge{
int to, val;
edge(){}
edge(int to, int val) :to(to), val(val){}
};
vector<edge> e[N];
int fa[N], son[N], siz[N], dep[N], val[N];
void dfs1(int u, int pre){
fa[u] = pre; siz[u] = 1; dep[u] = dep[pre] + 1;
for (const auto& to : e[u]){
int v = to.to, w = to.val;
if (v == pre) continue;
val[v] = w;
dfs1(v, u);
siz[u] += siz[v];
if (siz[son[u]] < siz[v]) son[u] = v;
}
}
int seg[N], rev[N], bnt, top[N];
void dfs2(int u){
seg[u] = ++bnt; rev[bnt] = u;
if (!son[u]) return;
top[son[u]] = top[u];
dfs2(son[u]);
for (const auto& to : e[u]){
int v = to.to;
if (v == fa[u] || v == son[u]) continue;
top[v] = v;
dfs2(v);
}
}
struct node{
int l, r, mx;
int add, cov;
}tree[N << 2];
void pushup(int u){
tree[u].mx = max(tree[u << 1].mx, tree[u << 1 | 1].mx);
}
void pushdown(int u){
int lc = u << 1, rc = u << 1 | 1;
if (tree[u].cov){
tree[lc].mx = tree[u].cov;
tree[rc].mx = tree[u].cov;
tree[lc].cov = tree[u].cov;
tree[rc].cov = tree[u].cov;
tree[u].cov = 0;
tree[u].add = tree[lc].add = tree[rc].add = 0;
}
if (tree[u].add){
tree[lc].mx += tree[u].add;
tree[rc].mx += tree[u].add;
tree[lc].add += tree[u].add;
tree[rc].add += tree[u].add;
tree[u].add = 0;
}
}
void build(int u, int l, int r){
tree[u].l = l; tree[u].r = r;
if (l == r){
tree[u].mx = val[rev[l]];
return;
}
int mid = (l + r) >> 1;
build(u << 1, l, mid);
build(u << 1 | 1, mid + 1, r);
pushup(u);
}
int ask(int u, int l, int r){
if (l <= tree[u].l && tree[u].r <= r) return tree[u].mx;
pushdown(u);
int mid = (tree[u].l + tree[u].r) >> 1;
int res = -1;
if (l <= mid) res = max(res, ask(u << 1, l, r));
if (mid < r) res = max(res, ask(u << 1 | 1, l, r));
pushup(u);
return res;
}
void modify_add(int u, int l, int r, int k){
pushdown(u);
if (l <= tree[u].l && tree[u].r <= r){
tree[u].mx += k;
tree[u].add += k;
return;
}
int mid = (tree[u].l + tree[u].r) >> 1;
if (l <= mid) modify_add(u << 1, l, r, k);
if (mid < r) modify_add(u << 1 | 1, l, r, k);
pushup(u);
}
void modify_cov(int u, int l, int r, int k){
if (l <= tree[u].l && tree[u].r <= r){
tree[u].mx = k;
tree[u].cov = k;
tree[u].add = 0;
return;
}
pushdown(u);
int mid = (tree[u].l + tree[u].r) >> 1;
if (l <= mid) modify_cov(u << 1, l, r, k);
if (mid < r) modify_cov(u << 1 | 1, l, r, k);
pushup(u);
}
int query(int x, int y){
int res = -1;
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swap(x, y);
res = max(res, ask(1, seg[top[x]], seg[x]));
x = fa[top[x]];
}
if (seg[x] > seg[y]) swap(x, y);
res = max(res, ask(1, seg[x] + 1, seg[y]));
return res;
}
void change_add(int x, int y, int k){
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swap(x, y);
modify_add(1, seg[top[x]], seg[x], k);
x = fa[top[x]];
}
if (seg[x] > seg[y]) swap(x, y);
modify_add(1, seg[x] + 1, seg[y], k);
}
void change_cov(int x, int y, int k){
while (top[x] != top[y]){
if (dep[top[x]] < dep[top[y]]) swap(x, y);
modify_cov(1, seg[top[x]], seg[x], k);
x = fa[top[x]];
}
if (seg[x] > seg[y]) swap(x, y);
modify_cov(1, seg[x] + 1, seg[y], k);
}
string q;
pair<int, int> ed[N << 1];
signed main(){
Cin >> n;
for (int i = 1; i < n; i++){
int x = read(), y = read(), val = read();
e[x].emplace_back(y, val);
e[y].emplace_back(x, val);
ed[i] = make_pair(x, y);
}
dfs1(1, 0);
top[1] = 1;
dfs2(1);
build(1, 1, n);
while (true){
read(q);
if (q == "Stop") break;
int x = read(), y = read();
if (q == "Max"){
print(query(x, y), '\n');
}
if (q == "Add"){
int k = read();
change_add(x, y, k);
}
if (q == "Change"){
int u = ed[x].first, v = ed[x].second;
if (dep[v] > dep[u]) swap(u, v);
modify_cov(1, seg[u], seg[u], y);
}
if (q == "Cover"){
int k = read();
change_cov(x, y, k);
}
}
return 0;
}