#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));
    }
  }
}