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

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

int n,q;
string op[100010];
vector<int> g[100010];
int mat[8][8];

int calc(int crt,string o,int x,int y){
  if(o[4]=='X'){
    if(o[3]=='&')return crt&x;
    if(o[3]=='|')return crt|x;
    if(o[3]=='^')return crt^x;
  }else{
    if(o[3]=='&')return crt&y;
    if(o[3]=='|')return crt|y;
    if(o[3]=='^')return crt^y;
  }
  return -1;
}

int dfs(int v,int pre,int x,int y,int f,int crt){
  vector<int> vs;
  for(int nv : g[v]){
    if(nv==pre)continue;
    vs.push_back(dfs(nv,v,x,y,1-f,v!=0?calc(crt,op[v],x,y):0));
  }
  if(vs.size()==0){
    return calc(crt,op[v],x,y);
  }
  sort(all(vs));
  return f==0?vs.back():vs.front();
}

int main(){
  cin>>n>>q;
  rep(i,n-1){
    cin>>op[i+1];
  }
  rep(i,n-1){
    int a,b;
    cin>>a>>b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  rep(x,8)rep(y,8){
    mat[x][y]=dfs(0,-1,x,y,0,0);
  }
  rep(i,q){
    int x,y;
    cin>>x>>y;
    bool used[2][2],pat[2][2];
    memset(used,0,sizeof(used));
    memset(pat,0,sizeof(pat));
    int nx=0,ny=0;
    for(int k=20;k>=0;k--){
      if((((x>>k)&1)|((y>>k)&1))&&!used[(x>>k)&1][(y>>k)&1]){
        used[(x>>k)&1][(y>>k)&1]=true;
        nx<<=1; ny<<=1;
        nx|=(x>>k)&1;
        ny|=(y>>k)&1;
      }
    }
    int res=0;
    for(int k=20;k>=0;k--){
      res<<=1;
      if(((x>>k)&1)|((y>>k)&1)){
        rep(nk,3){
          if(((nx>>nk)&1)==((x>>k)&1)&&((ny>>nk)&1)==((y>>k)&1)){
            res|=(mat[nx][ny]>>nk)&1;
          }
        }
      }
    }
    cout<<res<<endl;
  }
  return 0;
}


### Prompt

Create a solution in Cpp for the following problem:

H --Bit Operation Game

Given a rooted tree with N vertices. The vertices are numbered from 0 to N − 1, and the 0th vertex represents the root. `T = 0` for the root, but for the other vertices

* `T = T & X;`
* `T = T & Y;`
* `T = T | X`
* `T = T | Y`
* `T = T ^ X`
* `T = T ^ Y`



One of the operations is written. Here, the operators &, |, ^ mean the bitwise operators and, or, xor, respectively.

Mr. A and Mr. B played the following games M times using this tree. The two start from the root and select the child vertices and proceed alternately, starting from Mr. A and reaching the leaves. The final T value when the operations written in the passed nodes are applied in the order of passing is the score. Mr. B wants to make the score as small as possible, and Mr. A wants to make it large. Given the X and Y values ​​of the M games, output the score for each game when the two make the best choice.

Constraints

* 1 ≤ N ≤ 100000
* 1 ≤ M ≤ 100000
* 0 ≤ X, Y <2 ^ {16}



Input Format

Input is given from standard input in the following format.


N M
o_1_1
o_2
...
o_ {N−1}
u_1 v_1
u_2 v_2
...
u_ {N−1} v_ {N−1}
X_1 Y_1
X_2 Y_2
...
X_M Y_M


On the first line, the number of vertices N of the tree and the integer M representing the number of games played are entered.
From the 2nd line to the Nth line, the operation written at the 1st ... N-1st vertex is input.
In addition, the numbers of the two vertices connected by each side are entered in the N-1 line.
Finally, the values ​​of X and Y in M ​​games are entered over M lines.


Output Format

Print the final T value for each game on the M line.

Sample Input 1


6 3
T = T | X
T = T | Y
T = T | Y
T = T ^ Y
T = T & X;
0 1
0 2
13
14
twenty five
5 6
3 5
0 0


Sample Output 1


Four
6
0


<image>
For X = 5, Y = 6, proceed to vertices 0-> 2-> 5, and T = 5 & 6 = 4.
If X = 3, Y = 5, then go to vertices 0-> 1-> 4, and T = 3 ^ 5 = 6.
If X = 0, Y = 0, T does not change from 0 no matter where you go





Example

Input

6 3
T=T|X
T=T|Y
T=T|Y
T=T^Y
T=T&X
0 1
0 2
1 3
1 4
2 5
5 6
3 5
0 0


Output

4
6
0

### Response

```cpp
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<ll, ll> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcount

#define INF 1e16
#define mod 1000000007

int n,q;
string op[100010];
vector<int> g[100010];
int mat[8][8];

int calc(int crt,string o,int x,int y){
  if(o[4]=='X'){
    if(o[3]=='&')return crt&x;
    if(o[3]=='|')return crt|x;
    if(o[3]=='^')return crt^x;
  }else{
    if(o[3]=='&')return crt&y;
    if(o[3]=='|')return crt|y;
    if(o[3]=='^')return crt^y;
  }
  return -1;
}

int dfs(int v,int pre,int x,int y,int f,int crt){
  vector<int> vs;
  for(int nv : g[v]){
    if(nv==pre)continue;
    vs.push_back(dfs(nv,v,x,y,1-f,v!=0?calc(crt,op[v],x,y):0));
  }
  if(vs.size()==0){
    return calc(crt,op[v],x,y);
  }
  sort(all(vs));
  return f==0?vs.back():vs.front();
}

int main(){
  cin>>n>>q;
  rep(i,n-1){
    cin>>op[i+1];
  }
  rep(i,n-1){
    int a,b;
    cin>>a>>b;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  rep(x,8)rep(y,8){
    mat[x][y]=dfs(0,-1,x,y,0,0);
  }
  rep(i,q){
    int x,y;
    cin>>x>>y;
    bool used[2][2],pat[2][2];
    memset(used,0,sizeof(used));
    memset(pat,0,sizeof(pat));
    int nx=0,ny=0;
    for(int k=20;k>=0;k--){
      if((((x>>k)&1)|((y>>k)&1))&&!used[(x>>k)&1][(y>>k)&1]){
        used[(x>>k)&1][(y>>k)&1]=true;
        nx<<=1; ny<<=1;
        nx|=(x>>k)&1;
        ny|=(y>>k)&1;
      }
    }
    int res=0;
    for(int k=20;k>=0;k--){
      res<<=1;
      if(((x>>k)&1)|((y>>k)&1)){
        rep(nk,3){
          if(((nx>>nk)&1)==((x>>k)&1)&&((ny>>nk)&1)==((y>>k)&1)){
            res|=(mat[nx][ny]>>nk)&1;
          }
        }
      }
    }
    cout<<res<<endl;
  }
  return 0;
}


```