//Zory-2018
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<bitset>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#ifdef DEBUG
const int LOCAL=1;
#else
const int LOCAL=0;
#endif

namespace mine
{
	typedef long long ll;
	const int INF=0x3f3f3f3f;
	int qread()
	{
		int ans=0;char c=getchar();
		while(c<'0' or c>'9') c=getchar();
		while(c>='0' and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans;
	}
	void qwrite(int num)
	{
		if(num>=10) qwrite(num/10);
		putchar('0'+num%10);
	}
	void qwriteln(int num) {qwrite(num);puts("");}

	int n;

	const int MAX_N=110000;
	struct Nod{int hou;int num;int bfsid;Nod(){hou=bfsid=0;}}p[MAX_N];
	int yz[MAX_N];//dfn->id
	struct Edge{int y,g;}e[MAX_N*2];
	int ln=0;void ins(int x,int y) {e[++ln]=(Edge){y,p[x].hou};p[x].hou=ln;}

	int down[MAX_N];//down
	void predep(int x,int fa)
	{
		down[x]=0;
		for(int k=p[x].hou;k>0;k=e[k].g)
		{
			int y=e[k].y;if(y==fa) continue;
			predep(y,x);down[x]=max(down[x],down[y]+1);
		}
	}

	//bin意义下
	int bin[30],log[MAX_N];
	int mxpos[MAX_N];
	void pre()
	{
		bin[0]=1;for(int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
		log[1]=0;for(int i=2;i<MAX_N;i++) log[i]=log[i>>1]+1;
		mxpos[1]=0;for(int i=2;i<MAX_N;i++) mxpos[i]=mxpos[i>>1]+1;
	}

	struct Tree//一切编号按照bfs序
	{
		//L、R树中，编号大为父亲
		int fa[MAX_N];
		int ff[MAX_N][30];
		vector<int> son[MAX_N];
		void pre1()
		{
			for(int i=n;i>=1;i--)
			{
				son[fa[i]].push_back(i);
				ff[i][0]=fa[i];
				for(int t=1;t<=20;t++) ff[i][t]=ff[ff[i][t-1]][t-1];
			}
		}
		int mxdep[MAX_N];
		int bson[MAX_N];//长儿子
		void pre2(int x)//0=虚根
		{
			mxdep[x]=0;bson[x]=0;
			for(int t=0;t<(int)son[x].size();t++)
			{
				int y=son[x][t];
				pre2(y);
				mxdep[x]=max(mxdep[x],mxdep[y]+1);
				if(bson[x]==0 or mxdep[y]>=mxdep[bson[x]]) bson[x]=y;
			}
		}
		int belg[MAX_N],pos[MAX_N];//所在长链、位置
		vector<int> id[MAX_N];int tot;
		void pre3(int x,int blg)
		{
			pos[x]=id[blg].size();
			id[blg].push_back(x);
			belg[x]=blg;
			if(bson[x]>0) pre3(bson[x],blg);
			for(int t=0;t<(int)son[x].size();t++) if(son[x][t]!=bson[x]) pre3(son[x][t],++tot);
		}
		vector<int> up[MAX_N];//在链顶记录，向上的，长度为链长的链
		void pre4()
		{
			for(int now=1;now<=tot;now++)
			{
				int top=id[now][0];
				int tmp=top;up[top].push_back(-1);
				for(int t=1;t<=(int)id[now].size();t++)
				{
					up[top].push_back(tmp=fa[tmp]);
					if(tmp==0) break;
				}
			}
		}

		int getfa(int x,int k)
		{
			if(k==0) return -1;

			/*
			倍增版，log
			for(int t=20;t>=0;t--)
				if(bin[t]<=k and ff[x][t]!=0) x=ff[x][t],k-=bin[t];
			return k==0?x:-1;*/

			int wt=mxpos[k];
			x=ff[x][wt];k-=bin[wt];
			if(pos[x]>=k) return id[belg[x]][pos[x]-k];
			else
			{
				int top=id[belg[x]][0];
				if(k-pos[x]<=(int)up[top].size()-1) return up[top][k-pos[x]];
				else return -1;//debug
			}
		}

		Tree() {tot=1;}
		void pre()
		{
			pre1();pre2(0);pre3(0,1);pre4();
		}
	}L,R;
	int h[MAX_N];//bfs深度
	queue<int> q;
	void bfs(int rt)//bfs序和L、R指针
	{
		int id=1;q.push(rt);h[rt]=0;
		p[rt].bfsid=id;yz[id]=rt;
		while(!q.empty())
		{
			int x=q.front();q.pop();
			bool bk=1;//是否叶子
			int st=id+1,now=p[x].bfsid;
			for(int k=p[x].hou;k>0;k=e[k].g)
			{
				int y=e[k].y;if(p[y].bfsid) continue;
				h[y]=h[x]+1;bk=0;
				p[y].bfsid=++id;yz[id]=y;
				q.push(y);
			}
			if(!bk) L.fa[now]=st,R.fa[now]=id;
			else L.fa[now]=id+1,R.fa[now]=id;

		}
		for(int i=1;i<=n;i++)//边缘
		{
			if(h[yz[i]]+1!=h[yz[L.fa[i]]]) L.fa[i]=0;
			if(h[yz[i]]+1!=h[yz[R.fa[i]]]) R.fa[i]=0;
		}
	}

	int dp[MAX_N][30][30];
	void DP()
	{
		memset(dp,63,sizeof dp);
		for(int i=n;i>=1;i--)
		{
			for(int a=0;a<=20 and i+bin[a]-1<=n and h[yz[i]]==h[yz[i+bin[a]-1]];a++)//同一层
			{
				for(int b=0;b<=20;b++)
				{
					//if(i==9 and a==0 and b==1)
					//	puts("");

					if(a==0 and b==0) dp[i][a][b]=p[yz[i]].num;
					else if(b==0) dp[i][a][b]=min(dp[i][a-1][b],dp[i+bin[a-1]][a-1][b]);
					else
					{
						int fl=L.getfa(i,bin[b-1]),fr=R.getfa(i+bin[a]-1,bin[b-1]);
						if(fl<=0 or fr<=0 or fl>fr)//debug fl>fr的情况忘记判断
						{
							dp[i][a][b]=dp[i][a][b-1];//debug 延长转移，避免参差不齐的深度
							continue;
						}
						int k=log[fr-fl+1];
						dp[i][a][b]=min(dp[i][a][b-1],min(dp[fl][k][b-1],dp[fr-bin[k]+1][k][b-1]));
					}
				}
			}
		}
	}
	int solve(int x,int cc)//层数
	{
		cc=min(cc,down[x]+1);
		if(cc==1) return p[x].num;
		else
		{
			x=p[x].bfsid;

			int k=log[cc];
			int fl,fr;
			if(cc==bin[k]) fl=fr=x;
			else fl=L.getfa(x,cc-1-bin[k]+1),fr=R.getfa(x,cc-1-bin[k]+1);//转步数
			//往下

			if(fl<=0 or fr<=0) puts("error");

			int k2=log[fr-fl+1];
			return min(dp[x][0][k],min(dp[fl][k2][k],dp[fr-bin[k2]+1][k2][k]));
		}
	}
	void main()
	{
		pre();

		int rt;scanf("%d%d",&n,&rt);
		for(int i=1;i<=n;i++) scanf("%d",&p[i].num);
		for(int i=1;i<=n-1;i++) {int x,y;scanf("%d%d",&x,&y);ins(x,y);ins(y,x);}

		bfs(rt);predep(rt,0);
		L.pre();R.pre();
		DP();

		//for(int i=1;i<=n;i++) printf("%d ",p[i].bfsid);
		//puts("");

		int m;scanf("%d",&m);
		int lst=0;
		while(m--)
		{
			int x=qread(),dis=qread();
			x=(x+lst)%n+1;dis=(dis+lst)%n;
			qwriteln(lst=solve(x,dis+1));
		}
	}
};
int main()
{
	mine::main();
}


//Zory-2018
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<bitset>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#ifdef DEBUG
const int LOCAL=1;
#else
const int LOCAL=0;
#endif

namespace mine
{
	typedef long long ll;
	const int INF=0x3f3f3f3f;
	int qread()
	{
		int ans=0;char c=getchar();
		while(c<'0' or c>'9') c=getchar();
		while(c>='0' and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans;
	}
	void qwrite(int num)
	{
		if(num>=10) qwrite(num/10);
		putchar('0'+num%10);
	}
	void qwriteln(int num) {qwrite(num);puts("");}

	int n;

	const int MAX_N=110000;
	struct Nod{int hou;int num;int bfsid;Nod(){hou=bfsid=0;}}p[MAX_N];
	int yz[MAX_N];//dfn->id
	struct Edge{int y,g;}e[MAX_N*2];
	int ln=0;void ins(int x,int y) {e[++ln]=(Edge){y,p[x].hou};p[x].hou=ln;}

	int down[MAX_N];//down
	void predep(int x,int fa)
	{
		down[x]=0;
		for(int k=p[x].hou;k>0;k=e[k].g)
		{
			int y=e[k].y;if(y==fa) continue;
			predep(y,x);down[x]=max(down[x],down[y]+1);
		}
	}

	//bin意义下
	int bin[30],log[MAX_N];
	int mxpos[MAX_N];
	void pre()
	{
		bin[0]=1;for(int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
		log[1]=0;for(int i=2;i<MAX_N;i++) log[i]=log[i>>1]+1;
		mxpos[1]=0;for(int i=2;i<MAX_N;i++) mxpos[i]=mxpos[i>>1]+1;
	}

	struct Tree//一切编号按照bfs序
	{
		//L、R树中，编号大为父亲
		int fa[MAX_N];
		int ff[MAX_N][30];
		vector<int> son[MAX_N];
		void pre1()
		{
			for(int i=n;i>=1;i--)
			{
				son[fa[i]].push_back(i);
				ff[i][0]=fa[i];
				for(int t=1;t<=20;t++) ff[i][t]=ff[ff[i][t-1]][t-1];
			}
		}
		int mxdep[MAX_N];
		int bson[MAX_N];//长儿子
		void pre2(int x)//0=虚根
		{
			mxdep[x]=0;bson[x]=0;
			for(int t=0;t<(int)son[x].size();t++)
			{
				int y=son[x][t];
				pre2(y);
				mxdep[x]=max(mxdep[x],mxdep[y]+1);
				if(bson[x]==0 or mxdep[y]>=mxdep[bson[x]]) bson[x]=y;
			}
		}
		int belg[MAX_N],pos[MAX_N];//所在长链、位置
		vector<int> id[MAX_N];int tot;
		void pre3(int x,int blg)
		{
			pos[x]=id[blg].size();
			id[blg].push_back(x);
			belg[x]=blg;
			if(bson[x]>0) pre3(bson[x],blg);
			for(int t=0;t<(int)son[x].size();t++) pre3(son[x][t],++tot);
		}
		vector<int> up[MAX_N];//在链顶记录，向上的，长度为链长的链
		void pre4()
		{
			for(int now=1;now<=tot;now++)
			{
				int top=id[now][0];
				int tmp=top;up[top].push_back(-1);
				for(int t=1;t<=(int)id[now].size();t++) up[top].push_back(tmp=fa[tmp]);
			}
		}

		int getfa(int x,int k)
		{
			if(k==0) return -1;
			int wt=mxpos[k];
			x=ff[x][wt];k-=bin[wt];
			if(pos[x]>=k) return id[belg[x]][pos[x]-k];
			else
			{
				int top=id[belg[x]][0];
				if(k-pos[x]<=(int)up[top].size()-1) return up[top][k-pos[x]];
				else return -1;//debug
			}
		}

		Tree() {tot=1;}
		void pre()
		{
			pre1();pre2(0);pre3(0,1);pre4();
		}
	}L,R;
	int h[MAX_N];//bfs深度
	queue<int> q;
	void bfs(int rt)//bfs序和L、R指针
	{
		int id=1;q.push(rt);h[rt]=0;
		p[rt].bfsid=id;yz[id]=rt;
		while(!q.empty())
		{
			int x=q.front();q.pop();
			bool bk=1;//是否叶子
			int st=id+1,now=p[x].bfsid;
			for(int k=p[x].hou;k>0;k=e[k].g)
			{
				int y=e[k].y;if(p[y].bfsid) continue;
				h[y]=h[x]+1;bk=0;
				p[y].bfsid=++id;yz[id]=y;
				q.push(y);
			}
			if(!bk) L.fa[now]=st,R.fa[now]=id;
			else L.fa[now]=id+1,R.fa[now]=id;

		}
		for(int i=1;i<=n;i++)//边缘
		{
			if(h[yz[i]]+1!=h[yz[L.fa[i]]]) L.fa[i]=0;
			if(h[yz[i]]+1!=h[yz[R.fa[i]]]) R.fa[i]=0;
		}
	}

	int dp[MAX_N][30][30];
	void DP()
	{
		memset(dp,63,sizeof dp);
		for(int i=n;i>=1;i--)
		{
			for(int a=0;a<=20 and i+bin[a]-1<=n and h[yz[i]]==h[yz[i+bin[a]-1]];a++)//同一层
			{
				for(int b=0;b<=20;b++)
				{
					//if(i==2 and a==1 and b==1)
					//	puts("");

					if(a==0 and b==0) dp[i][a][b]=p[yz[i]].num;
					else if(b==0) dp[i][a][b]=min(dp[i][a-1][b],dp[i+bin[a-1]][a-1][b]);
					else
					{
						int fl=L.getfa(i,bin[b-1]),fr=R.getfa(i+bin[a]-1,bin[b-1]);
						if(fl<0 or fr<0) break;
						int k=log[fr-fl+1];
						dp[i][a][b]=min(dp[i][a][b-1],min(dp[fl][k][b-1],dp[fr-bin[k]+1][k][b-1]));
					}
				}
			}
		}
	}
	int solve(int x,int cc)//层数
	{
		cc=min(cc,down[x]+1);
		if(cc==1) return p[x].num;
		else
		{
			x=p[x].bfsid;

			int k=log[cc];
			int fl,fr;
			if(cc==bin[k]) fl=fr=x;
			else fl=L.getfa(x,cc-1-bin[k]+1),fr=R.getfa(x,cc-1-bin[k]+1);//转步数
			//往下

			if(fl<0 or fr<0) puts("error");

			int k2=log[fr-fl+1];
			return min(dp[x][0][k],min(dp[fl][k2][k],dp[fr-bin[k2]+1][k2][k]));
		}
	}
	void main()
	{
		pre();

		int rt;scanf("%d%d",&n,&rt);
		for(int i=1;i<=n;i++) scanf("%d",&p[i].num);
		for(int i=1;i<=n-1;i++) {int x,y;scanf("%d%d",&x,&y);ins(x,y);ins(y,x);}

		bfs(rt);predep(rt,0);
		L.pre();R.pre();
		/*puts("");
		for(int i=1;i<=n;i++)
		{
			for(int t=1;t<=15;t++) printf("(%d,%d) ",L.getfa(i,t),R.getfa(i,t));
			puts("");
		}*/
		DP();

		int m;scanf("%d",&m);
		int lst=0;
		while(m--)
		{
			int x=qread(),dis=qread();
			x=(x+lst)%n+1;dis=(dis+lst)%n;
			qwriteln(lst=solve(x,dis+1));
		}
	}
};
int main()
{
	mine::main();
}


//Zory-2018
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<bitset>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#ifdef DEBUG
const int LOCAL=1;
#else
const int LOCAL=0;
#endif

namespace mine
{
	typedef long long ll;
	const int INF=0x3f3f3f3f;
	int qread()
	{
		int ans=0;char c=getchar();
		while(c<'0' or c>'9') c=getchar();
		while(c>='0' and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans;
	}
	void qwrite(int num)
	{
		if(num>=10) qwrite(num/10);
		putchar('0'+num%10);
	}
	void qwriteln(int num) {qwrite(num);puts("");}

	int n;

	const int MAX_N=110000;
	struct Nod{int hou;int num;int bfsid;Nod(){hou=bfsid=0;}}p[MAX_N];
	int yz[MAX_N];//dfn->id
	struct Edge{int y,g;}e[MAX_N*2];
	int ln=0;void ins(int x,int y) {e[++ln]=(Edge){y,p[x].hou};p[x].hou=ln;}

	int down[MAX_N];//down
	void predep(int x,int fa)
	{
		down[x]=0;
		for(int k=p[x].hou;k>0;k=e[k].g)
		{
			int y=e[k].y;if(y==fa) continue;
			predep(y,x);down[x]=max(down[x],down[y]+1);
		}
	}

	//bin意义下
	int bin[30],log[MAX_N];
	int mxpos[MAX_N];
	void pre()
	{
		bin[0]=1;for(int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
		log[1]=0;for(int i=2;i<MAX_N;i++) log[i]=log[i>>1]+1;
		mxpos[1]=0;for(int i=2;i<MAX_N;i++) mxpos[i]=mxpos[i>>1]+1;
	}

	struct Tree//一切编号按照bfs序
	{
		//L、R树中，编号大为父亲
		int fa[MAX_N];
		int ff[MAX_N][30];
		vector<int> son[MAX_N];
		void pre1()
		{
			for(int i=n;i>=1;i--)
			{
				son[fa[i]].push_back(i);
				ff[i][0]=fa[i];
				for(int t=1;t<=20;t++) ff[i][t]=ff[ff[i][t-1]][t-1];
			}
		}
		int mxdep[MAX_N];
		int bson[MAX_N];//长儿子
		void pre2(int x)//0=虚根
		{
			mxdep[x]=0;bson[x]=0;
			for(int t=0;t<(int)son[x].size();t++)
			{
				int y=son[x][t];
				pre2(y);
				mxdep[x]=max(mxdep[x],mxdep[y]+1);
				if(bson[x]==0 or mxdep[y]>=mxdep[bson[x]]) bson[x]=y;
			}
		}
		int belg[MAX_N],pos[MAX_N];//所在长链、位置
		vector<int> id[MAX_N];int tot;
		void pre3(int x,int blg)
		{
			pos[x]=id[blg].size();
			id[blg].push_back(x);
			belg[x]=blg;
			if(bson[x]>0) pre3(bson[x],blg);
			for(int t=0;t<(int)son[x].size();t++) if(son[x][t]!=bson[x]) pre3(son[x][t],++tot);
		}
		vector<int> up[MAX_N];//在链顶记录，向上的，长度为链长的链
		void pre4()
		{
			//int all=0;
			for(int now=1;now<=tot;now++)
			{
				int top=id[now][0];
				int tmp=top;up[top].push_back(-1);
				for(int t=1;t<=(int)id[now].size();t++)
				{
					up[top].push_back(tmp=fa[tmp]);
					if(tmp==0) break;
				}
				//all+=up[top].size();
				//printf("all=%d\n",all);
			}
		}

		int getfa(int x,int k)
		{
			if(k==0) return -1;
			int wt=mxpos[k];
			x=ff[x][wt];k-=bin[wt];
			if(pos[x]>=k) return id[belg[x]][pos[x]-k];
			else
			{
				int top=id[belg[x]][0];
				if(k-pos[x]<=(int)up[top].size()-1) return up[top][k-pos[x]];
				else return -1;//debug
			}
		}

		Tree() {tot=1;}
		void pre()
		{
			pre1();pre2(0);pre3(0,1);pre4();
		}
	}L,R;
	int h[MAX_N];//bfs深度
	queue<int> q;
	void bfs(int rt)//bfs序和L、R指针
	{
		int id=1;q.push(rt);h[rt]=0;
		p[rt].bfsid=id;yz[id]=rt;
		while(!q.empty())
		{
			int x=q.front();q.pop();
			bool bk=1;//是否叶子
			int st=id+1,now=p[x].bfsid;
			for(int k=p[x].hou;k>0;k=e[k].g)
			{
				int y=e[k].y;if(p[y].bfsid) continue;
				h[y]=h[x]+1;bk=0;
				p[y].bfsid=++id;yz[id]=y;
				q.push(y);
			}
			if(!bk) L.fa[now]=st,R.fa[now]=id;
			else L.fa[now]=id+1,R.fa[now]=id;

		}
		for(int i=1;i<=n;i++)//边缘
		{
			if(h[yz[i]]+1!=h[yz[L.fa[i]]]) L.fa[i]=0;
			if(h[yz[i]]+1!=h[yz[R.fa[i]]]) R.fa[i]=0;
		}
	}

	int dp[MAX_N][30][30];
	void DP()
	{
		memset(dp,63,sizeof dp);
		for(int i=n;i>=1;i--)
		{
			for(int a=0;a<=20 and i+bin[a]-1<=n and h[yz[i]]==h[yz[i+bin[a]-1]];a++)//同一层
			{
				for(int b=0;b<=20;b++)
				{
					if(i==5 and a==0 and b==2)
						puts("");

					if(a==0 and b==0) dp[i][a][b]=p[yz[i]].num;
					else if(b==0) dp[i][a][b]=min(dp[i][a-1][b],dp[i+bin[a-1]][a-1][b]);
					else
					{
						int fl=L.getfa(i,bin[b-1]),fr=R.getfa(i+bin[a]-1,bin[b-1]);
						if(fl<=0 or fr<=0)
						{
							dp[i][a][b]=dp[i][a][b-1];//debug 延长转移，避免参差不齐的深度
							break;
						}
						int k=log[fr-fl+1];
						dp[i][a][b]=min(dp[i][a][b-1],min(dp[fl][k][b-1],dp[fr-bin[k]+1][k][b-1]));
					}
				}
			}
		}
	}
	int solve(int x,int cc)//层数
	{
		cc=min(cc,down[x]+1);
		if(cc==1) return p[x].num;
		else
		{
			x=p[x].bfsid;

			int k=log[cc];
			int fl,fr;
			if(cc==bin[k]) fl=fr=x;
			else fl=L.getfa(x,cc-1-bin[k]+1),fr=R.getfa(x,cc-1-bin[k]+1);//转步数
			//往下

			if(fl<0 or fr<0) puts("error");

			int k2=log[fr-fl+1];
			return min(dp[x][0][k],min(dp[fl][k2][k],dp[fr-bin[k2]+1][k2][k]));
		}
	}
	void main()
	{
		//freopen("tmp.in","r",stdin);

		pre();

		int rt;scanf("%d%d",&n,&rt);
		for(int i=1;i<=n;i++) scanf("%d",&p[i].num);
		for(int i=1;i<=n-1;i++) {int x,y;scanf("%d%d",&x,&y);ins(x,y);ins(y,x);}

		bfs(rt);predep(rt,0);
		L.pre();R.pre();
		/*puts("");
		for(int i=1;i<=n;i++)
		{
			for(int t=1;t<=15;t++) printf("(%d,%d) ",L.getfa(i,t),R.getfa(i,t));
			puts("");
		}*/
		DP();

		int m;scanf("%d",&m);
		int lst=0;
		while(m--)
		{
			int x=qread(),dis=qread();
			x=(x+lst)%n+1;dis=(dis+lst)%n;
			qwriteln(lst=solve(x,dis+1));
		}
	}
};
int main()
{
	mine::main();
}


//Zory-2018
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<bitset>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#ifdef DEBUG
const int LOCAL=1;
#else
const int LOCAL=0;
#endif

namespace mine
{
	typedef long long ll;
	const int INF=0x3f3f3f3f;
	int qread()
	{
		int ans=0;char c=getchar();
		while(c<'0' or c>'9') c=getchar();
		while(c>='0' and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans;
	}
	void qwrite(int num)
	{
		if(num>=10) qwrite(num/10);
		putchar('0'+num%10);
	}
	void qwriteln(int num) {qwrite(num);puts("");}

	int n;

	const int MAX_N=110000;
	struct Nod{int hou;int num;int bfsid;Nod(){hou=bfsid=0;}}p[MAX_N];
	int yz[MAX_N];//dfn->id
	struct Edge{int y,g;}e[MAX_N*2];
	int ln=0;void ins(int x,int y) {e[++ln]=(Edge){y,p[x].hou};p[x].hou=ln;}

	int down[MAX_N];//down
	void predep(int x,int fa)
	{
		down[x]=0;
		for(int k=p[x].hou;k>0;k=e[k].g)
		{
			int y=e[k].y;if(y==fa) continue;
			predep(y,x);down[x]=max(down[x],down[y]+1);
		}
	}

	//bin意义下
	int bin[30],log[MAX_N];
	int mxpos[MAX_N];
	void pre()
	{
		bin[0]=1;for(int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
		log[1]=0;for(int i=2;i<MAX_N;i++) log[i]=log[i>>1]+1;
		mxpos[1]=0;for(int i=2;i<MAX_N;i++) mxpos[i]=mxpos[i>>1]+1;
	}

	struct Tree//一切编号按照bfs序
	{
		//L、R树中，编号大为父亲
		int fa[MAX_N];
		int ff[MAX_N][30];
		vector<int> son[MAX_N];
		void pre1()
		{
			for(int i=n;i>=1;i--)
			{
				son[fa[i]].push_back(i);
				ff[i][0]=fa[i];
				for(int t=1;t<=20;t++) ff[i][t]=ff[ff[i][t-1]][t-1];
			}
		}
		int mxdep[MAX_N];
		int bson[MAX_N];//长儿子
		void pre2(int x)//0=虚根
		{
			mxdep[x]=0;bson[x]=0;
			for(int t=0;t<(int)son[x].size();t++)
			{
				int y=son[x][t];
				pre2(y);
				mxdep[x]=max(mxdep[x],mxdep[y]+1);
				if(bson[x]==0 or mxdep[y]>=mxdep[bson[x]]) bson[x]=y;
			}
		}
		int belg[MAX_N],pos[MAX_N];//所在长链、位置
		vector<int> id[MAX_N];int tot;
		void pre3(int x,int blg)
		{
			pos[x]=id[blg].size();
			id[blg].push_back(x);
			belg[x]=blg;
			if(bson[x]>0) pre3(bson[x],blg);
			for(int t=0;t<(int)son[x].size();t++) pre3(son[x][t],++tot);
		}
		vector<int> up[MAX_N];//在链顶记录，向上的，长度为链长的链
		void pre4()
		{
			for(int now=1;now<=tot;now++)
			{
				int top=id[now][0];
				int tmp=top;up[top].push_back(-1);
				for(int t=1;t<=(int)id[now].size();t++) up[top].push_back(tmp=fa[tmp]);
			}
		}

		int getfa(int x,int k)
		{
			if(k==0) return -1;
			int wt=mxpos[k];
			x=ff[x][wt];k-=bin[wt];
			if(pos[x]>=k) return id[belg[x]][pos[x]-k];
			else return up[ id[belg[x]][0] ][k-pos[x]];
		}

		Tree() {tot=1;}
		void pre()
		{
			pre1();pre2(0);pre3(0,1);pre4();
		}
	}L,R;
	int h[MAX_N];//bfs深度
	queue<int> q;
	void bfs(int rt)//bfs序和L、R指针
	{
		int id=1;q.push(rt);h[rt]=0;
		p[rt].bfsid=id;yz[id]=rt;
		while(!q.empty())
		{
			int x=q.front();q.pop();
			bool bk=1;//是否叶子
			int st=id+1,now=p[x].bfsid;
			for(int k=p[x].hou;k>0;k=e[k].g)
			{
				int y=e[k].y;if(p[y].bfsid) continue;
				h[y]=h[x]+1;bk=0;
				p[y].bfsid=++id;yz[id]=y;
				q.push(y);
			}
			if(!bk) L.fa[now]=st,R.fa[now]=id;
			else L.fa[now]=id,R.fa[now]=id+1;

		}
		for(int i=1;i<=n;i++)//边缘
		{
			if(h[yz[i]]+1!=h[yz[L.fa[i]]]) L.fa[i]=0;
			if(h[yz[i]]+1!=h[yz[R.fa[i]]]) R.fa[i]=0;
		}
	}

	int dp[MAX_N][30][30];
	void DP()
	{
		memset(dp,63,sizeof dp);
		for(int i=n;i>=1;i--)
		{
			for(int a=0;a<=20 and i+bin[a]-1<=n and h[yz[i]]==h[yz[i+bin[a]-1]];a++)//同一层
			{
				for(int b=0;b<=20 and bin[b]<=down[yz[i]]+1;b++)
				{
					if(a==0 and b==0) dp[i][a][b]=p[yz[i]].num;
					else if(b==0) dp[i][a][b]=min(dp[i][a-1][b],dp[i+bin[a-1]][a-1][b]);
					else
					{
						int fl=L.getfa(i,bin[b-1]),fr=R.getfa(i+bin[a]-1,bin[b-1]);
						if(fl<0 or fr<0) break;
						int k=log[fr-fl+1];
						dp[i][a][b]=min(dp[i][a][b-1],min(dp[fl][k][b-1],dp[fr-bin[k]+1][k][b-1]));
					}
				}
			}
		}
	}
	int solve(int x,int cc)//层数
	{
		cc=min(cc,down[x]+1);
		if(cc==1) return p[x].num;
		else
		{
			x=p[x].bfsid;

			int k=log[cc];
			int fl,fr;
			if(cc==bin[k]) fl=fr=x;
			else fl=L.getfa(x,cc-1-bin[k]+1),fr=R.getfa(x,cc-1-bin[k]+1);//转步数
			//往下

			if(fl<0 or fr<0) puts("error");

			int k2=log[fr-fl+1];
			return min(dp[x][0][k],min(dp[fl][k2][k],dp[fr-bin[k2]+1][k2][k]));
		}
	}
	void main()
	{
		pre();

		int rt;scanf("%d%d",&n,&rt);
		for(int i=1;i<=n;i++) scanf("%d",&p[i].num);
		for(int i=1;i<=n-1;i++) {int x,y;scanf("%d%d",&x,&y);ins(x,y);ins(y,x);}

		bfs(rt);predep(rt,0);
		L.pre();R.pre();
		/*puts("");
		for(int i=1;i<=n;i++)
		{
			for(int t=1;t<=15;t++) printf("(%d,%d) ",L.getfa(i,t),R.getfa(i,t));
			puts("");
		}*/
		DP();

		int m;scanf("%d",&m);
		int lst=0;
		while(m--)
		{
			int x=qread(),dis=qread();
			x=(x+lst)%n+1;dis=(dis+lst)%n;
			qwriteln(lst=solve(x,dis+1));
		}
	}
};
int main()
{
	mine::main();
}


//Zory-2018
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<bitset>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#ifdef DEBUG
const int LOCAL=1;
#else
const int LOCAL=0;
#endif

namespace mine
{
	typedef long long ll;
	const int INF=0x3f3f3f3f;
	int qread()
	{
		int ans=0;char c=getchar();
		while(c<'0' or c>'9') c=getchar();
		while(c>='0' and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans;
	}
	void qwrite(int num)
	{
		if(num>=10) qwrite(num/10);
		putchar('0'+num%10);
	}
	void qwriteln(int num) {qwrite(num);puts("");}

	int n;

	const int MAX_N=110000;
	struct Nod{int hou;int num;int bfsid;Nod(){hou=bfsid=0;}}p[MAX_N];
	int yz[MAX_N];//dfn->id
	struct Edge{int y,g;}e[MAX_N*2];
	int ln=0;void ins(int x,int y) {e[++ln]=(Edge){y,p[x].hou};p[x].hou=ln;}

	int down[MAX_N];//down
	void predep(int x,int fa)
	{
		down[x]=0;
		for(int k=p[x].hou;k>0;k=e[k].g)
		{
			int y=e[k].y;if(y==fa) continue;
			predep(y,x);down[x]=max(down[x],down[y]+1);
		}
	}

	//bin意义下
	int bin[30],log[MAX_N];
	int mxpos[MAX_N];
	void pre()
	{
		bin[0]=1;for(int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
		log[1]=0;for(int i=2;i<MAX_N;i++) log[i]=log[i>>1]+1;
		mxpos[1]=0;for(int i=2;i<MAX_N;i++) mxpos[i]=mxpos[i>>1]+1;
	}

	struct Tree//一切编号按照bfs序
	{
		//L、R树中，编号大为父亲
		int fa[MAX_N];
		int ff[MAX_N][30];
		vector<int> son[MAX_N];
		void pre1()
		{
			for(int i=n;i>=1;i--)
			{
				son[fa[i]].push_back(i);
				ff[i][0]=fa[i];
				for(int t=1;t<=20;t++) ff[i][t]=ff[ff[i][t-1]][t-1];
			}
		}
		int mxdep[MAX_N];
		int bson[MAX_N];//长儿子
		void pre2(int x)//0=虚根
		{
			mxdep[x]=0;bson[x]=0;
			for(int t=0;t<(int)son[x].size();t++)
			{
				int y=son[x][t];
				pre2(y);
				mxdep[x]=max(mxdep[x],mxdep[y]+1);
				if(bson[x]==0 or mxdep[y]>=mxdep[bson[x]]) bson[x]=y;
			}
		}
		int belg[MAX_N],pos[MAX_N];//所在长链、位置
		vector<int> id[MAX_N];int tot;
		void pre3(int x,int blg)
		{
			pos[x]=id[blg].size();
			id[blg].push_back(x);
			belg[x]=blg;
			if(bson[x]>0) pre3(bson[x],blg);
			for(int t=0;t<(int)son[x].size();t++) if(son[x][t]!=bson[x]) pre3(son[x][t],++tot);
		}
		vector<int> up[MAX_N];//在链顶记录，向上的，长度为链长的链
		void pre4()
		{
			//int all=0;
			for(int now=1;now<=tot;now++)
			{
				int top=id[now][0];
				int tmp=top;up[top].push_back(-1);
				for(int t=1;t<=(int)id[now].size();t++)
				{
					up[top].push_back(tmp=fa[tmp]);
					if(tmp==0) break;
				}
				//all+=up[top].size();
				//printf("all=%d\n",all);
			}
		}

		int getfa(int x,int k)
		{
			if(k==0) return -1;

			for(int t=20;t>=0;t--)
				if(bin[t]<=k and ff[x][t]!=0) x=ff[x][t],k-=bin[t];
			return k==0?x:-1;

			/*int wt=mxpos[k];
			x=ff[x][wt];k-=bin[wt];
			if(pos[x]>=k) return id[belg[x]][pos[x]-k];
			else
			{
				int top=id[belg[x]][0];
				if(k-pos[x]<=(int)up[top].size()-1) return up[top][k-pos[x]];
				else return -1;//debug
			}*/
		}

		Tree() {tot=1;}
		void pre()
		{
			pre1();pre2(0);pre3(0,1);pre4();
		}
	}L,R;
	int h[MAX_N];//bfs深度
	queue<int> q;
	void bfs(int rt)//bfs序和L、R指针
	{
		int id=1;q.push(rt);h[rt]=0;
		p[rt].bfsid=id;yz[id]=rt;
		while(!q.empty())
		{
			int x=q.front();q.pop();
			bool bk=1;//是否叶子
			int st=id+1,now=p[x].bfsid;
			for(int k=p[x].hou;k>0;k=e[k].g)
			{
				int y=e[k].y;if(p[y].bfsid) continue;
				h[y]=h[x]+1;bk=0;
				p[y].bfsid=++id;yz[id]=y;
				q.push(y);
			}
			if(!bk) L.fa[now]=st,R.fa[now]=id;
			else L.fa[now]=id+1,R.fa[now]=id;

		}
		for(int i=1;i<=n;i++)//边缘
		{
			if(h[yz[i]]+1!=h[yz[L.fa[i]]]) L.fa[i]=0;
			if(h[yz[i]]+1!=h[yz[R.fa[i]]]) R.fa[i]=0;
		}
	}

	int dp[MAX_N][30][30];
	void DP()
	{
		memset(dp,63,sizeof dp);
		for(int i=n;i>=1;i--)
		{
			for(int a=0;a<=20 and i+bin[a]-1<=n and h[yz[i]]==h[yz[i+bin[a]-1]];a++)//同一层
			{
				for(int b=0;b<=20;b++)
				{
					//if(i==5 and a==0 and b==2)
					//	puts("");

					if(a==0 and b==0) dp[i][a][b]=p[yz[i]].num;
					else if(b==0) dp[i][a][b]=min(dp[i][a-1][b],dp[i+bin[a-1]][a-1][b]);
					else
					{
						int fl=L.getfa(i,bin[b-1]),fr=R.getfa(i+bin[a]-1,bin[b-1]);
						if(fl<=0 or fr<=0)
						{
							dp[i][a][b]=dp[i][a][b-1];//debug 延长转移，避免参差不齐的深度
							break;
						}
						int k=log[fr-fl+1];
						dp[i][a][b]=min(dp[i][a][b-1],min(dp[fl][k][b-1],dp[fr-bin[k]+1][k][b-1]));
					}
				}
			}
		}
	}
	int solve(int x,int cc)//层数
	{
		cc=min(cc,down[x]+1);
		if(cc==1) return p[x].num;
		else
		{
			x=p[x].bfsid;

			int k=log[cc];
			int fl,fr;
			if(cc==bin[k]) fl=fr=x;
			else fl=L.getfa(x,cc-1-bin[k]+1),fr=R.getfa(x,cc-1-bin[k]+1);//转步数
			//往下

			if(fl<=0 or fr<=0) puts("error");

			int k2=log[fr-fl+1];
			return min(dp[x][0][k],min(dp[fl][k2][k],dp[fr-bin[k2]+1][k2][k]));
		}
	}
	void main()
	{
		pre();

		int rt;scanf("%d%d",&n,&rt);
		for(int i=1;i<=n;i++) scanf("%d",&p[i].num);
		for(int i=1;i<=n-1;i++) {int x,y;scanf("%d%d",&x,&y);ins(x,y);ins(y,x);}

		bfs(rt);predep(rt,0);
		L.pre();R.pre();
		DP();

		int m;scanf("%d",&m);
		int lst=0;
		while(m--)
		{
			int x=qread(),dis=qread();
			x=(x+lst)%n+1;dis=(dis+lst)%n;
			qwriteln(lst=solve(x,dis+1));
		}
	}
};
int main()
{
	mine::main();
}


//Zory-2018
#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<map>
#include<set>
#include<queue>
#include<deque>
#include<stack>
#include<bitset>
#include<vector>
#include<algorithm>
#include<iostream>
using namespace std;
#ifdef DEBUG
const int LOCAL=1;
#else
const int LOCAL=0;
#endif

namespace mine
{
	typedef long long ll;
	const int INF=0x3f3f3f3f;
	int qread()
	{
		int ans=0;char c=getchar();
		while(c<'0' or c>'9') c=getchar();
		while(c>='0' and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans;
	}
	void qwrite(ll num)
	{
		if(num>=10) qwrite(num/10);
		putchar('0'+num%10);
	}
	void qwriteln(ll num) {qwrite(num);puts("");}

	const int MAX_N=110000;
	struct Nod{int hou;int num;int bfsid;Nod(){hou=bfsid=0;}}p[MAX_N];
	int yz[MAX_N];//dfn->id
	struct Edge{int y,g;}e[MAX_N*2];
	int ln=0;void ins(int x,int y) {e[++ln]=(Edge){y,p[x].hou};p[x].hou=ln;}

	queue<int> q;
	void bfs(int rt)
	{
		int id=0;q.push(rt);
		while(!q.empty())
		{
			int x=q.front();q.pop();
			p[x].bfsid=++id;yz[id]=x;
			for(int k=p[x].hou;k>0;k=e[k].g) if(p[e[k].y].bfsid==0) q.push(e[k].y);
		}
	}

	struct Lian
	{
		int to[MAX_N];
		int blg[MAX_N],pos[MAX_N];
		vector<int> id[MAX_N];
		int tot;Lian(){tot=1;}
		int down(int x,int k)
		{
			int t=blg[x];
			return (pos[x]+k<=(int)id[t].size()-1)?(id[t][pos[x]+k]):-1;
		}
	}g[2];
	void pre(int x,int fa)
	{
		int now=p[x].bfsid;
		g[0].to[now]=INF;g[1].to[now]=0;
		for(int k=p[x].hou;k>0;k=e[k].g)
		{
			int y=e[k].y;if(y==fa) continue;
			g[0].to[now]=min(g[0].to[now],p[y].bfsid);
			g[1].to[now]=max(g[1].to[now],p[y].bfsid);
			pre(y,x);
		}
	}
	void pre_col(int type,int x,int fa,int blg)
	{
		int now=p[x].bfsid;
		g[type].blg[now]=blg;
		g[type].pos[now]=g[type].id[blg].size();
		g[type].id[blg].push_back(now);
		for(int k=p[x].hou;k>0;k=e[k].g)
		{
			int y=e[k].y;if(y==fa) continue;
			if(p[y].bfsid==g[type].to[now]) pre_col(type,y,x,blg);
			else pre_col(type,y,x,++g[type].tot);
		}
	}

	int n;
	int f[MAX_N][30][30];
	int bin[30],log[MAX_N];
	void dp()
	{
		bin[0]=1;for(int i=1;i<=20;i++) bin[i]=bin[i-1]*2;
		log[1]=0;for(int i=2;i<MAX_N;i++) log[i]=log[i/2]+1;

		memset(f,63,sizeof f);
		for(int i=n;i>=1;i--)
		{
			for(int a=0;a<=20 and i+bin[a]-1<=g[1].to[i];a++)
			{
				for(int b=0;b<=20;b++)
				{
					if(a==0 and b==0) f[i][a][b]=p[yz[i]].num;
					else if(b==0) f[i][a][b]=min(f[i][a-1][b],f[i+bin[a-1]][a-1][b]);
					else
					{
						int fl=g[0].down(i,bin[b-1]),fr=g[1].down(i+bin[a]-1,bin[b-1]);
						if(fl<0 or fr<0) break;
						int k=log[fr-fl+1];//非整次幂的长度
						f[i][a][b]=min(f[i][a][b-1],min(f[fl][k][b-1],f[fr-bin[k]+1][k][b-1]));
					}
				}
			}
		}
	}
	int solve(int x,int cc)//层数
	{
		if(cc==1) return p[x].num;
		else
		{
			x=p[x].bfsid;
			int mxcc=g[0].id[g[0].blg[x]].size()-1-g[0].pos[x]+1;
			cc=min(cc,mxcc);
			int k=log[cc];

			int fl=g[0].down(x,cc-1-bin[k]+1),fr=g[1].down(x,cc-1-bin[k]+1);
			int k2=log[fr-fl+1];
			return min(f[x][0][k],min(f[fl][k2][k],f[fr-bin[k2]+1][k2][k]));
		}
	}
	void main()
	{
		int rt;scanf("%d%d",&n,&rt);
		for(int i=1;i<=n;i++) scanf("%d",&p[i].num);
		for(int i=1;i<=n-1;i++) {int x,y;scanf("%d%d",&x,&y);ins(x,y);ins(y,x);}

		bfs(rt);pre(rt,0);pre_col(0,rt,0,1);pre_col(1,rt,0,1);
		dp();

		int m;scanf("%d",&m);
		int lst=0;
		while(m--)
		{
			int x,dis;scanf("%d%d",&x,&dis);
			x=(x+lst)%n+1;dis=(dis+lst)%n;
			//printf("ask=%d %d\n",x,dis);
			printf("%d\n",lst=solve(x,dis+1));
		}
	}
};
int main()
{
	mine::main();
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 100200
#define M 200100
#define INF 0x7f7f7f7f
struct node{
	int to,next;
}q[M];
int head[N],ss,a[N],Rt,root[N],n,dep[N],tree[N*400],ls[N*400],rs[N*400],cc;
void addedge(int x,int y)
{
	q[++ss]=(node){y,head[x]};head[x]=ss;
	q[++ss]=(node){x,head[y]};head[y]=ss;
}
void insert(int &i,int l,int r,int pos,int k)
{
	if (!i) i=++cc,tree[i]=INF;
	if (l==r)
	{
		tree[i]=k;
		return;
	}
	int mid=(l+r)>>1;
	if (pos<=mid) insert(ls[i],l,mid,pos,k);
	else insert(rs[i],mid+1,r,pos,k);
	tree[i]=min(tree[ls[i]],tree[rs[i]]);
}
//void merge(int &x,int y)
//{
//	if (!y) return;
//	if (!x) x=++cc,tree[x]=tree[y];
//	else tree[x]=min(tree[x],tree[y]);
//	merge(ls[x],ls[y]);
//	merge(rs[x],rs[y]);
//}
int merge(int x,int y)
{
	if (!x||!y) return x|y;
	int rt=++cc;
	ls[rt]=merge(ls[x],ls[y]);
	rs[rt]=merge(rs[x],rs[y]);
	tree[rt]=min(tree[x],tree[y]);
	return rt;
}
//void print(int i,int l,int r)
//{
//	if (l==r) {printf("dep:%d   %d\n",l,tree[i]);return;}
//	int mid=(l+r)>>1;
//	if (ls[i]) print(ls[i],l,mid);
//	if (rs[i]) print(rs[i],mid+1,r);
//}
void dfs(int i,int fa)
{
	dep[i]=dep[fa]+1;
	insert(root[i],1,n,dep[i],a[i]);
	for (int j=head[i];j;j=q[j].next)
		if (q[j].to!=fa)
		{
			int t=q[j].to;
			dfs(t,i);
			root[i]=merge(root[i],root[t]);
		}
}
int query(int i,int l,int r,int L,int R)
{
	if (!i) return INF;
	if (L<=l&&r<=R) return tree[i];
	int mid=(l+r)>>1;
	if (L>mid) return query(rs[i],mid+1,r,L,R);
	if (R<=mid) return query(ls[i],l,mid,L,R);
	return min(query(ls[i],l,mid,L,mid),query(rs[i],mid+1,r,mid+1,R));
}
int read(){
	int n=0;char a;bool z=false;
	while(a=getchar())
	{
		if (a>'9'||a<'0')
			if (z) break;
			else continue;
		if (!z) z=true;
		n=(n<<1)+(n<<3)+(a^48);
	}
	return n;
}
int main()
{
	tree[0]=INF;
	int lstans=0,Q,x,k;
	n=read();Rt=read();
	for (int i=1;i<=n;++i) a[i]=read();
	for (int i=1;i<n;++i) addedge(read(),read());
	dfs(Rt,0);
	Q=read();
	while(Q--)
	{
		x=(read()+lstans)%n+1;k=(read()+lstans)%n;
		cout<<(lstans=query(root[x],1,n,dep[x],min(dep[x]+k,n)))<<'\n';
	}
	return 0;
}


#include<cstdio>
#include<iostream>
using namespace std;
#define N 100200
#define M 200100
#define INF 0x3f3f3f3f
struct node{
	int to,next;
}q[M];
int head[N],ss,a[N],Rt,root[N],n,dep[N],tree[N*400],ls[N*400],rs[N*400],cc;
void addedge(int x,int y)
{
	q[++ss]=(node){y,head[x]};head[x]=ss;
	q[++ss]=(node){x,head[y]};head[y]=ss;
}
void insert(int &i,int l,int r,int pos,int k)
{
	if (!i) i=++cc;
	if (l==r)
	{
		tree[i]=k;
		return;
	}
	int mid=(l+r)>>1;
	if (pos<=mid) insert(ls[i],l,mid,pos,k);
	else insert(rs[i],mid+1,r,pos,k);
	tree[i]=min(tree[ls[i]],tree[rs[i]]);
}
int merge(int &x,int y)
{
	if (!x||!y) return x|y;
	if (!x) x=++cc;
	tree[x]=min(tree[x],tree[y]);
	ls[x]=merge(ls[x],ls[y]);
	rs[x]=merge(rs[x],rs[y]);
	return x;
}
void dfs(int i,int fa)
{
	dep[i]=dep[fa]+1;
	insert(root[i],1,n,dep[i],a[i]);
	for (int j=head[i];j;j=q[j].next)
		if (q[j].to!=fa)
		{
			int t=q[j].to;
			dfs(t,i);
			merge(root[i],root[t]);
		}
}
int query(int i,int l,int r,int L,int R)
{
	if (!i) return INF;
	if (L<=l&&r<=R) return tree[i];
	int mid=(l+r)>>1;
	if (L>mid) return query(rs[i],mid+1,r,L,R);
	if (R<=mid) return query(ls[i],l,mid,L,R);
	return min(query(ls[i],l,mid,L,mid),query(rs[i],mid+1,r,mid+1,R));
}
int read(){
	int n=0;char a;bool z=false;
	while(a=getchar())
	{
		if (a>'9'||a<'0')
			if (z) break;
			else continue;
		if (!z) z=true;
		n=(n<<1)+(n<<3)+(a^48);
	}
	return n;
}
int main()
{
	tree[0]=INF;
	int lstans=0,Q,x,k;
	n=read();Rt=read();
	for (int i=1;i<=n;++i) a[i]=read();
	for (int i=1;i<n;++i) addedge(read(),read());
	dfs(Rt,Rt);
	Q=read();
	while(Q--)
	{
		x=(read()+lstans)%n+1;k=(read()+lstans)%n;
		cout<<(lstans=query(root[x],1,n,dep[x],dep[x]+k))<<'\n';
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 100200
#define M 200100
#define INF 0x3f3f3f3f
struct node{
	int to,next;
}q[M];
int head[N],ss,a[N],Rt,root[N],n,dep[N],tree[N*400],ls[N*400],rs[N*400],cc;
void addedge(int x,int y)
{
	q[++ss]=(node){y,head[x]};head[x]=ss;
	q[++ss]=(node){x,head[y]};head[y]=ss;
}
void insert(int &i,int l,int r,int pos,int k)
{
	if (!i) i=++cc,tree[i]=INF;
	if (l==r)
	{
		tree[i]=k;
		return;
	}
	int mid=(l+r)>>1;
	if (pos<=mid) insert(ls[i],l,mid,pos,k);
	else insert(rs[i],mid+1,r,pos,k);
	tree[i]=min(tree[ls[i]],tree[rs[i]]);
}
void merge(int &x,int y)
{
	if (!y) return;
	if (!x) x=++cc,tree[x]=tree[y];
	else tree[x]=min(tree[x],tree[y]);
	merge(ls[x],ls[y]);
	merge(rs[x],rs[y]);
}
void print(int i,int l,int r)
{
	if (l==r) {printf("dep:%d   %d\n",l,tree[i]);return;}
	int mid=(l+r)>>1;
	if (ls[i]) print(ls[i],l,mid);
	if (rs[i]) print(rs[i],mid+1,r);
}
void dfs(int i,int fa)
{
	dep[i]=dep[fa]+1;
	insert(root[i],1,n,dep[i],a[i]);
	for (int j=head[i];j;j=q[j].next)
		if (q[j].to!=fa)
		{
			int t=q[j].to;
			dfs(t,i);
			merge(root[i],root[t]);
		}
	if (i==6||i==9) printf("root=%d\n",i),print(root[i],1,n),putchar('\n');
}
int query(int i,int l,int r,int L,int R)
{
	if (!i) return INF;
	if (L<=l&&r<=R) return tree[i];
	int mid=(l+r)>>1;
	if (L>mid) return query(rs[i],mid+1,r,L,R);
	if (R<=mid) return query(ls[i],l,mid,L,R);
	return min(query(ls[i],l,mid,L,mid),query(rs[i],mid+1,r,mid+1,R));
}
int read(){
	int n=0;char a;bool z=false;
	while(a=getchar())
	{
		if (a>'9'||a<'0')
			if (z) break;
			else continue;
		if (!z) z=true;
		n=(n<<1)+(n<<3)+(a^48);
	}
	return n;
}
int main()
{
	tree[0]=INF;
//	memset(tree,0x3f,sizeof(tree));
	int lstans=0,Q,x,k;
	n=read();Rt=read();
	for (int i=1;i<=n;++i) a[i]=read();
	for (int i=1;i<n;++i) addedge(read(),read());
	dfs(Rt,Rt);
//	R:
//	for (int i=1;i<=n;++i) printf("Root=%d\n",i),print(root[i],1,n),putchar('\n');
//	printf("%dd\n",tree[0]);
	Q=read();
	while(Q--)
	{
		x=(read()+lstans)%n+1;k=(read()+lstans)%n;
		cout<<(lstans=query(root[x],1,n,dep[x],dep[x]+k))<<'\n';
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 100200
#define M 200100
#define INF 0x3f3f3f3f
struct node{
	int to,next;
}q[M];
int head[N],ss,a[N],Rt,root[N],n,dep[N],tree[N*400],ls[N*400],rs[N*400],cc;
void addedge(int x,int y)
{
	q[++ss]=(node){y,head[x]};head[x]=ss;
	q[++ss]=(node){x,head[y]};head[y]=ss;
}
void insert(int &i,int l,int r,int pos,int k)
{
	if (!i) i=++cc,tree[i]=INF;
	if (l==r)
	{
		tree[i]=k;
		return;
	}
	int mid=(l+r)>>1;
	if (pos<=mid) insert(ls[i],l,mid,pos,k);
	else insert(rs[i],mid+1,r,pos,k);
	tree[i]=min(tree[ls[i]],tree[rs[i]]);
}
void merge(int &x,int y)
{
	if (!y) return;
	if (!x) x=++cc,tree[x]=tree[y];
	else tree[x]=min(tree[x],tree[y]);
	merge(ls[x],ls[y]);
	merge(rs[x],rs[y]);
}
//void print(int i,int l,int r)
//{
//	if (l==r) {printf("dep:%d   %d\n",l,tree[i]);return;}
//	int mid=(l+r)>>1;
//	if (ls[i]) print(ls[i],l,mid);
//	if (rs[i]) print(rs[i],mid+1,r);
//}
void dfs(int i,int fa)
{
	dep[i]=dep[fa]+1;
	insert(root[i],1,n,dep[i],a[i]);
	for (int j=head[i];j;j=q[j].next)
		if (q[j].to!=fa)
		{
			int t=q[j].to;
			dfs(t,i);
			merge(root[i],root[t]);
		}
}
int query(int i,int l,int r,int L,int R)
{
	if (!i) return INF;
	if (L<=l&&r<=R) return tree[i];
	int mid=(l+r)>>1;
	if (L>mid) return query(rs[i],mid+1,r,L,R);
	if (R<=mid) return query(ls[i],l,mid,L,R);
	return min(query(ls[i],l,mid,L,mid),query(rs[i],mid+1,r,mid+1,R));
}
int read(){
	int n=0;char a;bool z=false;
	while(a=getchar())
	{
		if (a>'9'||a<'0')
			if (z) break;
			else continue;
		if (!z) z=true;
		n=(n<<1)+(n<<3)+(a^48);
	}
	return n;
}
int main()
{
	tree[0]=INF;
	int lstans=0,Q,x,k;
	n=read();Rt=read();
	for (int i=1;i<=n;++i) a[i]=read();
	for (int i=1;i<n;++i) addedge(read(),read());
	dfs(Rt,Rt);
	Q=read();
	while(Q--)
	{
		x=(read()+lstans)%n+1;k=(read()+lstans)%n;
		cout<<(lstans=query(root[x],1,n,dep[x],min(dep[x]+k,n)))<<'\n';
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 100200
#define M 200100
#define INF 0x3f3f3f3f
struct node{
	int to,next;
}q[M];
int head[N],ss,a[N],Rt,root[N],n,dep[N],tree[N*400],ls[N*400],rs[N*400],cc;
void addedge(int x,int y)
{
	q[++ss]=(node){y,head[x]};head[x]=ss;
	q[++ss]=(node){x,head[y]};head[y]=ss;
}
void insert(int &i,int l,int r,int pos,int k)
{
	if (!i) i=++cc,tree[i]=INF;
	if (l==r)
	{
		tree[i]=k;
		return;
	}
	int mid=(l+r)>>1;
	if (pos<=mid) insert(ls[i],l,mid,pos,k);
	else insert(rs[i],mid+1,r,pos,k);
	tree[i]=min(tree[ls[i]],tree[rs[i]]);
}
void merge(int &x,int y)
{
	if (!y) return;
	if (!x) x=++cc,tree[x]=tree[y];
	else tree[x]=min(tree[x],tree[y]);
	merge(ls[x],ls[y]);
	merge(rs[x],rs[y]);
}
void print(int i,int l,int r)
{
	if (l==r) {printf("dep:%d   %d\n",l,tree[i]);return;}
	int mid=(l+r)>>1;
	if (ls[i]) print(ls[i],l,mid);
	if (rs[i]) print(rs[i],mid+1,r);
}
void dfs(int i,int fa)
{
	dep[i]=dep[fa]+1;
	insert(root[i],1,n,dep[i],a[i]);
	for (int j=head[i];j;j=q[j].next)
		if (q[j].to!=fa)
		{
			int t=q[j].to;
			dfs(t,i);
			merge(root[i],root[t]);
		}
//	if (i==6||i==9) printf("root=%d\n",i),print(root[i],1,n),putchar('\n');
}
int query(int i,int l,int r,int L,int R)
{
	if (!i) return INF;
	if (L<=l&&r<=R) return tree[i];
	int mid=(l+r)>>1;
	if (L>mid) return query(rs[i],mid+1,r,L,R);
	if (R<=mid) return query(ls[i],l,mid,L,R);
	return min(query(ls[i],l,mid,L,mid),query(rs[i],mid+1,r,mid+1,R));
}
int read(){
	int n=0;char a;bool z=false;
	while(a=getchar())
	{
		if (a>'9'||a<'0')
			if (z) break;
			else continue;
		if (!z) z=true;
		n=(n<<1)+(n<<3)+(a^48);
	}
	return n;
}
int main()
{
	tree[0]=INF;
//	memset(tree,0x3f,sizeof(tree));
	int lstans=0,Q,x,k;
	n=read();Rt=read();
	for (int i=1;i<=n;++i) a[i]=read();
	for (int i=1;i<n;++i) addedge(read(),read());
	dfs(Rt,Rt);
//	R:
//	for (int i=1;i<=n;++i) printf("Root=%d\n",i),print(root[i],1,n),putchar('\n');
//	printf("%dd\n",tree[0]);
	Q=read();
	while(Q--)
	{
		x=(read()+lstans)%n+1;k=(read()+lstans)%n;
		cout<<(lstans=query(root[x],1,n,dep[x],dep[x]+k))<<'\n';
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 100200
#define M 200100
#define INF 0x3f3f3f3f
struct node{
	int to,next;
}q[M];
int head[N],ss,a[N],Rt,root[N],n,dep[N],tree[N*400],ls[N*400],rs[N*400],cc;
void addedge(int x,int y)
{
	q[++ss]=(node){y,head[x]};head[x]=ss;
	q[++ss]=(node){x,head[y]};head[y]=ss;
}
void insert(int &i,int l,int r,int pos,int k)
{
	if (!i) i=++cc,tree[i]=INF;
	if (l==r)
	{
		tree[i]=k;
		return;
	}
	int mid=(l+r)>>1;
	if (pos<=mid) insert(ls[i],l,mid,pos,k);
	else insert(rs[i],mid+1,r,pos,k);
	tree[i]=min(tree[ls[i]],tree[rs[i]]);
}
void merge(int &x,int y)
{
	if (!x||!y) {x|=y;return;}
	if (!x) x=++cc,tree[x]=INF;
	tree[x]=min(tree[x],tree[y]);
	merge(ls[x],ls[y]);
	merge(rs[x],rs[y]);
}
void dfs(int i,int fa)
{
	dep[i]=dep[fa]+1;
	insert(root[i],1,n,dep[i],a[i]);
	for (int j=head[i];j;j=q[j].next)
		if (q[j].to!=fa)
		{
			int t=q[j].to;
			dfs(t,i);
			merge(root[i],root[t]);
		}
}
int query(int i,int l,int r,int L,int R)
{
	if (!i) return INF;
	if (L<=l&&r<=R) return tree[i];
	int mid=(l+r)>>1;
	if (L>mid) return query(rs[i],mid+1,r,L,R);
	if (R<=mid) return query(ls[i],l,mid,L,R);
	return min(query(ls[i],l,mid,L,mid),query(rs[i],mid+1,r,mid+1,R));
}
int read(){
	int n=0;char a;bool z=false;
	while(a=getchar())
	{
		if (a>'9'||a<'0')
			if (z) break;
			else continue;
		if (!z) z=true;
		n=(n<<1)+(n<<3)+(a^48);
	}
	return n;
}
int main()
{
	tree[0]=INF;
//	memset(tree,0x3f,sizeof(tree));
	int lstans=0,Q,x,k;
	n=read();Rt=read();
	for (int i=1;i<=n;++i) a[i]=read();
	for (int i=1;i<n;++i) addedge(read(),read());
	dfs(Rt,Rt);
	Q=read();
	while(Q--)
	{
		x=(read()+lstans)%n+1;k=(read()+lstans)%n;
		cout<<(lstans=query(root[x],1,n,dep[x],dep[x]+k))<<'\n';
	}
	return 0;
}


#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
#define N 100200
#define M 200100
#define INF 0x7f7f7f7f
struct node{
	int to,next;
}q[M];
int head[N],ss,a[N],Rt,root[N],n,dep[N],tree[N*400],ls[N*400],rs[N*400],cc;
void addedge(int x,int y)
{
	q[++ss]=(node){y,head[x]};head[x]=ss;
	q[++ss]=(node){x,head[y]};head[y]=ss;
}
void insert(int &i,int l,int r,int pos,int k)
{
	if (!i) i=++cc,tree[i]=INF;
	if (l==r)
	{
		tree[i]=k;
		return;
	}
	int mid=(l+r)>>1;
	if (pos<=mid) insert(ls[i],l,mid,pos,k);
	else insert(rs[i],mid+1,r,pos,k);
	tree[i]=min(tree[ls[i]],tree[rs[i]]);
}
void merge(int &x,int y)
{
	if (!y) return;
	if (!x) x=++cc,tree[x]=tree[y];
	else tree[x]=min(tree[x],tree[y]);
	merge(ls[x],ls[y]);
	merge(rs[x],rs[y]);
}
//void print(int i,int l,int r)
//{
//	if (l==r) {printf("dep:%d   %d\n",l,tree[i]);return;}
//	int mid=(l+r)>>1;
//	if (ls[i]) print(ls[i],l,mid);
//	if (rs[i]) print(rs[i],mid+1,r);
//}
void dfs(int i,int fa)
{
	dep[i]=dep[fa]+1;
	insert(root[i],1,n,dep[i],a[i]);
	for (int j=head[i];j;j=q[j].next)
		if (q[j].to!=fa)
		{
			int t=q[j].to;
			dfs(t,i);
			merge(root[i],root[t]);
		}
}
int query(int i,int l,int r,int L,int R)
{
	if (!i) return INF;
	if (L<=l&&r<=R) return tree[i];
	int mid=(l+r)>>1;
	if (L>mid) return query(rs[i],mid+1,r,L,R);
	if (R<=mid) return query(ls[i],l,mid,L,R);
	return min(query(ls[i],l,mid,L,mid),query(rs[i],mid+1,r,mid+1,R));
}
int read(){
	int n=0;char a;bool z=false;
	while(a=getchar())
	{
		if (a>'9'||a<'0')
			if (z) break;
			else continue;
		if (!z) z=true;
		n=(n<<1)+(n<<3)+(a^48);
	}
	return n;
}
int main()
{
	tree[0]=INF;
	int lstans=0,Q,x,k;
	n=read();Rt=read();
	for (int i=1;i<=n;++i) a[i]=read();
	for (int i=1;i<n;++i) addedge(read(),read());
	dfs(Rt,0);
	Q=read();
	while(Q--)
	{
		x=(read()+lstans)%n+1;k=(read()+lstans)%n;
		cout<<(lstans=query(root[x],1,n,dep[x],min(dep[x]+k,n)))<<'\n';
	}
	return 0;
}


#include<bits/stdc++.h>
#define LL long long int
#define FIO ios::sync_with_stdio(false)
#define FRD freopen("input.txt","r",stdin)
#define lowbit(x) (x&-(x))
#define INF 2e9
#define ms(x) memset(x,0,sizeof x)
#define pb(x) push_back(x)
#define lson l,mid,now<<1
#define rson mid+1,r,now<<1|1
#define UNIQUE(x) unique(x.begin(),x.end())
#define SORT(x) sort(x.begin(),x.end())
#define LISAN(x) x.erase(UNIQUE(x),x.end())
#define pii pair<int,int>
#define pll pair<LL,LL>
#define N 200010
const LL MOD=1e9+7;
using namespace std;
template<class T> inline T Min(const T& a,const T& b){return a<b?a:b;}
template<class T> inline T Max(const T& a,const T& b){return a<b?b:a;}
inline void inc(int &x,int &v,int &mod){x+=v;if(x>=mod) x-=mod;}
inline void dec(int &x,int &v,int &mod){x-=v;if(x<0) x+=mod;}
inline int read(){char ch = getchar();int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
inline LL readl(){char ch = getchar();LL x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
struct ModSegementTree{
	LL sum[N<<5];
	int L[N<<5], R[N<<5],cnt=0;
	inline int build(int l, int r){
	    int rt = ++ cnt;
	    sum[rt] =1e15 ;
	    int mid=(l+r)/2;
	    if (l < r){
	        L[rt] = build(l, mid);
	        R[rt] = build(mid+1,r);
	    }
	    return rt;
	}
	inline int update(int &pre, int l, int r,const int &pos,const LL &x){
	    int rt = ++ cnt;
	    L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = Min(sum[pre],x);
	    int mid=(l+r)/2;
	    if (l < r){
	        if (pos <= mid) L[rt] = update(L[pre], l, mid,pos, x);
	        else R[rt] = update(R[pre], mid+1, r,pos, x);
	    }
	    return rt;
	}
	inline LL query(int &u,int ll,int rr,int l,int r){
	    if(ll>r||rr<l)
	        return INF;
	    if(ll<=l&&r<=rr){
	        return sum[u];
	    }
	    LL ans=1e15;
	    int mid=(l+r)/2;
	    if(ll<=mid)
	        ans=Min(ans,query(L[u],ll,rr,l,mid));
	    if(mid<rr)
	        ans=Min(ans,query(R[u],ll,rr,mid+1,r));
	    return ans;
	}
}Tree;
namespace G{
	vector<int> vec[N];
	LL val[N];
	int bfn[N],sz[N],in[N],level[N],rt[N],dep[N],tot;
	bool vis[N];
	void bfs(int s){
		queue<int> Q;
		Q.push(s);
		int tim=0,now_dep=0;
		while(Q.size()){
			int now=Q.front();Q.pop();
			bfn[++tim]=now;
			vis[now]=true;
			for(auto to:vec[now]){
				if(!vis[to]){
					Q.push(to);
				}
			}
		}
	}
	void dfs(int x,int fa,int dis){
		in[x]=++tot;
		sz[x]=1;
		dep[x]=dis;
		for(auto to:vec[x]){
			if(to==fa)	continue;
			dfs(to,x,dis+1);
			sz[x]+=sz[to];
		}
	}
	void init(int n,int root){
		rt[0]=Tree.build(1,n);
		for(int i=1;i<=n;i++){
			if(dep[bfn[i]]!=dep[bfn[i-1]]){
				rt[dep[bfn[i]]]=rt[dep[bfn[i-1]]];
			}
			rt[dep[bfn[i]]]=Tree.update(rt[dep[bfn[i-1]]],1,n,in[bfn[i]],val[bfn[i]]);
		}
	}
	LL solve(int x,int k,int n){
		int id=rt[Min(dep[bfn[n]],dep[x]+k)];
		return Tree.query(id,in[x],in[x]+sz[x]-1,1,n);
	}
}
int main(){
	#ifndef ONLINE_JUDGE
    	int startTime = clock();
		FRD;
	#endif
	int n=read(),rt=read();
	for(int i=1;i<=n;i++)	G::val[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G::vec[u].pb(v);
		G::vec[v].pb(u);
	}
	G::dfs(rt,rt,1);
	G::bfs(rt);
	G::init(n,rt);
	int q=read();
	LL lastans=0;
	while(q--){
		int x=(read()+lastans)%n+1,k=(read()+lastans)%n;
		lastans=G::solve(x,k,n);
		printf("%lld\n",lastans);
	}
	#ifndef ONLINE_JUDGE
    	printf("Time = %dms\n", clock() - startTime);
	#endif
	return 0;
}


#include<bits/stdc++.h>
#define LL long long int
#define FIO ios::sync_with_stdio(false)
#define FRD freopen("input.txt","r",stdin)
#define lowbit(x) (x&-(x))
#define INF 2e9
#define ms(x) memset(x,0,sizeof x)
#define pb(x) push_back(x)
#define lson l,mid,now<<1
#define rson mid+1,r,now<<1|1
#define UNIQUE(x) unique(x.begin(),x.end())
#define SORT(x) sort(x.begin(),x.end())
#define LISAN(x) x.erase(UNIQUE(x),x.end())
#define pii pair<int,int>
#define pll pair<LL,LL>
#define N 200010
const LL MOD=1e9+7;
using namespace std;
template<class T> inline T Min(const T& a,const T& b){return a<b?a:b;}
template<class T> inline T Max(const T& a,const T& b){return a<b?b:a;}
inline void inc(int &x,int &v,int &mod){x+=v;if(x>=mod) x-=mod;}
inline void dec(int &x,int &v,int &mod){x-=v;if(x<0) x+=mod;}
inline int read(){char ch = getchar();int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
inline LL readl(){char ch = getchar();LL x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
struct ModSegementTree{
	int sum[N<<5], L[N<<5], R[N<<5],cnt=0;
	inline int build(int l, int r){
	    int rt = ++ cnt;
	    sum[rt] = 2e9;
	    int mid=(l+r)/2;
	    if (l < r){
	        L[rt] = build(l, mid);
	        R[rt] = build(mid+1,r);
	    }
	    return rt;
	}
	inline int update(int &pre, int l, int r,const int &pos,const int &x){
	    int rt = ++ cnt;
	    L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = Min(sum[pre],x);
	    int mid=(l+r)/2;
	    if (l < r){
	        if (pos <= mid) L[rt] = update(L[pre], l, mid,pos, x);
	        else R[rt] = update(R[pre], mid+1, r,pos, x);
	    }
	    return rt;
	}
	inline int query(int &u,int ll,int rr,int l,int r){
	    if(ll>r||rr<l)
	        return INF;
	    if(ll<=l&&r<=rr){
	        return sum[u];
	    }
	    int ans=INF;
	    int mid=(l+r)/2;
	    if(ll<=mid)
	        ans=Min(ans,query(L[u],ll,rr,l,mid));
	    if(mid<rr)
	        ans=Min(ans,query(R[u],ll,rr,mid+1,r));
	    return ans;
	}
}Tree;
namespace G{
	vector<int> vec[N];
	LL val[N];
	int bfn[N],sz[N],in[N],level[N],rt[N],dep[N],tot;
	bool vis[N];
	void bfs(int s){
		queue<int> Q;
		Q.push(s);
		int tim=0,now_dep=0;
		while(Q.size()){
			int now=Q.front();Q.pop();
			bfn[++tim]=now;
			vis[now]=true;
			for(auto to:vec[now]){
				if(!vis[to]){
					Q.push(to);
				}
			}
		}
	}
	void dfs(int x,int fa,int dis){
		in[x]=++tot;
		sz[x]=1;
		dep[x]=dis;
		for(auto to:vec[x]){
			if(to==fa)	continue;
			dfs(to,x,dis+1);
			sz[x]+=sz[to];
		}
	}
	void init(int n,int root){
		rt[0]=Tree.build(1,n);
		rt[1]=Tree.update(rt[0],1,n,1,val[root]);
		for(int i=2;i<=n;i++){
			if(dep[bfn[i]]!=dep[bfn[i-1]]){
				rt[dep[bfn[i]]]=rt[dep[bfn[i-1]]];
			}
			rt[dep[bfn[i]]]=Tree.update(rt[dep[bfn[i-1]]],1,n,in[bfn[i]],val[bfn[i]]);
			//cout<<i<<' '<<bfn[i]<<' '<<val[bfn[i]]<<' '<<in[bfn[i]]<<endl;
		}
	}
	int solve(int x,int k,int n){
		int id=rt[Min(dep[bfn[n]],dep[x]+k)];
		return Tree.query(id,in[x],in[x]+sz[x]-1,1,n);
	}
}
int main(){
	#ifndef ONLINE_JUDGE
    	int startTime = clock();
		FRD;
	#endif
	int n=read(),rt=read();
	for(int i=1;i<=n;i++)	G::val[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G::vec[u].pb(v);
		G::vec[v].pb(u);
	}
	G::dfs(rt,rt,1);
	G::bfs(rt);
	G::init(n,rt);
	int q=read();
	int lastans=0;
	while(q--){
		int x=(read()+lastans)%n+1,k=(read()+lastans)%n;
		//cout<<x<<' '<<k<<endl;
		lastans=G::solve(x,k,n);
		printf("%d\n",lastans);
	}
	#ifndef ONLINE_JUDGE
    	printf("Time = %dms\n", clock() - startTime);
	#endif
	return 0;
}


#include<bits/stdc++.h>
#define LL long long int
#define FIO ios::sync_with_stdio(false)
#define FRD freopen("input.txt","r",stdin)
#define lowbit(x) (x&-(x))
#define INF 2e9
#define ms(x) memset(x,0,sizeof x)
#define pb(x) push_back(x)
#define lson l,mid,now<<1
#define rson mid+1,r,now<<1|1
#define UNIQUE(x) unique(x.begin(),x.end())
#define SORT(x) sort(x.begin(),x.end())
#define LISAN(x) x.erase(UNIQUE(x),x.end())
#define pii pair<int,int>
#define pll pair<LL,LL>
#define N 200010
const LL MOD=1e9+7;
using namespace std;
template<class T> inline T Min(const T& a,const T& b){return a<b?a:b;}
template<class T> inline T Max(const T& a,const T& b){return a<b?b:a;}
inline void inc(int &x,int &v,int &mod){x+=v;if(x>=mod) x-=mod;}
inline void dec(int &x,int &v,int &mod){x-=v;if(x<0) x+=mod;}
inline int read(){char ch = getchar();int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
inline LL readl(){char ch = getchar();LL x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
struct ModSegementTree{
	int sum[N<<5], L[N<<5], R[N<<5],cnt=0;
	inline int build(int l, int r){
	    int rt = ++ cnt;
	    sum[rt] = 2e9;
	    int mid=(l+r)/2;
	    if (l < r){
	        L[rt] = build(l, mid);
	        R[rt] = build(mid+1,r);
	    }
	    return rt;
	}
	inline int update(int &pre, int l, int r,const int &pos,const int &x){
	    int rt = ++ cnt;
	    L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = Min(sum[pre],x);
	    int mid=(l+r)/2;
	    if (l < r){
	        if (pos <= mid) L[rt] = update(L[pre], l, mid,pos, x);
	        else R[rt] = update(R[pre], mid+1, r,pos, x);
	    }
	    return rt;
	}
	inline int query(int &u,int ll,int rr,int l,int r){
	    if(ll>r||rr<l)
	        return INF;
	    if(ll<=l&&r<=rr){
	        return sum[u];
	    }
	    int ans=INF;
	    int mid=(l+r)/2;
	    if(ll<=mid)
	        ans=Min(ans,query(L[u],ll,rr,l,mid));
	    if(mid<rr)
	        ans=Min(ans,query(R[u],ll,rr,mid+1,r));
	    return ans;
	}
}Tree;
namespace G{
	vector<int> vec[N];
	LL val[N];
	int bfn[N],sz[N],in[N],level[N],rt[N],dep[N],tot;
	bool vis[N];
	void bfs(int s){
		queue<int> Q;
		Q.push(s);
		int tim=0,now_dep=0;
		while(Q.size()){
			int now=Q.front();Q.pop();
			bfn[++tim]=now;
			vis[now]=true;
			for(auto to:vec[now]){
				if(!vis[to]){
					Q.push(to);
				}
			}
		}
	}
	void dfs(int x,int fa,int dis){
		in[x]=++tot;
		sz[x]=1;
		dep[x]=dis;
		for(auto to:vec[x]){
			if(to==fa)	continue;
			dfs(to,x,dis+1);
			sz[x]+=sz[to];
		}
	}
	void init(int n,int root){
		rt[0]=Tree.build(1,n);
		rt[1]=Tree.update(rt[0],1,n,root,val[root]);
		for(int i=2;i<=n;i++){
			if(dep[bfn[i]]!=dep[bfn[i-1]]){
				rt[dep[bfn[i]]]=rt[dep[bfn[i-1]]];
			}
			rt[dep[bfn[i]]]=Tree.update(rt[dep[bfn[i-1]]],1,n,in[bfn[i]],val[bfn[i]]);
			//cout<<i<<' '<<bfn[i]<<' '<<val[bfn[i]]<<' '<<in[bfn[i]]<<endl;
		}
	}
	int solve(int x,int k,int n){
		int id=rt[Min(dep[bfn[n]],dep[x]+k)];
		return Tree.query(id,in[x],in[x]+sz[x]-1,1,n);
	}
}
int main(){
	#ifndef ONLINE_JUDGE
    	int startTime = clock();
		FRD;
	#endif
	int n=read(),rt=read();
	for(int i=1;i<=n;i++)	G::val[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G::vec[u].pb(v);
		G::vec[v].pb(u);
	}
	G::dfs(rt,rt,1);
	G::bfs(rt);
	G::init(n,rt);
	int q=read();
	int lastans=0;
	while(q--){
		int x=(read()+lastans)%n+1,k=(read()+lastans)%n;
		//cout<<x<<' '<<k<<endl;
		lastans=G::solve(x,k,n);
		printf("%d\n",lastans);
	}
	#ifndef ONLINE_JUDGE
    	printf("Time = %dms\n", clock() - startTime);
	#endif
	return 0;
}


#include<bits/stdc++.h>
#define LL long long int
#define FIO ios::sync_with_stdio(false)
#define FRD freopen("input.txt","r",stdin)
#define lowbit(x) (x&-(x))
#define INF 2e9
#define ms(x) memset(x,0,sizeof x)
#define pb(x) push_back(x)
#define lson l,mid,now<<1
#define rson mid+1,r,now<<1|1
#define UNIQUE(x) unique(x.begin(),x.end())
#define SORT(x) sort(x.begin(),x.end())
#define LISAN(x) x.erase(UNIQUE(x),x.end())
#define pii pair<int,int>
#define pll pair<LL,LL>
#define N 200010
const LL MOD=1e9+7;
using namespace std;
template<class T> inline T Min(const T& a,const T& b){return a<b?a:b;}
template<class T> inline T Max(const T& a,const T& b){return a<b?b:a;}
inline void inc(int &x,int &v,int &mod){x+=v;if(x>=mod) x-=mod;}
inline void dec(int &x,int &v,int &mod){x-=v;if(x<0) x+=mod;}
inline int read(){char ch = getchar();int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
inline LL readl(){char ch = getchar();LL x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
struct ModSegementTree{
	int sum[N<<5], L[N<<5], R[N<<5],cnt=0;
	inline int build(int l, int r){
	    int rt = ++ cnt;
	    sum[rt] = 2e9;
	    int mid=(l+r)/2;
	    if (l < r){
	        L[rt] = build(l, mid);
	        R[rt] = build(mid+1,r);
	    }
	    return rt;
	}
	inline int update(int &pre, int l, int r,const int &pos,const int &x){
	    int rt = ++ cnt;
	    L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = Min(sum[pre],x);
	    int mid=(l+r)/2;
	    if (l < r){
	        if (pos <= mid) L[rt] = update(L[pre], l, mid,pos, x);
	        else R[rt] = update(R[pre], mid+1, r,pos, x);
	    }
	    return rt;
	}
	inline int query(int &u,int ll,int rr,int l,int r){
	    if(ll>r||rr<l)
	        return INF;
	    if(ll<=l&&r<=rr){
	        return sum[u];
	    }
	    int ans=INF;
	    int mid=(l+r)/2;
	    if(ll<=mid)
	        ans=Min(ans,query(L[u],ll,rr,l,mid));
	    if(mid<rr)
	        ans=Min(ans,query(R[u],ll,rr,mid+1,r));
	    return ans;
	}
}Tree;
namespace G{
	vector<int> vec[N];
	LL val[N];
	int bfn[N],sz[N],in[N],level[N],rt[N],dep[N],tot;
	bool vis[N];
	void bfs(int s){
		queue<int> Q;
		Q.push(s);
		int tim=0,now_dep=0;
		while(Q.size()){
			int now=Q.front();Q.pop();
			bfn[++tim]=now;
			vis[now]=true;
			for(auto to:vec[now]){
				if(!vis[to]){
					Q.push(to);
				}
			}
		}
	}
	void dfs(int x,int fa,int dis){
		in[x]=++tot;
		sz[x]=1;
		dep[x]=dis;
		for(auto to:vec[x]){
			if(to==fa)	continue;
			dfs(to,x,dis+1);
			sz[x]+=sz[to];
		}
	}
	void init(int n,int root){
		rt[0]=Tree.build(1,n);
		//rt[1]=Tree.update(rt[0],1,n,root,val[root]);
		for(int i=1;i<=n;i++){
			if(dep[bfn[i]]!=dep[bfn[i-1]]){
				rt[dep[bfn[i]]]=rt[dep[bfn[i-1]]];
			}
			rt[dep[bfn[i]]]=Tree.update(rt[dep[bfn[i-1]]],1,n,in[bfn[i]],val[bfn[i]]);
			//cout<<i<<' '<<bfn[i]<<' '<<val[bfn[i]]<<' '<<in[bfn[i]]<<endl;
		}
	}
	int solve(int x,int k,int n){
		int id=rt[Min(dep[bfn[n]],dep[x]+k)];
		return Tree.query(id,in[x],in[x]+sz[x]-1,1,n);
	}
}
int main(){
	#ifndef ONLINE_JUDGE
    	int startTime = clock();
		FRD;
	#endif
	int n=read(),rt=read();
	for(int i=1;i<=n;i++)	G::val[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G::vec[u].pb(v);
		G::vec[v].pb(u);
	}
	G::dfs(rt,rt,1);
	G::bfs(rt);
	G::init(n,rt);
	int q=read();
	int lastans=0;
	while(q--){
		int x=(read()+lastans)%n+1,k=(read()+lastans)%n;
		//cout<<x<<' '<<k<<endl;
		lastans=G::solve(x,k,n);
		printf("%d\n",lastans);
	}
	#ifndef ONLINE_JUDGE
    	printf("Time = %dms\n", clock() - startTime);
	#endif
	return 0;
}


#include<bits/stdc++.h>
#define LL long long int
#define FIO ios::sync_with_stdio(false)
#define FRD freopen("input.txt","r",stdin)
#define lowbit(x) (x&-(x))
#define INF 2e9
#define ms(x) memset(x,0,sizeof x)
#define pb(x) push_back(x)
#define lson l,mid,now<<1
#define rson mid+1,r,now<<1|1
#define UNIQUE(x) unique(x.begin(),x.end())
#define SORT(x) sort(x.begin(),x.end())
#define LISAN(x) x.erase(UNIQUE(x),x.end())
#define pii pair<int,int>
#define pll pair<LL,LL>
#define N 200010
const LL MOD=1e9+7;
using namespace std;
template<class T> inline T Min(const T& a,const T& b){return a<b?a:b;}
template<class T> inline T Max(const T& a,const T& b){return a<b?b:a;}
inline void inc(int &x,int &v,int &mod){x+=v;if(x>=mod) x-=mod;}
inline void dec(int &x,int &v,int &mod){x-=v;if(x<0) x+=mod;}
inline int read(){char ch = getchar();int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
inline LL readl(){char ch = getchar();LL x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
struct ModSegementTree{
	int sum[N<<5];
	int L[N<<5], R[N<<5],cnt=0;
	inline int build(int l, int r){
	    int rt = ++ cnt;
	    sum[rt] =INF ;
	    int mid=(l+r)/2;
	    if (l < r){
	        L[rt] = build(l, mid);
	        R[rt] = build(mid+1,r);
	    }
	    return rt;
	}
	inline int update(int &pre, int l, int r,const int &pos,const int &x){
	    int rt = ++ cnt;
	    L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = Min(sum[pre],x);
	    int mid=(l+r)/2;
	    if (l < r){
	        if (pos <= mid) L[rt] = update(L[pre], l, mid,pos, x);
	        else R[rt] = update(R[pre], mid+1, r,pos, x);
	    }
	    return rt;
	}
	inline int query(int &u,int ll,int rr,int l,int r){
	    if(ll>r||rr<l)
	        return INF;
	    if(ll<=l&&r<=rr){
	        return sum[u];
	    }
	    int ans=INF;
	    int mid=(l+r)/2;
	    if(ll<=mid)
	        ans=Min(ans,query(L[u],ll,rr,l,mid));
	    if(mid<rr)
	        ans=Min(ans,query(R[u],ll,rr,mid+1,r));
	    return ans;
	}
}Tree;
namespace G{
	vector<int> vec[N];
	LL val[N];
	int bfn[N],sz[N],in[N],level[N],rt[N],dep[N],tot;
	bool vis[N];
	void bfs(int s){
		queue<int> Q;
		Q.push(s);
		int tim=0,now_dep=0;
		while(Q.size()){
			int now=Q.front();Q.pop();
			bfn[++tim]=now;
			vis[now]=true;
			for(auto to:vec[now]){
				if(!vis[to]){
					Q.push(to);
				}
			}
		}
	}
	void dfs(int x,int fa,int dis){
		in[x]=++tot;
		sz[x]=1;
		dep[x]=dis;
		for(auto to:vec[x]){
			if(to==fa)	continue;
			dfs(to,x,dis+1);
			sz[x]+=sz[to];
		}
	}
	void init(int n,int root){
		rt[0]=Tree.build(1,n);
		for(int i=1;i<=n;i++){
			if(dep[bfn[i]]!=dep[bfn[i-1]]){
				rt[dep[bfn[i]]]=rt[dep[bfn[i-1]]];
			}
			rt[dep[bfn[i]]]=Tree.update(rt[dep[bfn[i-1]]],1,n,in[bfn[i]],val[bfn[i]]);
		}
	}
	int solve(int x,int k,int n){
		int id=rt[Min(dep[bfn[n]],dep[x]+k)];
		return Tree.query(id,in[x],in[x]+sz[x]-1,1,n);
	}
}
int main(){
	#ifndef ONLINE_JUDGE
    	int startTime = clock();
		FRD;
	#endif
	int n=read(),rt=read();
	for(int i=1;i<=n;i++)	G::val[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G::vec[u].pb(v);
		G::vec[v].pb(u);
	}
	G::dfs(rt,rt,1);
	G::bfs(rt);
	G::init(n,rt);
	int q=read();
	int lastans=0;
	while(q--){
		int x=(read()+lastans)%n+1,k=(read()+lastans)%n;
		lastans=G::solve(x,k,n);
		printf("%d\n",lastans);
	}
	#ifndef ONLINE_JUDGE
    	printf("Time = %dms\n", clock() - startTime);
	#endif
	return 0;
}


#include<bits/stdc++.h>
#define LL long long int
#define FIO ios::sync_with_stdio(false)
#define FRD freopen("input.txt","r",stdin)
#define lowbit(x) (x&-(x))
#define INF 2e9
#define ms(x) memset(x,0,sizeof x)
#define pb(x) push_back(x)
#define lson l,mid,now<<1
#define rson mid+1,r,now<<1|1
#define UNIQUE(x) unique(x.begin(),x.end())
#define SORT(x) sort(x.begin(),x.end())
#define LISAN(x) x.erase(UNIQUE(x),x.end())
#define pii pair<int,int>
#define pll pair<LL,LL>
#define N 200010
const LL MOD=1e9+7;
using namespace std;
template<class T> inline T Min(const T& a,const T& b){return a<b?a:b;}
template<class T> inline T Max(const T& a,const T& b){return a<b?b:a;}
inline void inc(int &x,int &v,int &mod){x+=v;if(x>=mod) x-=mod;}
inline void dec(int &x,int &v,int &mod){x-=v;if(x<0) x+=mod;}
inline int read(){char ch = getchar();int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
inline LL readl(){char ch = getchar();LL x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
struct ModSegementTree{
	int sum[N<<5], L[N<<5], R[N<<5],cnt=0;
	inline int build(int l, int r){
	    int rt = ++ cnt;
	    sum[rt] = 2e9;
	    int mid=(l+r)/2;
	    if (l < r){
	        L[rt] = build(l, mid);
	        R[rt] = build(mid+1,r);
	    }
	    return rt;
	}
	inline int update(int &pre, int l, int r,const int &pos,const int &x){
	    int rt = ++ cnt;
	    L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = Min(sum[pre],x);
	    int mid=(l+r)/2;
	    if (l < r){
	        if (pos <= mid) L[rt] = update(L[pre], l, mid,pos, x);
	        else R[rt] = update(R[pre], mid+1, r,pos, x);
	    }
	    return rt;
	}
	inline int query(int &u,int ll,int rr,int l,int r){
	    if(ll>r||rr<l)
	        return INF;
	    if(ll<=l&&r<=rr){
	        return sum[u];
	    }
	    int ans=INF;
	    int mid=(l+r)/2;
	    if(ll<=mid)
	        ans=Min(ans,query(L[u],ll,rr,l,mid));
	    if(mid<rr)
	        ans=Min(ans,query(R[u],ll,rr,mid+1,r));
	    return ans;
	}
}Tree;
namespace G{
	vector<int> vec[N];
	int val[N],bfn[N],sz[N],in[N],level[N],rt[N],dep[N],tot;
	bool vis[N];
	void bfs(int s){
		queue<int> Q;
		Q.push(s);
		int tim=0,now_dep=0;
		while(Q.size()){
			int now=Q.front();Q.pop();
			bfn[++tim]=now;
			vis[now]=true;
			for(auto to:vec[now]){
				if(!vis[to]){
					Q.push(to);
				}
			}
		}
	}
	void dfs(int x,int fa,int dis){
		in[x]=++tot;
		sz[x]=1;
		dep[x]=dis;
		for(auto to:vec[x]){
			if(to==fa)	continue;
			dfs(to,x,dis+1);
			sz[x]+=sz[to];
		}
	}
	void init(int n,int root){
		rt[0]=Tree.build(1,n);
		rt[1]=Tree.update(rt[0],1,n,root,val[root]);
		for(int i=2;i<=n;i++){
			if(dep[bfn[i]]!=dep[bfn[i-1]]){
				rt[dep[bfn[i]]]=rt[dep[bfn[i-1]]];
			}
			rt[dep[bfn[i]]]=Tree.update(rt[dep[bfn[i-1]]],1,n,in[bfn[i]],val[bfn[i]]);
			//cout<<i<<' '<<bfn[i]<<' '<<val[bfn[i]]<<' '<<in[bfn[i]]<<endl;
		}
	}
	int solve(int x,int k,int n){
		int id=rt[Min(dep[bfn[n]],dep[x]+k)];
		return Tree.query(id,in[x],in[x]+sz[x]-1,1,n);
	}
}
int main(){
	#ifndef ONLINE_JUDGE
    	int startTime = clock();
		FRD;
	#endif
	int n=read(),rt=read();
	for(int i=1;i<=n;i++)	G::val[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G::vec[u].pb(v);
		G::vec[v].pb(u);
	}
	G::dfs(rt,rt,1);
	G::bfs(rt);
	G::init(n,rt);
	int q=read();
	int lastans=0;
	while(q--){
		int x=(read()+lastans)%n+1,k=(read()+lastans)%n;
		//cout<<x<<' '<<k<<endl;
		lastans=G::solve(x,k,n);
		printf("%d\n",lastans);
	}
	#ifndef ONLINE_JUDGE
    	printf("Time = %dms\n", clock() - startTime);
	#endif
	return 0;
}


#include<bits/stdc++.h>
#define LL long long int
#define FIO ios::sync_with_stdio(false)
#define FRD freopen("input.txt","r",stdin)
#define lowbit(x) (x&-(x))
#define INF 2e9
#define ms(x) memset(x,0,sizeof x)
#define pb(x) push_back(x)
#define lson l,mid,now<<1
#define rson mid+1,r,now<<1|1
#define UNIQUE(x) unique(x.begin(),x.end())
#define SORT(x) sort(x.begin(),x.end())
#define LISAN(x) x.erase(UNIQUE(x),x.end())
#define pii pair<int,int>
#define pll pair<LL,LL>
#define N 100010
const LL MOD=1e9+7;
using namespace std;
template<class T> inline T Min(const T& a,const T& b){return a<b?a:b;}
template<class T> inline T Max(const T& a,const T& b){return a<b?b:a;}
inline void inc(int &x,int &v,int &mod){x+=v;if(x>=mod) x-=mod;}
inline void dec(int &x,int &v,int &mod){x-=v;if(x<0) x+=mod;}
inline int read(){char ch = getchar();int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
inline LL readl(){char ch = getchar();LL x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
struct ModSegementTree{
	int sum[N<<5], L[N<<5], R[N<<5],cnt=0;
	inline int build(int l, int r){
	    int rt = ++ cnt;
	    sum[rt] = 2e9;
	    int mid=(l+r)/2;
	    if (l < r){
	        L[rt] = build(l, mid);
	        R[rt] = build(mid+1,r);
	    }
	    return rt;
	}
	inline int update(int &pre, int l, int r,const int &pos,const int &x){
	    int rt = ++ cnt;
	    L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = Min(sum[pre],x);
	    int mid=(l+r)/2;
	    if (l < r){
	        if (pos <= mid) L[rt] = update(L[pre], l, mid,pos, x);
	        else R[rt] = update(R[pre], mid+1, r,pos, x);
	    }
	    return rt;
	}
	inline int query(int &u,int ll,int rr,int l,int r){
	    if(ll>r||rr<l)
	        return INF;
	    if(ll<=l&&r<=rr){
	        return sum[u];
	    }
	    int ans=INF;
	    int mid=(l+r)/2;
	    if(ll<=mid)
	        ans=Min(ans,query(L[u],ll,rr,l,mid));
	    if(mid<rr)
	        ans=Min(ans,query(R[u],ll,rr,mid+1,r));
	    return ans;
	}
}Tree;
namespace G{
	vector<int> vec[N];
	int val[N],bfn[N],sz[N],in[N],level[N],rt[N],dep[N],tot;
	bool vis[N];
	void bfs(int s){
		queue<int> Q;
		Q.push(s);
		int tim=0,now_dep=0;
		while(Q.size()){
			int now=Q.front();Q.pop();
			bfn[++tim]=now;
			vis[now]=true;
			for(auto to:vec[now]){
				if(!vis[to]){
					Q.push(to);
				}
			}
		}
	}
	void dfs(int x,int fa,int dis){
		in[x]=++tot;
		sz[x]=1;
		dep[x]=dis;
		for(auto to:vec[x]){
			if(to==fa)	continue;
			dfs(to,x,dis+1);
			sz[x]+=sz[to];
		}
	}
	void init(int n,int root){
		rt[0]=Tree.build(1,n);
		rt[1]=Tree.update(rt[0],1,n,root,val[root]);
		for(int i=2;i<=n;i++){
			if(dep[bfn[i]]!=dep[bfn[i-1]]){
				rt[dep[bfn[i]]]=rt[dep[bfn[i-1]]];
			}
			rt[dep[bfn[i]]]=Tree.update(rt[dep[bfn[i-1]]],1,n,in[bfn[i]],val[bfn[i]]);
			//cout<<i<<' '<<bfn[i]<<' '<<val[bfn[i]]<<' '<<in[bfn[i]]<<endl;
		}
	}
	int solve(int x,int k,int n){
		int id=rt[Min(dep[bfn[n]],dep[x]+k)];
		return Tree.query(id,in[x],in[x]+sz[x]-1,1,n);
	}
}
int main(){
	#ifndef ONLINE_JUDGE
    	int startTime = clock();
		FRD;
	#endif
	int n=read(),rt=read();
	for(int i=1;i<=n;i++)	G::val[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G::vec[u].pb(v);
		G::vec[v].pb(u);
	}
	G::dfs(rt,rt,1);
	G::bfs(rt);
	G::init(n,rt);
	int q=read();
	int lastans=0;
	while(q--){
		int x=(read()+lastans)%n+1,k=(read()+lastans)%n;
		//cout<<x<<' '<<k<<endl;
		lastans=G::solve(x,k,n);
		printf("%d\n",lastans);
	}
	#ifndef ONLINE_JUDGE
    	printf("Time = %dms\n", clock() - startTime);
	#endif
	return 0;
}


#include<bits/stdc++.h>
#define LL long long int
#define FIO ios::sync_with_stdio(false)
#define FRD freopen("input.txt","r",stdin)
#define lowbit(x) (x&-(x))
#define INF 2e9
#define ms(x) memset(x,0,sizeof x)
#define pb(x) push_back(x)
#define lson l,mid,now<<1
#define rson mid+1,r,now<<1|1
#define UNIQUE(x) unique(x.begin(),x.end())
#define SORT(x) sort(x.begin(),x.end())
#define LISAN(x) x.erase(UNIQUE(x),x.end())
#define pii pair<int,int>
#define pll pair<LL,LL>
#define N 200010
const LL MOD=1e9+7;
using namespace std;
template<class T> inline T Min(const T& a,const T& b){return a<b?a:b;}
template<class T> inline T Max(const T& a,const T& b){return a<b?b:a;}
inline void inc(int &x,int &v,int &mod){x+=v;if(x>=mod) x-=mod;}
inline void dec(int &x,int &v,int &mod){x-=v;if(x<0) x+=mod;}
inline int read(){char ch = getchar();int x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
inline LL readl(){char ch = getchar();LL x = 0, f = 1;while(ch < '0' || ch > '9') {if(ch == '-') f = -1;ch = getchar();}while('0' <= ch && ch <= '9') {x = x * 10 + ch - '0';ch = getchar();}return x * f;}
struct ModSegementTree{
	int sum[N<<5];
	int L[N<<5], R[N<<5],cnt=0;
	inline int build(int l, int r){
	    int rt = ++ cnt;
	    sum[rt] =INF ;
	    int mid=(l+r)/2;
	    if (l < r){
	        L[rt] = build(l, mid);
	        R[rt] = build(mid+1,r);
	    }
	    return rt;
	}
	inline int update(int &pre, int l, int r,const int &pos,const int &x){
	    int rt = ++ cnt;
	    L[rt] = L[pre]; R[rt] = R[pre]; sum[rt] = Min(sum[pre],x);
	    int mid=(l+r)/2;
	    if (l < r){
	        if (pos <= mid) L[rt] = update(L[pre], l, mid,pos, x);
	        else R[rt] = update(R[pre], mid+1, r,pos, x);
	    }
	    return rt;
	}
	inline int query(int &u,int ll,int rr,int l,int r){
	    if(ll>r||rr<l)
	        return INF;
	    if(ll<=l&&r<=rr){
	        return sum[u];
	    }
	    int ans=INF;
	    int mid=(l+r)/2;
	    if(ll<=mid)
	        ans=Min(ans,query(L[u],ll,rr,l,mid));
	    if(mid<rr)
	        ans=Min(ans,query(R[u],ll,rr,mid+1,r));
	    return ans;
	}
}Tree;
namespace G{
	vector<int> vec[N];
	LL val[N];
	int bfn[N],sz[N],in[N],level[N],rt[N],dep[N],tot;
	bool vis[N];
	void bfs(int s){
		queue<int> Q;
		Q.push(s);
		int tim=0,now_dep=0;
		while(Q.size()){
			int now=Q.front();Q.pop();
			bfn[++tim]=now;
			vis[now]=true;
			for(auto to:vec[now]){
				if(!vis[to]){
					Q.push(to);
				}
			}
		}
	}
	void dfs(int x,int fa,int dis){
		in[x]=++tot;
		sz[x]=1;
		dep[x]=dis;
		for(auto to:vec[x]){
			if(to==fa)	continue;
			dfs(to,x,dis+1);
			sz[x]+=sz[to];
		}
	}
	void init(int n,int root){
		rt[0]=Tree.build(1,n);
		for(int i=1;i<=n;i++){
			if(dep[bfn[i]]!=dep[bfn[i-1]]){
				rt[dep[bfn[i]]]=rt[dep[bfn[i-1]]];
			}
			rt[dep[bfn[i]]]=Tree.update(rt[dep[bfn[i-1]]],1,n,in[bfn[i]],val[bfn[i]]);
		}
	}
	LL solve(int x,int k,int n){
		int id=rt[Min(dep[bfn[n]],dep[x]+k)];
		return Tree.query(id,in[x],in[x]+sz[x]-1,1,n);
	}
}
int main(){
	#ifndef ONLINE_JUDGE
    	int startTime = clock();
		FRD;
	#endif
	int n=read(),rt=read();
	for(int i=1;i<=n;i++)	G::val[i]=read();
	for(int i=1;i<n;i++){
		int u=read(),v=read();
		G::vec[u].pb(v);
		G::vec[v].pb(u);
	}
	G::dfs(rt,rt,1);
	G::bfs(rt);
	G::init(n,rt);
	int q=read();
	LL lastans=0;
	while(q--){
		int x=(read()+lastans)%n+1,k=(read()+lastans)%n;
		lastans=G::solve(x,k,n);
		printf("%lld\n",lastans);
	}
	#ifndef ONLINE_JUDGE
    	printf("Time = %dms\n", clock() - startTime);
	#endif
	return 0;
}


#include "bits/stdc++.h"
using namespace std;

const int N = 1e5 + 5;
const int blk = 320;
int root, n, m, u, v, x, k, last, ans;
int a[N];
vector<int>adj[N];
int in[N], out[N], lvl[N], timer;
int ord[N], ptr, pos[N];
int sv[blk][N];
void dfs(int u, int p){
  in[u] = timer++;
  for(auto v : adj[u])if(v != p){

    lvl[v] = lvl[u] + 1;
    dfs(v, u);

  }
  pos[u] = ptr;
  ord[ptr++] = u;
  out[u] = timer++;
}
bool isChild(int p, int u){
  return in[u] >= in[p] && out[u] <= out[p];
}
int get_last(int x){

  int lo = 0, hi = pos[x];

  while(lo < hi){

    int md = lo + (hi - lo) / 2;

    if(isChild(x,ord[md]))
      hi = md;
    else
      lo = md + 1;

  }

  return lo;
}
void pre(){

  for(int i = 0; i * blk < n; i++){

    for(int j = 0; j  < n; j++)
      sv[i][j] = INT_MAX;

    int l = i * blk;
    int r = l + blk;

    for(int j = l; j < r; j++)
      sv[i][lvl[ord[j]]] = min(sv[i][lvl[ord[j]]], a[ord[j]]);

    for(int j = 1; j < n; j++)
      sv[i][j] = min(sv[i][j], sv[i][j-1]);

  }

}
int qry(int l, int r, int target){
  target = min(target, n-1);
  r++;
  int ans = INT_MAX;
  for( ; l < r && l%blk != 0; l++){
    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);
  }

  for(; l / blk != r / blk; l += blk){

    ans = min(ans, sv[l/blk][target]);

  }

  for(; l < r; l++){

    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);

  }

  return ans;
}

int main(){

  scanf("%d%d", &n, &root);

  for(int i = 1; i <= n; i++){

    scanf("%d", a+i);
  }

  for(int i = 1; i < n; i++){

    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);

  }
  dfs(root, root);
  pre();
  scanf("%d",&m);

  while(m--){

    scanf("%d%d", &x, &k);
    x = (x + last) % n + 1;
    k = (k + last) % n;
    last = qry(get_last(x),pos[x],k + lvl[x]);
    printf("%d\n", last);
  }

}


#include "bits/stdc++.h"
using namespace std;

const int N = 4e5 + 5;
const int blk = 320;
int root, n, m, u, v, x, k, last, ans;
int a[N];
vector<int>adj[N];
int in[N], out[N], lvl[N], timer;
int ord[N], ptr, pos[N];
int sv[blk][N];
void dfs(int u, int p){
  in[u] = timer++;
  for(auto v : adj[u])if(v != p){

    lvl[v] = lvl[u] + 1;
    dfs(v, u);

  }
  pos[u] = ptr;
  ord[ptr++] = u;
  out[u] = timer++;
}
bool isChild(int p, int u){
  return in[u] >= in[p] && out[u] <= out[p];
}
int get_last(int x){

  int lo = 0, hi = pos[x];

  while(lo < hi){

    int md = lo + (hi - lo) / 2;

    if(isChild(x,ord[md]))
      hi = md;
    else
      lo = md + 1;

  }

  return lo;
}
void pre(){

  for(int i = 0; i * blk < n; i++){

    for(int j = 0; j  < n; j++)
      sv[i][j] = INT_MAX;

    int l = i * blk;
    int r = l + blk;

    for(int j = l; j < r; j++)
      sv[i][lvl[ord[j]]] = min(sv[i][lvl[ord[j]]], a[ord[j]]);

    for(int j = 1; j < n; j++)
      sv[i][j] = min(sv[i][j], sv[i][j-1]);

  }

}
int qry(int l, int r, int target){
  target = min(target, n-1);
  r++;
  int ans = INT_MAX;
  for( ; l < r && l%blk != 0; l++){
    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);
  }

  for(; l / blk != r / blk; l += blk){

    ans = min(ans, sv[l/blk][target]);

  }

  for(; l < r; l++){

    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);

  }

  return ans;
}

int main(){

  scanf("%d%d", &n, &root);

  for(int i = 1; i <= n; i++){

    scanf("%d", a+i);
  }

  for(int i = 1; i < n; i++){

    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);

  }
  dfs(root, root);
  pre();
  scanf("%d",&m);

  while(m--){

    scanf("%d%d", &x, &k);
    x = (x + last) % n + 1;
    k = (k + last) % n;
    if(x > n || x < 0){
      puts("NO");
      return 0;
    }
    last = qry(get_last(x),pos[x],k + lvl[x]);
    printf("%d\n", last);
  }

}


#include "bits/stdc++.h"
using namespace std;

const int N = 1e5 + 5;
const int blk = 320;
int root, n, m, u, v, x, k, last, ans;
int a[N];
vector<int>adj[N];
int in[N], out[N], lvl[N], timer;
int ord[N], ptr, pos[N];
int sv[blk][N];
void dfs(int u, int p){
  in[u] = timer++;
  for(auto v : adj[u])if(v != p){

    lvl[v] = lvl[u] + 1;
    dfs(v, u);

  }
  pos[u] = ptr;
  ord[ptr++] = u;
  out[u] = timer++;
}
bool isChild(int p, int u){
  return in[u] >= in[p] && out[u] <= out[p];
}
int get_last(int x){

  int lo = 0, hi = pos[x];

  while(lo < hi){

    int md = lo + (hi - lo) / 2;

    if(isChild(x,ord[md]))
      hi = md;
    else
      lo = md + 1;

  }

  return lo;
}
void pre(){

  for(int i = 0; i * blk < n; i++){

    for(int j = 0; j  < n; j++)
      sv[i][j] = INT_MAX;

    int l = i * blk;
    int r = l + blk;

    for(int j = l; j < r; j++)
      sv[i][lvl[ord[j]]] = min(sv[i][lvl[ord[j]]], a[ord[j]]);

    for(int j = 1; j < n; j++)
      sv[i][j] = min(sv[i][j], sv[i][j-1]);

  }

}
int qry(int l, int r, int target){
  r++;
  int ans = INT_MAX;
  for( ; l < r && l%blk != 0; l++){
    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);
  }

  for(; l / blk != r / blk; l += blk){

    ans = min(ans, sv[l/blk][target]);

  }

  for(; l < r; l++){

    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);

  }

  return ans;
}

int main(){

  scanf("%d%d", &n, &root);

  for(int i = 1; i <= n; i++){

    scanf("%d", a+i);
  }

  for(int i = 1; i < n; i++){

    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);

  }
  dfs(root, root);
  pre();
  scanf("%d",&m);

  while(m--){

    scanf("%d%d", &x, &k);
    x = (x + last) % n + 1;
    k = (k + last) % n;
    last = qry(get_last(x),pos[x],k + lvl[x]);
    printf("%d\n", last);
  }

}


#include "bits/stdc++.h"
using namespace std;

const int N = 1e5 + 5;
const int blk = 320;
int root, n, m, u, v, x, k, last, ans;
int a[N];
vector<int>adj[N];
int in[N], out[N], lvl[N], timer;
int ord[N], ptr, pos[N];
int sv[blk][N];
void dfs(int u, int p){
  in[u] = timer++;
  for(auto v : adj[u])if(v != p){

    lvl[v] = lvl[u] + 1;
    dfs(v, u);

  }
  pos[u] = ptr;
  ord[ptr++] = u;
  out[u] = timer++;
}
bool isChild(int p, int u){
  return in[u] >= in[p] && out[u] <= out[p];
}
int get_last(int x){

  int lo = 0, hi = pos[x];

  while(lo < hi){

    int md = lo + (hi - lo) / 2;

    if(isChild(x,ord[md]))
      hi = md;
    else
      lo = md + 1;

  }

  return lo;
}
void pre(){

  for(int i = 0; i * blk < n; i++){

    for(int j = 0; j  < n; j++)
      sv[i][j] = INT_MAX;

    int l = i * blk;
    int r = l + blk;

    for(int j = l; j < r; j++)
      sv[i][lvl[ord[j]]] = min(sv[i][lvl[ord[j]]], a[ord[j]]);

    for(int j = 1; j < n; j++)
      sv[i][j] = min(sv[i][j], sv[i][j-1]);

  }

}
int qry(int l, int r, int target){
  target = min(target, n-1);
  r++;
  int ans = INT_MAX;
  for( ; l < r && l%blk != 0; l++){
    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);
  }

  for(; l / blk != r / blk; l += blk){

    ans = min(ans, sv[l/blk][target]);

  }

  for(; l < r; l++){

    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);

  }

  return ans;
}

int main(){

  scanf("%d%d", &n, &root);

  for(int i = 1; i <= n; i++){

    scanf("%d", a+i);
  }

  for(int i = 1; i < n; i++){

    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);

  }
  dfs(root, root);
  pre();
  scanf("%d",&m);

  while(m--){

    scanf("%d%d", &x, &k);
    x = (x + last) % n + 1;
    k = (k + last) % n;
    if(x > n || x < 0){
      puts("NO");
      return 0;
    }
    last = qry(get_last(x),pos[x],k + lvl[x]);
    printf("%d\n", last);
  }

}


#include "bits/stdc++.h"
using namespace std;

const int N = 1e5 + 5;
const int blk = 320;
int root, n, m, u, v, x, k, last, ans;
int a[N];
vector<int>adj[N];
int in[N], out[N], lvl[N], timer;
int ord[N], ptr, pos[N];
int sv[N][blk];
void dfs(int u, int p){
  in[u] = timer++;
  for(auto v : adj[u])if(v != p){

    lvl[v] = lvl[u] + 1;
    dfs(v, u);

  }
  pos[u] = ptr;
  ord[ptr++] = u;
  out[u] = timer++;
}
bool isChild(int p, int u){
  return in[u] >= in[p] && out[u] <= out[p];
}
int get_last(int x){

  int lo = 0, hi = pos[x];

  while(lo < hi){

    int md = lo + (hi - lo) / 2;

    if(isChild(x,ord[md]))
      hi = md;
    else
      lo = md + 1;

  }

  return lo;
}
void pre(){

  for(int i = 0; i * blk < n; i++){

    for(int j = 0; j  < n; j++)
      sv[i][j] = INT_MAX;

    int l = i * blk;
    int r = l + blk;

    for(int j = l; j < r; j++)
      sv[i][lvl[ord[j]]] = min(sv[i][lvl[ord[j]]], a[ord[j]]);

    for(int j = 1; j < n; j++)
      sv[i][j] = min(sv[i][j], sv[i][j-1]);

  }

}
int qry(int l, int r, int target){
  r++;
  int ans = INT_MAX;
  for( ; l < r && l%blk != 0; l++){
    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);
  }

  for(; l / blk != r / blk; l += blk){

    ans = min(ans, sv[l/blk][target]);

  }

  for(; l < r; l++){

    if(lvl[ord[l]] <= target)
      ans = min(ans,a[ord[l]]);

  }

  return ans;
}

int main(){

  scanf("%d%d", &n, &root);

  for(int i = 1; i <= n; i++){

    scanf("%d", a+i);
  }

  for(int i = 1; i < n; i++){

    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);

  }
  dfs(root, root);
  pre();
  scanf("%d",&m);

  while(m--){

    scanf("%d%d", &x, &k);
    x = (x + last) % n + 1;
    k = (k + last) % n;
    last = qry(get_last(x),pos[x],k + lvl[x]);
    printf("%d\n", last);
  }

}


#include<iostream>
#include<vector>
using namespace std;
#define INT long long
INT number[100001];
vector< INT > g[100001];
INT timer;
INT Pos[100001];
INT Hsh[100001];
INT Sz[100001];
INT Ds[100001];
void dfs(INT node, INT pa, INT dist){
    Pos[node] = ++timer;
    Hsh[timer] = node;
    Sz[node] = 1;
    Ds[node] = dist;
    for(INT i = 0 ; i < (INT)g[node].size() ; ++i){
        INT to = g[node][i];
        if(to == pa) continue;
        dfs(to, node, dist + 1);
        Sz[node] += Sz[to];
    }
}
vector< pair< INT , INT > > seg[400000];
INT query(INT node, INT l, INT r, INT s, INT e, INT dist){
    if(s > r || l > e) return 2e9;
    if(l >= s && r <= e){
        INT b = 0;
        INT e = (INT)seg[node].size() - 1;
        INT idx = -1;
        while(b <= e){
            INT mi = (b + e)/2;
            if(seg[node][mi].first <= dist){
                idx = mi;
                b = mi + 1;
            } else
                e = mi - 1;
        }
        return seg[node][idx].second;
    }
    INT p = query(2 * node, l, (l + r)/2 , s , e, dist);
    INT q = query(2 * node + 1, (l + r)/2 + 1, r, s, e, dist);
    return min(p, q);
}
void Merge(INT node){
    INT l = 2 * node;
    INT r = l + 1;
    INT n = (INT)seg[l].size();
    INT m = (INT)seg[r].size();
    INT i = 0;
    INT j = 0;
    while(i < n && j < m){
        if(seg[l][i].first <= seg[r][j].first){
            seg[node].push_back(seg[l][i]);
            ++i;
        }else{
                seg[node].push_back(seg[r][j]);
            ++j;
        }
    }
    while(i < n) {
        seg[node].push_back(seg[l][i]) ;
        ++i;
    }
    while(j < m){
        seg[node].push_back(seg[r][j]);
        ++j;
    }
}
void build(INT node, INT l, INT r){
    if(l == r){
        seg[node].push_back({Ds[Hsh[l]], number[Hsh[l]]});
        return;
    }
    build(2 * node, l, (l + r)/2);
    build(2 * node + 1, (l + r)/2 + 1, r);
    Merge(node);
}
int main(){
    INT n, r;
    scanf("%lld %lld", &n, &r);
    for(INT i = 1; i <= n; ++i) scanf("%lld", number + i);
    INT e = n - 1;
    while(e--){
        INT u, v;
        scanf("%lld %lld", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(r, -1, 0);
    build(1, 1, n);
    for(INT i = 0 ; i < 4 * n  ;++i){
        INT s = (INT)seg[i].size();
        for(INT j = 1 ; j < s ; ++j) seg[i][j].second = min(seg[i][j].second, seg[i][j - 1].second);
    }
    INT q;
    long long last = 0;
    scanf("%lld", &q);
    while(q--){
        INT pi, qi;
        scanf("%lld %lld", &pi, &qi);
        INT xi = (pi + last) % n + 1;
        INT ki = (qi + last) % n;
        last = query(1, 1, n, Pos[xi], Pos[xi] + Sz[xi] - 1, ki + Ds[xi]);
        cout<<last<<endl;
    }

}


#include<iostream>
#include<vector>
using namespace std;
int number[200001];
vector< int > g[200001];
int timer;
int Pos[200001];
int Hsh[200001];
int Sz[200001];
int Ds[200001];
void dfs(int node, int pa, int dist){
    Pos[node] = ++timer;
    Hsh[timer] = node;
    Sz[node] = 1;
    Ds[node] = dist;
    for(int i = 0 ; i < (int)g[node].size() ; ++i){
        int to = g[node][i];
        if(to == pa) continue;
        dfs(to, node, dist + 1);
        Sz[node] += Sz[to];
    }
}
vector< pair< int , int > > seg[400010];
int query(int node, int l, int r, int s, int e, int dist){
    if(s > r || l > e) return 2e9;
    if(l >= s && r <= e){
        int B = 0;
        int E = (int)seg[node].size() - 1;
        int idx = -1;
        while(B <= E){
            int mi = (B + E)/2;
            if(seg[node][mi].first <= dist){
                idx = mi;
                B = mi + 1;
            } else
                E = mi - 1;
        }
        return seg[node][idx].second;
    }
    int p = query(2 * node, l, (l + r)/2 , s , e, dist);
    int q = query(2 * node + 1, (l + r)/2 + 1, r, s, e, dist);
    return min(p, q);
}
void Merge(int node){
    int l = 2 * node;
    int r = l + 1;
    int n = (int)seg[l].size();
    int m = (int)seg[r].size();
    int i = 0;
    int j = 0;
    while(i < n && j < m){
        if(seg[l][i].first <= seg[r][j].first){
            seg[node].push_back(seg[l][i]);
            ++i;
        }else{
                seg[node].push_back(seg[r][j]);
            ++j;
        }
    }
    while(i < n) {
        seg[node].push_back(seg[l][i]) ;
        ++i;
    }
    while(j < m){
        seg[node].push_back(seg[r][j]);
        ++j;
    }
}
void build(int node, int l, int r){
    if(l == r){
        seg[node].push_back({Ds[Hsh[l]], number[Hsh[l]]});
        return;
    }
    build(2 * node, l, (l + r)/2);
    build(2 * node + 1, (l + r)/2 + 1, r);
    Merge(node);
}
int main(){
    int n, r;
    scanf("%d %d", &n, &r);
    for(int i = 1; i <= n; ++i) scanf("%d", number + i);
    int e = n - 1;
    while(e--){
        int u, v;
        scanf("%d %d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(r, -1, 0);
    build(1, 1, n);
    for(int i = 0 ; i <= 4 * n  ;++i){
        int s = (int)seg[i].size();
        for(int j = 1 ; j < s ; ++j) seg[i][j].second = min(seg[i][j].second, seg[i][j - 1].second);
    }
    int q;
    int last = 0;
    scanf("%d", &q);
    while(q--){
        int pi, qi;
        scanf("%d %d", &pi, &qi);
        int xi = (pi + last) % n + 1;
        int ki = (qi + last) % n;
        last = query(1, 1, n, Pos[xi], Pos[xi] + Sz[xi] - 1, ki + Ds[xi]);
        printf("%d\n", last);
    }

}


#include<iostream>
#include<vector>
using namespace std;
int number[200001];
vector< int > g[200001];
int timer;
int Pos[200001];
int Hsh[200001];
int Sz[200001];
int Ds[200001];
void dfs(int node, int pa, int dist){
    Pos[node] = ++timer;
    Hsh[timer] = node;
    Sz[node] = 1;
    Ds[node] = dist;
    for(int i = 0 ; i < (int)g[node].size() ; ++i){
        int to = g[node][i];
        if(to == pa) continue;
        dfs(to, node, dist + 1);
        Sz[node] += Sz[to];
    }
}
vector< pair< int , int > > seg[400010];
int query(int node, int l, int r, int s, int e, int dist){
    if(s > r || l > e) return 2000000007;
    if(l >= s && r <= e){
        int B = 0;
        int E = (int)seg[node].size() - 1;
        int idx = -1;
        while(B <= E){
            int mi = (B + E)/2;
            if(seg[node][mi].first <= dist){
                idx = mi;
                B = mi + 1;
            } else
                E = mi - 1;
        }
        return seg[node][idx].second;
    }
    int p = query(2 * node, l, (l + r)/2 , s , e, dist);
    int q = query(2 * node + 1, (l + r)/2 + 1, r, s, e, dist);
    return min(p, q);
}
void Merge(int node){
    int l = 2 * node;
    int r = l + 1;
    int n = (int)seg[l].size();
    int m = (int)seg[r].size();
    int i = 0;
    int j = 0;
    while(i < n && j < m){
        if(seg[l][i].first <= seg[r][j].first){
            seg[node].push_back(seg[l][i]);
            ++i;
        }else{
                seg[node].push_back(seg[r][j]);
            ++j;
        }
    }
    while(i < n) {
        seg[node].push_back(seg[l][i]) ;
        ++i;
    }
    while(j < m){
        seg[node].push_back(seg[r][j]);
        ++j;
    }
}
void build(int node, int l, int r){
    if(l == r){
        seg[node].push_back({Ds[Hsh[l]], number[Hsh[l]]});
        return;
    }
    build(2 * node, l, (l + r)/2);
    build(2 * node + 1, (l + r)/2 + 1, r);
    Merge(node);
}
int main(){
    int n, r;
    scanf("%d %d", &n, &r);
    for(int i = 1; i <= n; ++i) scanf("%d", number + i);
    int e = n - 1;
    while(e--){
        int u, v;
        scanf("%d %d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(r, -1, 0);
    build(1, 1, n);
    for(int i = 0 ; i <= 4 * n  ;++i){
        int s = (int)seg[i].size();
        for(int j = 1 ; j < s ; ++j) seg[i][j].second = min(seg[i][j].second, seg[i][j - 1].second);
    }
    int q;
    int last = 0;
//printf("%d\n",2000000007);
    scanf("%d", &q);
    while(q--){
        int pi, qi;
        scanf("%d %d", &pi, &qi);
        int xi = (pi + last) % n + 1;
        int ki = (qi + last) % n;
        last = query(1, 1, n, Pos[xi], Pos[xi] + Sz[xi] - 1, ki + Ds[xi]);
        printf("%d\n", last);
    }

}


#include<iostream>
#include<vector>
using namespace std;
int number[200001];
vector< int > g[200001];
int timer;
int Pos[200001];
int Hsh[200001];
int Sz[200001];
int Ds[200001];
void dfs(int node, int pa, int dist){
    Pos[node] = ++timer;
    Hsh[timer] = node;
    Sz[node] = 1;
    Ds[node] = dist;
    for(int i = 0 ; i < (int)g[node].size() ; ++i){
        int to = g[node][i];
        if(to == pa) continue;
        dfs(to, node, dist + 1);
        Sz[node] += Sz[to];
    }
}
vector< pair< int , int > > seg[400010];
int query(int node, int l, int r, int s, int e, int dist){
    if(s > r || l > e) return 2000000007;
    if(l >= s && r <= e){
        int B = 0;
        int E = (int)seg[node].size() - 1;
        int idx = -1;
        while(B <= E){
            int mi = (B + E)/2;
            if(seg[node][mi].first <= dist){
                idx = mi;
                B = mi + 1;
            } else
                E = mi - 1;
        }
		if(idx==-1)
		{
		while(1)
		{
		int ffff = 3;
		}
		}
        return seg[node][idx].second;
    }
    int p = query(2 * node, l, (l + r)/2 , s , e, dist);
    int q = query(2 * node + 1, (l + r)/2 + 1, r, s, e, dist);
    return min(p, q);
}
void Merge(int node){
    int l = 2 * node;
    int r = l + 1;
    int n = (int)seg[l].size();
    int m = (int)seg[r].size();
    int i = 0;
    int j = 0;
    while(i < n && j < m){
        if(seg[l][i].first <= seg[r][j].first){
            seg[node].push_back(seg[l][i]);
            ++i;
        }else{
                seg[node].push_back(seg[r][j]);
            ++j;
        }
    }
    while(i < n) {
        seg[node].push_back(seg[l][i]) ;
        ++i;
    }
    while(j < m){
        seg[node].push_back(seg[r][j]);
        ++j;
    }
}
void build(int node, int l, int r){
    if(l == r){
        seg[node].push_back({Ds[Hsh[l]], number[Hsh[l]]});
        return;
    }
    build(2 * node, l, (l + r)/2);
    build(2 * node + 1, (l + r)/2 + 1, r);
    Merge(node);
}
int main(){
    int n, r;
    scanf("%d %d", &n, &r);
    for(int i = 1; i <= n; ++i) scanf("%d", number + i);
    int e = n - 1;
    while(e--){
        int u, v;
        scanf("%d %d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(r, -1, 0);
    build(1, 1, n);
    for(int i = 0 ; i <= 4 * n  ;++i){
        int s = (int)seg[i].size();
        for(int j = 1 ; j < s ; ++j) seg[i][j].second = min(seg[i][j].second, seg[i][j - 1].second);
    }
    int q;
    int last = 0;
//printf("%d\n",2000000007);
    scanf("%d", &q);
    while(q--){
        int pi, qi;
        scanf("%d %d", &pi, &qi);
        int xi = (pi + last) % n + 1;
        int ki = (qi + last) % n;
        last = query(1, 1, n, Pos[xi], Pos[xi] + Sz[xi] - 1, ki + Ds[xi]);
        printf("%d\n", last);
    }

}


#include<iostream>
#include<vector>
using namespace std;
int number[200001];
vector< int > g[200001];
int timer;
int Pos[200001];
int Hsh[200001];
int Sz[200001];
int Ds[200001];
void dfs(int node, int pa, int dist){
    Pos[node] = ++timer;
    Hsh[timer] = node;
    Sz[node] = 1;
    Ds[node] = dist;
    for(int i = 0 ; i < (int)g[node].size() ; ++i){
        int to = g[node][i];
        if(to == pa) continue;
        dfs(to, node, dist + 1);
        Sz[node] += Sz[to];
    }
}
vector< pair< int , int > > seg[400010];
int query(int node, int l, int r, int s, int e, int dist){
    if(s > r || l > e) return 2000000007;
    if(l >= s && r <= e){
        int B = 0;
        int E = (int)seg[node].size() - 1;
        int idx = -1;
        while(B <= E){
            int mi = (B + E)/2;
            if(seg[node][mi].first <= dist){
                idx = mi;
                B = mi + 1;
            } else
                E = mi - 1;
        }
		if(idx==-1)
		{
		return 2000000007;
		}
        return seg[node][idx].second;
    }
    int p = query(2 * node, l, (l + r)/2 , s , e, dist);
    int q = query(2 * node + 1, (l + r)/2 + 1, r, s, e, dist);
    return min(p, q);
}
void Merge(int node){
    int l = 2 * node;
    int r = l + 1;
    int n = (int)seg[l].size();
    int m = (int)seg[r].size();
    int i = 0;
    int j = 0;
    while(i < n && j < m){
        if(seg[l][i].first <= seg[r][j].first){
            seg[node].push_back(seg[l][i]);
            ++i;
        }else{
                seg[node].push_back(seg[r][j]);
            ++j;
        }
    }
    while(i < n) {
        seg[node].push_back(seg[l][i]) ;
        ++i;
    }
    while(j < m){
        seg[node].push_back(seg[r][j]);
        ++j;
    }
}
void build(int node, int l, int r){
    if(l == r){
        seg[node].push_back({Ds[Hsh[l]], number[Hsh[l]]});
        return;
    }
    build(2 * node, l, (l + r)/2);
    build(2 * node + 1, (l + r)/2 + 1, r);
    Merge(node);
}
int main(){
    int n, r;
    scanf("%d %d", &n, &r);
    for(int i = 1; i <= n; ++i) scanf("%d", number + i);
    int e = n - 1;
    while(e--){
        int u, v;
        scanf("%d %d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(r, -1, 0);
    build(1, 1, n);
    for(int i = 0 ; i <= 4 * n  ;++i){
        int s = (int)seg[i].size();
        for(int j = 1 ; j < s ; ++j) seg[i][j].second = min(seg[i][j].second, seg[i][j - 1].second);
    }
    int q;
    int last = 0;
//printf("%d\n",2000000007);
    scanf("%d", &q);
    while(q--){
        int pi, qi;
        scanf("%d %d", &pi, &qi);
        int xi = (pi + last) % n + 1;
        int ki = (qi + last) % n;
        last = query(1, 1, n, Pos[xi], Pos[xi] + Sz[xi] - 1, ki + Ds[xi]);
        printf("%d\n", last);
    }

}


#include<iostream>
#include<vector>
using namespace std;
int number[100001];
vector< int > g[100001];
int timer;
int Pos[100001];
int Hsh[100001];
int Sz[100001];
int Ds[100001];
void dfs(int node, int pa, int dist){
    Pos[node] = ++timer;
    Hsh[timer] = node;
    Sz[node] = 1;
    Ds[node] = dist;
    for(int i = 0 ; i < (int)g[node].size() ; ++i){
        int to = g[node][i];
        if(to == pa) continue;
        dfs(to, node, dist + 1);
        Sz[node] += Sz[to];
    }
}
vector< pair< int , int > > seg[400000];
int query(int node, int l, int r, int s, int e, int dist){
    if(s > r || l > e) return 2e9;
    if(l >= s && r <= e){
        int b = 0;
        int e = (int)seg[node].size() - 1;
        int idx = -1;
        while(b <= e){
            int mi = (b + e)/2;
            if(seg[node][mi].first <= dist){
                idx = mi;
                b = mi + 1;
            } else
                e = mi - 1;
        }
        return seg[node][idx].second;
    }
    int p = query(2 * node, l, (l + r)/2 , s , e, dist);
    int q = query(2 * node + 1, (l + r)/2 + 1, r, s, e, dist);
    return min(p, q);
}
void Merge(int node){
    int l = 2 * node;
    int r = l + 1;
    int n = (int)seg[l].size();
    int m = (int)seg[r].size();
    int i = 0;
    int j = 0;
    while(i < n && j < m){
        if(seg[l][i].first <= seg[r][j].first){
            seg[node].push_back(seg[l][i]);
            ++i;
        }else{
                seg[node].push_back(seg[r][j]);
            ++j;
        }
    }
    while(i < n) {
        seg[node].push_back(seg[l][i]) ;
        ++i;
    }
    while(j < m){
        seg[node].push_back(seg[r][j]);
        ++j;
    }
}
void build(int node, int l, int r){
    if(l == r){
        seg[node].push_back({Ds[Hsh[l]], number[Hsh[l]]});
        return;
    }
    build(2 * node, l, (l + r)/2);
    build(2 * node + 1, (l + r)/2 + 1, r);
    Merge(node);
}
int main(){
    int n, r;
    scanf("%d %d", &n, &r);
    for(int i = 1; i <= n; ++i) scanf("%d", number + i);
    int e = n - 1;
    while(e--){
        int u, v;
        scanf("%d %d", &u, &v);
        g[u].push_back(v);
        g[v].push_back(u);
    }
    dfs(r, -1, 0);
    build(1, 1, n);
    for(int i = 0 ; i < 4 * n  ;++i){
        int s = (int)seg[i].size();
        for(int j = 1 ; j < s ; ++j) seg[i][j].second = min(seg[i][j].second, seg[i][j - 1].second);
    }
    int q;
    int last = 0;
    scanf("%d", &q);
    while(q--){
        int pi, qi;
        scanf("%d %d", &pi, &qi);
        int xi = (pi + last) % n + 1;
        int ki = (qi + last) % n;
        last = query(1, 1, n, Pos[xi], Pos[xi] + Sz[xi] - 1, ki + Ds[xi]);
        printf("%d\n", last);
    }

}