///**Bismillahir Rahmanir Raheem**
///** Mizanul Hoque **
///** IIUC **
/// ###############################
#include <bits/stdc++.h>
using namespace std;
/// POLICY BASED DATA STRUCTURE..
/// order_of_key return number of element which are strictly greater/smaller than x..
/// find_by_order return ans iterator corresponding to the xth position of the set..
// #include<ext/pb_ds/assoc_container.hpp>
// #include<ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less_equal<int>, rb_tree_tag, tree_order_statistics_node_update>
#define faster \
ios_base::sync_with_stdio(false); \
cin.tie(NULL)
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define allr(x) (x).rbegin(), (x).rend()
#define sz(n) (int)(n).size()
#define eps 1e-10
#define YES cout << "YES" << endl
#define NO cout << "NO" << endl
#define Yes cout << "Yes" << endl;
#define No cout << "No" << endl;
#define yes cout << "yes" << endl;
#define no cout << "no" << endl;
#define min3(a, b, c) min(c, min(a, b))
#define min4(a, b, c, d) min(d, min(c, min(a, b)))
#define max3(a, b, c) max(c, max(a, b))
#define max4(a, b, c, d) max(d, max(c, max(a, b)))
#define pi 2 * acos(0) /// acos(-1.0)
#define deg_to_rad(x) ((x) * ((2 * acos(0)) / 180.0))
#define rad_to_deg(x) ((x) * (180.0 / (2 * acos(0))))
#define fi first
#define sc second
#define mp make_pair
#define __lcm(a, b) (a / __gcd(a, b) * b)
typedef long long ll;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int M = 1e9 + 7;
const int N = 200020;
// ll n,m,i,k,h;
vector<ll> prime_divisor[N];
int vis[N];
vector<int> edge[N];
bool cmp(pair<ll, ll> p1, pair<ll, ll> p2)
{
return p1.fi < p2.fi;
}
vector<int> dfsarr;
int st[N], en[N];
char a[N];
// node i subtree { dfsarr[st[i],en[i]] }
void dfs(int u, int par) // 1 based
{
dfsarr.pb(u);
st[u] = sz(dfsarr) - 1; // starting idx of node u in dfs array
for (int v : edge[u])
{
if (v == par)
continue;
dfs(v, u);
}
en[u] = sz(dfsarr) - 1; // ending idx of node u in dfs array
}
struct Node
{
ll bit[27] = {};
};
Node seg[4 * N];
class SGTree
{
// vector<ll> seg; // mx,cnt;
public:
SGTree(int n)
{
// seg.resize(4 * n);
}
void merge(int ind)
{
for (int i = 0; i < 26; i++)
{
seg[ind].bit[i] = (seg[2 * ind].bit[i] + seg[2 * ind + 1].bit[i]);
}
}
void fix(int ind, ll val)
{
for (int i = 0; i < 26; i++)
{
seg[ind].bit[i] = (((val - 'a') == i) ? 1 : 0);
}
}
void build(int ind, int low, int high)
{
if (low == high)
{
fix(ind, a[dfsarr[low]]);
return;
}
int mid = (low + high) >> 1;
build(2 * ind, low, mid);
build(2 * ind + 1, mid + 1, high);
merge(ind);
}
void update(int ind, int low, int high, int i, ll val) // a[i]=val
{
if (low == high)
{
fix(ind, val);
return;
}
int mid = (low + high) >> 1;
if (i <= mid)
update(2 * ind, low, mid, i, val);
else
update(2 * ind + 1, mid + 1, high, i, val);
merge(ind);
}
Node query(int ind, int low, int high, int l, int r)
{
if (r < low || high < l)
{
Node nn;
return nn;
}
if (l <= low && high <= r)
{
return seg[ind];
}
int mid = (low + high) >> 1;
Node left = query(2 * ind, low, mid, l, r);
Node right = query(2 * ind + 1, mid + 1, high, l, r);
Node ret;
for (int i = 0; i < 26; i++)
{
ret.bit[i] = (left.bit[i] +right.bit[i]);
}
return ret;
}
};
void solve()
{
ll i, j, k, n, m, p, q, x, y, z, u, v, l, r, mod = 1e9 + 7, mx, mn, mx1, mn1, cnt1, cnt;
cin >> n;
for(i=1;i<=n;i++)
{
cin>>a[i];
}
for (i = 2; i <= n; i++)
{
cin >> u >> v;
edge[u].pb(v);
edge[v].pb(u);
}
dfsarr.pb(10000000); // 1 based hisab korar jonno
dfs(1, -1);
SGTree ss(n);
ss.build(1, 1, n);
cin>>q;
while (q--)
{
cin >> x;
if (x == 1)
{
char ch;
cin >> u >> ch;
ss.update(1, 1, n, st[u], ch);
}
else
{
cin >> u;
Node xx=ss.query(1, 1, n, st[u], en[u]);
ll mxx=0;
char ans='a';
for(i=0;i<26;i++)
{
if(mxx<xx.bit[i])
{
mxx=xx.bit[i];
ans=(char)(i+'a');
}
}
cout<<ans<<endl;
}
}
}
int main()
{
faster;
ll tc = 1;
// cin>>tc;
for (ll t = 1; t <= tc; t++)
{
/// cout<<"Case "<<t<<": ";
solve();
}
return 0;
}