#include #include #include #include #include #include #include #include using namespace std; // constant expr const int ZERO = 0; const int ONE = 1; const int X = 2; const int Y = 3; // unary operators const int NOT = 4; // binary operators const int EQ = 5; const int AND = 6; const int OR = 7; const int XOR = 8; const int LEFT_PAREN = 9; int eval(int op, int x, int y) { if(op == AND) return x & y; if(op == OR) return x | y; if(op == XOR) return x ^ y; if(op == EQ) return x == y; assert(false); } int getop(char c) { if(c == '&') return AND; if(c == '|') return OR; if(c == '^') return XOR; if(c == '=') return EQ; assert(false); } void parse(const string& s, vector& ops) { vector opst; for(auto ch: s) { if(ch == '0') { ops.push_back(ZERO); continue; } if(ch == '1') { ops.push_back(ONE); continue; } if(ch == 'x') { ops.push_back(X); continue; } if(ch == 'y') { ops.push_back(Y); continue; } if(ch == '(') { opst.push_back(LEFT_PAREN); continue; } if(ch == ')') { while(true) { assert(opst.size()); if(opst.back() == LEFT_PAREN) { opst.pop_back(); break; } ops.push_back(opst.back()); opst.pop_back(); } while(false && opst.size() && opst.back() == NOT) { opst.pop_back(); ops.push_back(NOT); } continue; } if(ch == '!') { opst.push_back(NOT); continue; } // assume it is a binary op int currop = getop(ch); while(opst.size() && opst.back() <= currop) { ops.push_back(opst.back()); opst.pop_back(); } opst.push_back(currop); } while(opst.size()) { assert(opst.back() != LEFT_PAREN); ops.push_back(opst.back()); opst.pop_back(); } } int main() { int n, k; cin >> n >> k; vector stops; vector> bitindices; vector retval; vector>> solved(k); for(auto& x: solved) { x.resize(k); for(auto& y: x) y.resize(4); } for(int i = 0; i < n; i++) { int a, b; cin >> a >> b; a--; b--; string op; int ans; cin >> op >> ans; vector ops; parse(op, ops); uint8_t valid = 0; for(int x = 0; x < 2; x++) for(int y = 0; y < 2; y++) { if(solved[a][b][2*x+y]) continue; vector vals; for(int out: ops) { if(out == ZERO) { vals.push_back(0); continue; } if(out == ONE) { vals.push_back(1); continue; } if(out == X) { vals.push_back(x); continue; } if(out == Y) { vals.push_back(y); continue; } if(out == NOT) { assert(vals.size()); vals.back() ^= 1; continue; } assert(vals.size() >= 2); int a = vals.back(); vals.pop_back(); int b = vals.back(); vals.pop_back(); vals.push_back(eval(out, a, b)); } assert(vals.size() == 1); if(vals.back() == 1) { solved[a][b][2*x+y] = true; valid |= (1<<(2*x+y)); } } if(valid == 0) continue; stops.push_back(valid); bitindices.push_back({a, b}); retval.push_back(ans); } int finalresult; cin >> finalresult; vector> results(1024); for(int a = 0; a < (1<>bitindices[i][0])&1; int y = (b>>bitindices[i][1])&1; if(stops[i] & (1 << (2*x+y))) { ans = retval[i]; } } if(ans == -1) ans = finalresult; if(ans == 1) results[a].set(b); } { int ret = 0; for(int i = 0; i < (1< inner = ~results[i] & results[j]; ret += inner.count(); } } } cout << " " << ret << "\n"; } }