#include<bits/stdc++.h>
#define int long long
#define PP pair <int, int>
using namespace std;
inline int read () {
int s = 0, f = 1;
char ch = getchar ();
while (ch < '0' || ch > '9') {
if (ch == '-') f = -1;
ch = getchar ();
}
while (ch >= '0' && ch <= '9') {
s = (s << 1) + (s << 3) + (ch ^ 48);
ch = getchar ();
}
return s;
}
const int N = 1e6 + 10;
struct SegmentTree {
int l, r, Max, lazy_c, lazy_a;
} tree[N * 4];
struct EDGE {
int next, to, z, id;
} edge[N * 2];
int head[N], cnt, dep[N], tot, id[N], s[N], w[N], fat[N], son[N], tp[N], siz[N], n, b[N];
inline void add (int x, int y, int z, int id) {
edge[ ++ cnt].next = head[x];
edge[cnt].to = y;
edge[cnt].z = z;
edge[cnt].id = id;
head[x] = cnt;
}
void dfs (int x, int fa) {
siz[x] = 1;
for (int i = head[x]; i; i = edge[i].next) {
int y = edge[i].to, z = edge[i].z;
if (y == fa) continue;
fat[y] = x;
dep[y] = dep[x] + 1;
s[y] = z;
b[edge[i].id] = y;
dfs (y, x);
siz[x] += siz[y];
if (siz[y] > siz[son[x]]) son[x] = y;
}
}
void dfs1 (int x, int t) {
id[x] = ++ tot;
w[tot] = s[x];
tp[x] = t;
if (son[x] == 0) return;
dfs1 (son[x], t);
for (int i = head[x]; i; i = edge[i].next) {
int y = edge[i].to;
if (y == son[x] || y == fat[x]) continue;
dfs1 (y, y);
}
}
void build (int p, int l, int r) {
tree[p].l = l, tree[p].r = r, tree[p].lazy_c = -1;
if (l == r) {
tree[p].Max = w[l];
return;
}
int mid = (l + r) >> 1;
build (p * 2, l, mid);
build (p * 2 + 1, mid + 1, r);
tree[p].Max = max (tree[p * 2].Max, tree[p * 2 + 1].Max);
}
inline void down (int p) {
if (tree[p].lazy_c != -1) {
tree[p * 2].Max = tree[p].lazy_c;
tree[p * 2 + 1].Max = tree[p].lazy_c;
tree[p * 2].lazy_c = tree[p].lazy_c;
tree[p * 2 + 1].lazy_c = tree[p].lazy_c;
tree[p].lazy_c = -1;
tree[p].lazy_a = 0;
return;
}
if (tree[p].lazy_a != 0) {
tree[p * 2].Max += tree[p].lazy_a;
tree[p * 2 + 1].Max += tree[p].lazy_a;
tree[p * 2].lazy_a += tree[p].lazy_a;
tree[p * 2 + 1].lazy_a += tree[p].lazy_a;
tree[p].lazy_a = 0;
return;
}
}
void change (int p, int x, int z) {
if (tree[p].l == tree[p].r) {
tree[p].Max = z;
return;
}
down (p);
int mid = (tree[p].l + tree[p].r) >> 1;
if (x <= mid) change (p * 2, x, z);
else change (p * 2 + 1, x, z);
tree[p].Max = max (tree[p * 2].Max, tree[p * 2 + 1].Max);
}
void Change (int p, int l, int r, int z) {
if (tree[p].l >= l && tree[p].r <= r) {
tree[p].Max = z;
tree[p].lazy_c = z;
tree[p].lazy_a = 0;
return;
}
down (p);
int mid = (tree[p].l + tree[p].r) >> 1;
if (l <= mid) Change (p * 2, l, r, z);
if (mid < r) Change (p * 2 + 1, l, r, z);
tree[p].Max = max (tree[p * 2].Max, tree[p * 2 + 1].Max);
}
void Add (int p, int l, int r, int z) {
if (tree[p].l >= l && tree[p].r <= r) {
tree[p].Max += z;
if (tree[p].lazy_c != -1) tree[p].lazy_c += z;
else tree[p].lazy_a += z;
return;
}
down (p);
int mid = (tree[p].l + tree[p].r) >> 1;
if (l <= mid) Add (p * 2, l, r, z);
if (mid < r) Add (p * 2 + 1, l, r, z);
tree[p].Max = max (tree[p * 2].Max, tree[p * 2 + 1].Max);
}
int query (int p, int l, int r) {
if (tree[p].l >= l && tree[p].r <= r) return tree[p].Max;
down (p);
int mid = (tree[p].l + tree[p].r) >> 1, res = -0x3f3f3f3f;
if (l <= mid) res = max (res, query (p * 2, l, r));
if (mid < r) res = max (res, query (p * 2 + 1, l, r));
return res;
}
inline void TreeChange (int x, int y, int z) {
if (tp[x] != tp[y]) {
if (dep[tp[x]] < dep[tp[y]]) swap (x, y);
Change (1, id[tp[x]], id[x], z);
x = fat[tp[x]];
}
if (dep[x] > dep[y]) swap (x, y);
Change (1, id[x] + 1, id[y], z);
}
inline void TreeAdd (int x, int y, int z) {
if (tp[x] != tp[y]) {
if (dep[tp[x]] < dep[tp[y]]) swap (x, y);
Add (1, id[tp[x]], id[x], z);
x = fat[tp[x]];
}
if (dep[x] > dep[y]) swap (x, y);
Add (1, id[x] + 1, id[y], z);
}
inline int TreeQuery (int x, int y) {
int res = -0x3f3f3f3f;
if (tp[x] != tp[y]) {
if (dep[tp[x]] < dep[tp[y]]) swap (x, y);
res = max (res, query (1, id[tp[x]], id[x]));
x = fat[tp[x]];
}
if (dep[x] > dep[y]) swap (x, y);
res = max (res, query (1, id[x] + 1, id[y]));
return res;
}
signed main () {
n = read ();
for (int i = 1; i < n; i ++ ) {
int x = read (), y = read (), z = read ();
add (x, y, z, i);
add (y, x, z, i);
}
dep[1] = 1;
dfs (1, 0);
dfs1 (1, 0);
build (1, 1, n);
string a;
cin >> a;
while (a != "Stop") {
if (a == "Change") {
int k = read (), z = read ();
change (1, id[b[k]], z);
}
else if (a == "Cover") {
int x = read (), y = read (), z = read ();
TreeChange (x, y, z);
}
else if (a == "Add") {
int x = read (), y = read (), z = read ();
TreeAdd (x, y, z);
}
else {
int x = read (), y = read ();
cout << TreeQuery (x, y) << endl;
}
cin >> a;
}
return 0;
}