// Izvidaci - Djerek
// Dobro rjesenje, nesto slicno heavy light dekompoziciji
// O((n+m) log n)

#include <cstdio>
#include <cassert>
#include <list>

using namespace std;

const int MAXN = 100000;

int n;
list<int> g[MAXN];
int initial[MAXN];
int depth[MAXN];
int weight[MAXN];
int parent[MAXN];
int lparent[MAXN];
int heavy_child[MAXN];
int first_in_chain[MAXN];
int stack[MAXN];
int below[MAXN];
int below_nonheavy[MAXN];
int saved_below[MAXN];

int node = 0;
int total = 0;
long long total_cost = 0;
int current_below = 0;

void visit(int k, int d) {
  stack[d] = k;
  depth[k] = d;
  parent[k] = d?stack[d-1]:-1;
  lparent[k] = d?stack[d-(d&-d)]:-1;
  weight[k] = 1;
  heavy_child[k] = -1;
  for (list<int>::iterator i=g[k].begin(); i!=g[k].end(); i++) {
    if (*i == parent[k])
      continue ;
    visit(*i, d+1);
    weight[k] += weight[*i];
    if (heavy_child[k] == -1 || weight[heavy_child[k]] < weight[*i])
      heavy_child[k] = *i;
  }
}

void set_first_in_chain(int k, int f) {
  first_in_chain[k] = f;
  for (list<int>::iterator i=g[k].begin(); i!=g[k].end(); i++) {
    if (*i == parent[k])
      continue ;
    if (heavy_child[k] == *i)
      set_first_in_chain(*i, first_in_chain[k]);
    else
      set_first_in_chain(*i, *i);
  }
}

int lca(int a, int b) {
  if (depth[a] < depth[b])
    swap(a, b);
  while (depth[a] > depth[b])
    a = depth[lparent[a]] >= depth[b]?lparent[a]:parent[a];
  while (a != b)
    if (lparent[a] != lparent[b])
      a = lparent[a], b = lparent[b];
    else
      a = parent[a], b = parent[b];

  return a;
}

void read_graph() {
  scanf("%d", &n);
  for (int i=0; i<n; i++)
    scanf("%d", &initial[i]);
  for (int i=0; i<n-1; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    g[a-1].push_back(b-1);
    g[b-1].push_back(a-1);
  }
}


void fixup(int k, int amount) {
  while (k != -1) {
    below_nonheavy[k] += amount;
    if (first_in_chain[k] != k)
      k = first_in_chain[k];
    below[k] += amount;
    k = parent[k];
  }
}

void add(int k, int amount) {
  int p = lca(k, node);
  total += amount;
  total_cost += amount*((long long)depth[k]+depth[node]-2*depth[p]);
  fixup(k, amount);
  saved_below[p] += amount;
  if (p == node)
    current_below += amount;
}

void move(int k) {
  assert(parent[k] == node || parent[node] == k);
  int old_below = current_below;
  if (parent[k] == node && heavy_child[node] == k) {
    // Down on heavy.
    current_below -= below_nonheavy[node];
    total_cost += total-2*current_below;
  } else if (parent[k] == node) {
    // Down on light.
    current_below = below[k];
    saved_below[node] = old_below-current_below;
    total_cost += total-2*current_below;
  } else if (heavy_child[k] == node) {
    // Up on heavy.
    current_below += below_nonheavy[k];
    total_cost -= total-2*old_below;
  } else {
    // Up on light.
    current_below += saved_below[k];
    total_cost -= total-2*old_below;
  }
  node = k;
}

void init() {
  memset(below, 0, sizeof below);
  memset(below_nonheavy, 0, sizeof below_nonheavy);
  for (int i=0; i<n; i++)
    add(i, initial[i]);
}

void process() {
  int m;
  scanf("%d", &m);
  for (int i=0; i<m; i++) {
    char c[2];
    int a;
    scanf("%s%d", c, &a);
    assert(c[0] == 'S' || c[0] == 'P');
    if (c[0] == 'S') {
      if (a-1 != node)
        move(a-1);
      printf("%lld\n", total_cost);

    } else
      add(a-1, 1);
  }
}

void debug() {
  for (int i=0; i<n; i++)
    printf("%d: %d %d %d %d %d %d %d\n", i, depth[i], weight[i],
           heavy_child[i], first_in_chain[i], below[i], below_nonheavy[i], saved_below[i]);
}

int main() {
  read_graph();
  visit(0, 0);
  set_first_in_chain(0, 0);
  init();
  //debug();
  process();
  return 0;
}
