import std.algorithm;
import std.array;
import std.ascii;
import std.container;
import std.conv;
import std.math;
import std.numeric;
import std.range;
import std.stdio;
import std.string;
import std.typecons;

void log(A...)(A arg) {
    stderr.writeln(arg);
}
int size(T)(in T s) {
    return cast(int)s.length;
}

void main() {
    int N, M;
    scanf("%d %d\n", &N, &M);
    auto O = new int[N];
    foreach (i; 1 .. N) {
        auto s = readln.chomp;
        O[i] = cast(int)([
            "T=T&X",
            "T=T&Y",
            "T=T|X",
            "T=T|Y",
            "T=T^X",
            "T=T^Y"
        ].countUntil(s));
    }
    auto T = new int[][N];
    foreach (i; 0 .. N - 1) {
        int u, v; scanf("%d %d\n", &u, &v);
        T[u] ~= v;
        T[v] ~= u;
    }

    int op(int v, int t, int x, int y) {
        switch (O[v]) {
            case 0: return t & x;
            case 1: return t & y;
            case 2: return t | x;
            case 3: return t | y;
            case 4: return t ^ x;
            case 5: return t ^ y;
            default: assert(false);
        }
    }

    // bitwise result of game 
    int result(int v, int prev, int depth, int t, int x, int y) {
        static int[Tuple!(int, int, int)] cache;
        auto key = tuple(v, x, y);
        if (key in cache) return cache[key];
        auto value_func = (delegate(int a, int b) {
            return depth % 2 == 0 ? max(a, b) : min(a, b); // max for A, min for B
        });
        int ans = depth % 2 == 0 ? 0 : 100;
        bool last = true;
        foreach (next; T[v]) {
            if (next == prev) continue;
            last = false;
            ans = value_func(ans, result(next, v, depth + 1, op(next, t, x, y), x, y));
        }
        if (last) return cache[key] = t; // if there's no turn, then t is the answer
        else return cache[key] = ans;
    }

    foreach (_; 0 .. M) {
        int X, Y;
        scanf("%d %d\n", &X, &Y);
        bool[Tuple!(int, int)] used;
        int lx, ly;
        for (int i = 15; i >= 0; i--) {
            int x = (X >> i) & 1;
            int y = (Y >> i) & 1;
            auto k = tuple(x, y);
            if (k in used) continue;
            used[k] = true;
            lx = (lx << 1) | x;
            ly = (ly << 1) | y;
        }
        auto bitwise_result = result(0, -1, 0, 0, lx, ly);
        //log([lx, ly], format("%b", bitwise_result));
        int ans;
        for (int i = 15; i >= 0; i--) {
            int x = (X >> i) & 1;
            int y = (Y >> i) & 1;
            for (int j = 0; j < 4; j++) {
                if ( (x == ((lx >> j) & 1)) && (y == ((ly >> j) & 1)) ) {
                    ans |= ((bitwise_result >> j) & 1) << i;
                    break;
                }
            }
        }
        writeln(ans);
    }
}