//feasible relation category dfs difficulty easy
#include<bits/stdc++.h>
#define ull unsigned long long
#define pb push_back
#define mp make_pair
using namespace std;
typedef pair<int,int> pii;
typedef vector<int> vi;
class union_find
{
public:
vector <int> parent,size;
union_find(int n)
{
parent=vector<int>(n);
size=vector<int>(n,1);
for(int i=0;i<n;i++)
{
parent[i]=i;
}
}
//find operation using path compression heuristic
//i.e. when root() is called for 'a' make the found root parent of a so we dont have
//to traverse up all again in order to find root of 'a'
int root(int a)
{
return parent[a]==a?a:parent[a]=root(parent[a]);
}
void unionset(int a,int b)
{
int aroot=root(a);
int broot=root(b);
if(size[aroot]<size[broot])
{
parent[aroot]=broot;
size[broot]+=size[aroot];
}
else
{
parent[broot]=aroot;
size[aroot]+=size[broot];
}
}
};
int main()
{
ios::sync_with_stdio(false);
//cin.tie(NULL);
int test;
cin>>test;
while(test--)
{
int n,k;
cin>>n>>k;
union_find uf(n);
cin.ignore();
vector<pii > qu;
string ans="YES";
//cout<<"Yaha\n";
while(k--)
{
string s;
getline(cin,s);
istringstream iss(s);
int a,b;
string sa;
iss>>a;
iss>>sa;
iss>>b;
a--;
b--;
//cout<<"Yahaloopme\n";
if(sa=="!=")
{
if(uf.root(a)==uf.root(b))
{
ans="NO";
break;
}
else
qu.pb(mp(a,b));
}
else
uf.unionset(a,b);
}
//cout<<"fir";
for(int i=0;i<qu.size()&&ans=="YES";i++)
{
if(uf.root(qu[i].first)==uf.root(qu[i].second))
{ans="NO"; break;}
}
cout<<ans<<endl;
}
}
Ly9mZWFzaWJsZSByZWxhdGlvbiBjYXRlZ29yeSBkZnMgZGlmZmljdWx0eSBlYXN5CiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CiNkZWZpbmUgdWxsIHVuc2lnbmVkIGxvbmcgbG9uZwojZGVmaW5lIHBiIHB1c2hfYmFjawojZGVmaW5lIG1wIG1ha2VfcGFpcgp1c2luZyBuYW1lc3BhY2Ugc3RkOwp0eXBlZGVmIHBhaXI8aW50LGludD4gcGlpOwp0eXBlZGVmIHZlY3RvcjxpbnQ+IHZpOwpjbGFzcyB1bmlvbl9maW5kCnsKCXB1YmxpYzoKCXZlY3RvciA8aW50PiBwYXJlbnQsc2l6ZTsKCXVuaW9uX2ZpbmQoaW50IG4pCgl7CgkJcGFyZW50PXZlY3RvcjxpbnQ+KG4pOwoJCXNpemU9dmVjdG9yPGludD4obiwxKTsKCQlmb3IoaW50IGk9MDtpPG47aSsrKQoJCXsKCQkJcGFyZW50W2ldPWk7CgkJfQoJfQoJLy9maW5kIG9wZXJhdGlvbiB1c2luZyBwYXRoIGNvbXByZXNzaW9uIGhldXJpc3RpYwoJLy9pLmUuIHdoZW4gcm9vdCgpIGlzIGNhbGxlZCBmb3IgJ2EnIG1ha2UgdGhlIGZvdW5kIHJvb3QgcGFyZW50IG9mIGEgc28gd2UgZG9udCBoYXZlCgkvL3RvIHRyYXZlcnNlIHVwIGFsbCBhZ2FpbiBpbiBvcmRlciB0byBmaW5kIHJvb3Qgb2YgJ2EnCglpbnQgcm9vdChpbnQgYSkKCXsKCQlyZXR1cm4gcGFyZW50W2FdPT1hP2E6cGFyZW50W2FdPXJvb3QocGFyZW50W2FdKTsKCX0KCXZvaWQgdW5pb25zZXQoaW50IGEsaW50IGIpCgl7CgkJaW50IGFyb290PXJvb3QoYSk7CgkJaW50IGJyb290PXJvb3QoYik7CgkJaWYoc2l6ZVthcm9vdF08c2l6ZVticm9vdF0pCgkJewoJCQlwYXJlbnRbYXJvb3RdPWJyb290OwoJCQlzaXplW2Jyb290XSs9c2l6ZVthcm9vdF07CgkJfQoJCWVsc2UKCQl7CgkJCXBhcmVudFticm9vdF09YXJvb3Q7CgkJCXNpemVbYXJvb3RdKz1zaXplW2Jyb290XTsKCQl9Cgl9Cn07CmludCBtYWluKCkKewoJaW9zOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOwoJLy9jaW4udGllKE5VTEwpOwoJaW50IHRlc3Q7CgljaW4+PnRlc3Q7Cgl3aGlsZSh0ZXN0LS0pCgl7CgkJaW50IG4sazsKCQljaW4+Pm4+Pms7CgkJdW5pb25fZmluZCB1ZihuKTsKCQljaW4uaWdub3JlKCk7CgkJdmVjdG9yPHBpaSA+IHF1OwoJCXN0cmluZyBhbnM9IllFUyI7CgkJLy9jb3V0PDwiWWFoYVxuIjsKCQl3aGlsZShrLS0pCgkJewoJCQlzdHJpbmcgczsKCQkJZ2V0bGluZShjaW4scyk7CgkJCWlzdHJpbmdzdHJlYW0gaXNzKHMpOwoJCQlpbnQgYSxiOwoJCQlzdHJpbmcgc2E7CgkJCWlzcz4+YTsKCQkJaXNzPj5zYTsKCQkJaXNzPj5iOwoJCQlhLS07CgkJCWItLTsKCQkJLy9jb3V0PDwiWWFoYWxvb3BtZVxuIjsKCQkJaWYoc2E9PSIhPSIpCgkJCXsKCQkJCWlmKHVmLnJvb3QoYSk9PXVmLnJvb3QoYikpCgkJCQl7CgkJCQkJYW5zPSJOTyI7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQllbHNlCgkJCQkJcXUucGIobXAoYSxiKSk7CgkJCX0JCgkJCWVsc2UKCQkJCXVmLnVuaW9uc2V0KGEsYik7CgkJfQoJCS8vY291dDw8ImZpciI7CgkJZm9yKGludCBpPTA7aTxxdS5zaXplKCkmJmFucz09IllFUyI7aSsrKQoJCXsKCQkJCgkJCWlmKHVmLnJvb3QocXVbaV0uZmlyc3QpPT11Zi5yb290KHF1W2ldLnNlY29uZCkpCgkJCQl7YW5zPSJOTyI7IGJyZWFrO30KCgkJfQoJCWNvdXQ8PGFuczw8ZW5kbDsKCX0KCn0=