#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<set>
#include<algorithm>
#include<map>
#include<vector>
#include<queue>
#include<iostream>
#include<string>
#include<cmath>
#define N 500010
#define Lc(x) (x<<1)
#define Rc(X) ((x<<1)+1)
#define FOR(i,a,b) for(i=(a);i<=(b);i++)
#define ROF(i,a,b) for(i=(a);i>=(b);i--)
typedef long long LL;
using namespace std;
int pos[N],list[N],st[2*N],ed[2*N],f[2*N],lc[2*N],rc[2*N],L,len,n,a[N];
char op[N][5];
bool vis[2*N];int q,root[2*N],opv[N][2];
struct node{int l,r,m,d;};
int getf(int x)
{
if (f[x]!=x) f[x]=getf(f[x]);
return f[x];
}
void DFS(int x)
{
vis[x]=1;
if (lc[x]==0&&rc[x]==0)
{
list[++L]=x;pos[x]=L;
st[x]=ed[x]=L;
return;
}
st[x]=L+1;
DFS(lc[x]);
DFS(rc[x]);
ed[x]=L;
}
struct segtree
{
node tree[3*N];
void upd(int x){tree[x].m=max(tree[Lc(x)].m,tree[Rc(x)].m);}
void pushdown(int x)
{
tree[Lc(x)].d+=tree[x].d;
tree[Rc(x)].d+=tree[x].d;
tree[Lc(x)].m+=tree[x].d;
tree[Rc(x)].m+=tree[x].d;
tree[x].d=0;
}
void change(int x,int L,int R,int delta)
{
if (tree[x].l==L&&tree[x].r==R)
{
tree[x].d+=delta;tree[x].m+=delta;
return;
}
pushdown(x);
int mid=(tree[x].l+tree[x].r)>>1;
if (R<=mid) change(Lc(x),L,R,delta);
else if (L>mid) change(Rc(x),L,R,delta);
else
{
change(Lc(x),L,mid,delta);
change(Rc(x),mid+1,R,delta);
}
upd(x);
}
int query(int x,int L,int R)
{
if (tree[x].l==L&&tree[x].r==R) return tree[x].m;
pushdown(x);
int mid=(tree[x].l+tree[x].r)>>1;
if (R<=mid) return query(Lc(x),L,R);
if (L>mid) return query(Rc(x),L,R);
return max(query(Lc(x),L,mid),query(Rc(x),mid+1,R));
}
void build(int x,int L,int R)
{
tree[x].l=L;tree[x].r=R;int mid=(L+R)>>1;
if (L==R) {tree[x].m=a[list[L]];tree[x].d=0;return;}
build(Lc(x),L,mid);build(Rc(x),mid+1,R);upd(x);
}
}tree;
int main()
{
scanf("%d",&n);int i;
FOR(i,1,n) f[i]=i;
FOR(i,1,n) scanf("%d",&a[i]);
scanf("%d",&q);
memset(root,0,sizeof(root));
len=n;
FOR(i,1,q)
{
scanf("%s",op[i]);
if (strcmp(op[i],"F3")==0) continue;
scanf("%d",&opv[i][0]);
if (strcmp(op[i],"A1")==0||
strcmp(op[i],"U")==0||
strcmp(op[i],"A2")==0)
{
scanf("%d",&opv[i][1]);
if (strcmp(op[i],"U")==0)
{
int fx=getf(opv[i][0]),fy=getf(opv[i][1]);
if (fx==fy) continue;
len++;root[fx]=1;root[fy]=1;
f[fx]=len;f[fy]=len;f[len]=len;
lc[len]=fx;rc[len]=fy;
}
}
}
memset(vis,0,sizeof(vis));
L=0;
FOR(i,n+1,len)
if (!root[i]) DFS(i);
FOR(i,1,n) if (!vis[i]) DFS(i);
tree.build(1,1,n);
FOR(i,1,n) f[i]=i;
len=n;
FOR(i,1,q)
{
if (strcmp(op[i],"U")==0)
{
int fx=getf(opv[i][0]),fy=getf(opv[i][1]);
if (fx==fy) continue;
len++;f[fx]=len;f[fy]=len;f[len]=len;
}
if (strcmp(op[i],"A1")==0)
{
tree.change(1,pos[opv[i][0]],pos[opv[i][0]],opv[i][1]);
}
if (strcmp(op[i],"A2")==0)
{
int root=getf(opv[i][0]);
tree.change(1,st[root],ed[root],opv[i][1]);
}
if (strcmp(op[i],"A3")==0)
{
tree.change(1,1,n,opv[i][0]);
}
if (strcmp(op[i],"F1")==0)
{
printf("%d\n",tree.query(1,pos[opv[i][0]],pos[opv[i][0]]));
}
if (strcmp(op[i],"F2")==0)
{
int root=getf(opv[i][0]);
printf("%d\n",tree.query(1,st[root],ed[root]));
}
if (strcmp(op[i],"F3")==0)
{
printf("%d\n",tree.query(1,1,n));
}
}
}