#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define NMAX 520100
#define NODE_LOGMAX 20
//#define SOL_TRIVIAL // construieste efectiv fiecare arr (prin copiere) ; raspunde in O(1) la fiecare query
//#define SOL_M // O(1) pentru fiecare concatenare ; O(M) pentru fiecare query; memorie: O(M)//
#define SOL_LOGM_LOGLMAX_1 // O(1) pentru fiecare concatenare ; O(log(M)*log(LMAX)) pentru fiecare query; memorie: O(M*log(M)) (preprocesari de stramosi)
//#define SOL_LOGM_LOGLMAX_2 // O(1) pentru fiecare concatenare ; O(log(M)*log(LMAX)) pentru fiecare query; memorie: O(M)
#define max(u,v) ((u) >= (v) ? (u) : (v))
int i, a, b, c, N, M, Q;
int val[NMAX], left[NMAX], right[NMAX], h[NMAX];
long long len[NMAX], psum[NMAX], p, sum;
#ifdef SOL_TRIVIAL
int *arr[NMAX];
void solTrivial()
{
// answer the queries
for (i = 1; i <= Q; i++)
{
scanf("%d %lld", &a, &p);
printf("%d\n", arr[a][p - 1]);
}
}
#endif
#ifdef SOL_M
void solM()
{
// answer the queries
for (i = 1; i <= Q; i++)
{
scanf("%d %lld", &a, &p);
while (len[a] > 1)
{
if (p > len[left[a]])
{
p -= len[left[a]];
a = right[a];
}
else
a = left[a];
}
printf("%d\n", val[a]);
}
}
#endif
#ifdef SOL_LOGM_LOGLMAX_1
int anc[NODE_LOGMAX][NMAX];
void solLogMLogLMAX1()
{
// compute the anc values
for (i = N + 1; i <= N + M; i++)
{
if (len[left[i]] >= len[right[i]])
anc[0][i] = left[i];
else
anc[0][i] = right[i];
}
for (a = 1; a < NODE_LOGMAX; a++)
for (i = N + 1; i <= N + M; i++)
anc[a][i] = anc[a - 1][anc[a - 1][i]];
// compute the psum values
for (i = N + 1; i <= N + M; i++)
if (anc[0][i] == left[i])
psum[i] = psum[anc[0][i]];
else
psum[i] = psum[anc[0][i]] + len[left[i]];
// answer the queries
for (i = 1; i <= Q; i++)
{
scanf("%d %lld", &a, &p);
while (len[a] > 1)
{
b = NODE_LOGMAX - 1;
while (!anc[b][a])
b--;
while (b >= 0)
{
sum = psum[a] - psum[anc[b][a]];
if (p - sum >= 1 && p - sum <= len[anc[b][a]])
{
p -= sum;
a = anc[b][a];
}
b--;
}
if (len[a] > 1)
{
if (p > len[left[a]])
{
p -= len[left[a]];
a = right[a];
}
else
a = left[a];
}
}
printf("%d\n", val[a]);
}
}
#endif
#ifdef SOL_LOGM_LOGLMAX_2
int parent[NMAX], cnt[NMAX], maxSonCnt[NMAX], maxSon[NMAX], pathLen[NMAX], pathRoot[NMAX];
int bit[NMAX];
int *path[NMAX];
void solLogMLogLMAX2()
{
// compute the parent values
for (i = N + 1; i <= N + M; i++)
{
if (len[left[i]] >= len[right[i]])
parent[i] = left[i];
else
parent[i] = right[i];
}
for (i = N + M; i > N; i--)
{
cnt[i]++;
pathLen[i]++;
cnt[parent[i]] += cnt[i];
if (cnt[i] > maxSonCnt[parent[i]])
{
maxSonCnt[parent[i]] = cnt[i];
maxSon[parent[i]] = i;
pathLen[parent[i]] = pathLen[i];
}
}
for (i = 1; i <= N; i++)
{
cnt[i]++;
pathLen[i]++;
}
for (i = 1; i <= N + M; i++)
if (len[i] == 1 || i != maxSon[parent[i]])
{
path[i] = (int*) malloc(pathLen[i] * sizeof(int));
path[i][pathLen[i] - 1] = i;
pathRoot[i] = i;
}
else
{
path[i] = NULL;
pathRoot[i] = pathRoot[parent[i]];
path[pathRoot[i]][pathLen[i] - 1] = i;
}
// compute the psum values
for (i = N + 1; i <= N + M; i++)
if (parent[i] == left[i])
psum[i] = psum[parent[i]];
else
psum[i] = psum[parent[i]] + len[left[i]];
// compute the powers of two
bit[0] = 1;
for (i = 1; i < NODE_LOGMAX; i++)
bit[i] = bit[i - 1] * 2;
// answer the queries
for (i = 1; i <= Q; i++)
{
scanf("%d %lld", &a, &p);
while (len[a] > 1)
{
if (a == pathRoot[a])
{
if (p > len[left[a]])
{
p -= len[left[a]];
a = right[a];
}
else
a = left[a];
}
else
{
sum = psum[a] - psum[pathRoot[a]];
if (p - sum >= 1 && p - sum <= len[pathRoot[a]])
{
p -= sum;
a = pathRoot[a];
}
else
{
b = NODE_LOGMAX - 1;
while (b >= 0)
{
if (pathLen[a] - 1 + bit[b] < pathLen[pathRoot[a]])
{
c = path[pathRoot[a]][pathLen[a] - 1 + bit[b]];
sum = psum[a] - psum[c];
if (p - sum >= 1 && p - sum <= len[c])
{
p -= sum;
a = c;
}
}
b--;
}
if (len[a] > 1)
{
if (p > len[left[a]])
{
p -= len[left[a]];
a = right[a];
}
else
a = left[a];
}
}
}
}
printf("%d\n", val[a]);
//fprintf(stderr, "%d done\n", i);
}
}
#endif
void solve()
{
freopen("carray.in", "r", stdin);
freopen("carray.out", "w", stdout);
scanf("%d %d %d", &N, &M, &Q);
for (i = 1; i <= N; i++)
{
scanf("%d", &val[i]);
len[i] = 1;
#ifdef SOL_TRIVIAL
arr[i] = (int*) malloc(sizeof(int));
arr[i][0] = val[i];
#else
left[i] = right[i] = h[i] = 0;
#endif
}
for (i = N + 1; i <= N + M; i++)
{
scanf("%d %d", &a, &b);
len[i] = len[a] + len[b];
#ifdef SOL_TRIVIAL
arr[i] = (int*) malloc(len[i] * sizeof(int));
memcpy(&arr[i][0], &arr[a][0], len[a] * sizeof(int));
memcpy(&arr[i][len[a]], &arr[b][0], len[b] * sizeof(int));
#else
left[i] = a;
right[i] = b;
h[i] = 1 + max(h[a], h[b]);
#endif
}
#ifdef SOL_TRIVIAL
solTrivial();
#endif
#ifdef SOL_M
solM();
#endif
#ifdef SOL_LOGM_LOGLMAX_1
solLogMLogLMAX1();
#endif
#ifdef SOL_LOGM_LOGLMAX_2
solLogMLogLMAX2();
#endif
}
int main()
{
int tstart = clock();
solve();
fprintf(stderr, "Duration = %.3lf sec\n", ((double) (clock() - tstart)) / CLOCKS_PER_SEC);
return 0;
}