#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
template <typename T>
struct Segtree_ptr {
  int N;
  struct Node {
    int l, r;
    vector<int> ch;
    T val;
    Node(int l, int r) : l(l), r(r) {
      val = INF;
      ch.resize(2, -1);
    }
  };
  vector<Node> nodes;
  Segtree_ptr() {}
  Segtree_ptr(int Nin) { initialize(Nin); }
  void initialize(int Nin) {
    N = 1;
    while (N < Nin) N <<= 1;
  }
  int create() {
    nodes.push_back(Node(0, N));
    return nodes.size() - 1;
  }
  T getval(int nd) { return (nd != -1 ? nodes[nd].val : INF); }
  void update(int k, T x) { update(0, k, x); }
  void update(int nd, int k, T x) {
    int l = nodes[nd].l, r = nodes[nd].r;
    if (k < l || r <= k) return;
    if (r - l == 1) {
      nodes[nd].val = min(nodes[nd].val, x);
    } else {
      int d = (r - l) / 2;
      int t = (k - l) / d;
      if (nodes[nd].ch[t] == -1) {
        nodes[nd].ch[t] = nodes.size();
        nodes.push_back(Node(l + t * d, l + (t + 1) * d));
      }
      update(nodes[nd].ch[t], k, x);
      nodes[nd].val = min(getval(nodes[nd].ch[0]), getval(nodes[nd].ch[1]));
    }
  }
  T between(int a, int b) { return query(0, a, b + 1); }
  T query(int nd, int a, int b) {
    if (nd == -1) return INF;
    int l = nodes[nd].l, r = nodes[nd].r;
    if (b <= l || r <= a) return INF;
    if (a <= l && r <= b) return nodes[nd].val;
    return min(query(nodes[nd].ch[0], a, b), query(nodes[nd].ch[1], a, b));
  }
};
Segtree_ptr<int> stpt;
template <typename T>
struct Segtree {
  int n;
  vector<int> dat;
  Segtree() {}
  Segtree(int n_input, int m_input) { initialize(n_input, m_input); }
  void initialize(int n_input, int m_input) {
    n = 1;
    while (n < n_input) n <<= 1;
    stpt.initialize(m_input);
    dat.resize(2 * n - 1);
    for (auto& a : dat) a = stpt.create();
  }
  void update(int k, int x, T a) {
    k += n - 1;
    stpt.update(dat[k], x, a);
    while (k > 0) {
      k = (k - 1) / 2;
      stpt.update(dat[k], x, a);
    }
  }
  T between(int a, int b, int s, int t) {
    return query(a, b + 1, 0, 0, n, s, t);
  }
  T query(int a, int b, int k, int l, int r, int s, int t) {
    if (r <= a || b <= l) return INF;
    if (a <= l && r <= b) return stpt.query(dat[k], s, t + 1);
    T vl = query(a, b, 2 * k + 1, l, (l + r) / 2, s, t);
    T vr = query(a, b, 2 * k + 2, (l + r) / 2, r, s, t);
    return min(vl, vr);
  }
};
int depth[100000];
struct EulerTour {
  int sz = 0;
  vector<int> L, R;
  EulerTour() {}
  EulerTour(int N, vector<int> G[], int root = 0) { initialize(N, G, root); }
  void dfs(int i, int p, vector<int> G[], int d) {
    depth[i] = d;
    L[i] = sz;
    bool first = true;
    for (int j : G[i])
      if (j != p) {
        if (!first) sz++;
        first = false;
        dfs(j, i, G, d + 1);
      }
    R[i] = sz;
  }
  void initialize(int N, vector<int> G[], int root) {
    L.resize(N);
    R.resize(N);
    dfs(root, -1, G, 0);
  }
};
int main() {
  int N, R;
  cin >> N >> R;
  R--;
  vector<int> A(N);
  for (int i = 0; i < N; i++) scanf("%d", &A[i]);
  vector<int> edges[100000];
  for (int i = 0; i < N - 1; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    a--;
    b--;
    edges[a].push_back(b);
    edges[b].push_back(a);
  }
  EulerTour et(N, edges, R);
  int mx_len = *max_element(et.L.begin(), et.L.end());
  int mx_depth = *max_element(depth, depth + N);
  Segtree<int> st(mx_len + 1, mx_depth + 1);
  for (int i = 0; i < N; i++) st.update(et.L[i], depth[i], A[i]);
  int Q;
  cin >> Q;
  int last = 0;
  while (Q--) {
    int p, q;
    scanf("%d %d", &p, &q);
    int x = (p + last) % N, k = (q + last) % N;
    int ds = depth[x];
    int dt = min(mx_depth, ds + k);
    int ans = st.between(et.L[x], et.R[x], ds, dt);
    printf("%d\n", ans);
    last = ans;
  }
  return 0;
}
