int n, m;
struct node {
int to,nex;
} e[maxm << 2];
int cnt = 0, head[maxn << 1];
bool inStk[maxn << 1];
int low[maxn << 1], dfn[maxn << 1],dfc, pos[maxn << 1];
void init() {
dfc = cnt = 0;
for(int i=0; i <=2* n; i++) {
head[i] = -1;
low[i] = dfn[i] = 0;
}
}
stack<int> stk;
void add(int u,int v) {
e[cnt].to = v;
e[cnt].nex = head[u];
head[u] = cnt ++;
}
int cntSCC;
void Tarjan(int u) {
// cout << u << endl;
dfn[u] = low[u] = ++ dfc;
inStk[u] = 1;
stk.push(u);
for(int i=head[u]; ~i; i=e[i].nex) {
itn to = e[i].to;
if(!dfn[to]) {
Tarjan(to);
low[u] = min(low[u],low[to]);
} else if(inStk[to] && !pos[to]) {
low[u] = min(low[u],dfn[to]);
}
}
if(low[u] == dfn[u]) {
int tp;
++ cntSCC;
do {
tp = stk.top();
stk.pop();
inStk[tp] = 0;
pos[tp] = cntSCC;
} while(tp != u);
}
}
int a,b,c;
string op;
int main() {
n=read,m=read;
init();
for(int i=1; i<=m; i++) {
a = read,b = read,c = read;
cin >> op;
int u=a * 2,u1=2 * a+1;
int v=b * 2,v1=2 * b+1;
if(op == "AND") {
if(c == 1) {/// u,v
add(u1,u);
add(v1,v);
} else {
// add(u,u1);
add(u,v1);
// add(v,u1);
add(v,u1);
}
} else if(op == "OR") {
if(c == 1) {
// add(u1,u);
add(u1,v);
// add(v1,v);
add(v1,u);
} else {
add(u,u1);
add(v,v1);
}
} else if(op == "XOR") {
if(c == 1) {
add(u,v1);
add(v,u1);
add(u1,v);
add(v1,u);
} else {
add(u,v);
add(v,u);
add(u1,v1);
add(v1,u1);
}
}
}
for(int i=0; i <= 2*n; i++) {
if(!dfn[i]) Tarjan(i);
}
for(int i=0; i <= 2*n; i++) {
if(pos[i] == pos[i+1]) {
puts("NO");
return 0;
}
i ++;
}
puts("YES");
return 0;
}