#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<map>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
#include<list>
using namespace std;
namespace FastIO {
inline long long read() {
char cc = getchar();
long long f = 1;
long long ans = 0;
while (cc < '0' or cc>'9') {
if (cc == '-') f = -1;
cc = getchar();
}
while (cc >= '0' and cc <= '9') {
ans = ans * 10 + cc - '0';
cc = getchar();
}
return ans * f;
}
}
using namespace FastIO;
namespace Code{
int T;
int t;
auto i=0, j=0, e = 0;
vector<int > n;
vector<int > f;
struct Edge {
int i;
int j;
int e;
}edge[11451411];
bool operator < (const Edge& a, const Edge& b) {
return a.e < b.e;
}
priority_queue<Edge> q;
map<int , bool> xp;
int u, v, w;
int get(int x) {
if (x == f[x]) return x;
return f[x] = get(f[x]);
}
void merge(int a, int b) {
int x = get(a);
int y = get(b);
f[x] = y;
}
int main() {
T = read();
f.resize(11451412);
while (T--) {
t = read();
n.clear();
xp.clear();
for (j = 0; j <= 11451411; j++) {
f[j] = j;
}
for (i = 1; i <= t; i++) {
edge[i].i = read();
edge[i].j = read();
edge[i].e = read();
if (edge[i].e == 1) {
if (xp[edge[i].i] == 0) {
n.push_back(edge[i].i);
}
if (xp[edge[i].j] == 0) {
n.push_back(edge[i].j);
}
xp[edge[i].i] = 1;
xp[edge[i].j] = 1;
}
q.push(edge[i]);
}
sort(n.begin(), n.end());
int flag = 1;
while (q.size()) {
if (q.top().e == 1) {
int u = lower_bound(n.begin(), n.end(), q.top().i) - n.begin();
int v = lower_bound(n.begin(), n.end(), q.top().j) - n.begin();
merge(u, v);
}
if (q.top().e == 0) {
if (get(lower_bound(n.begin(), n.end(), q.top().i) - n.begin()) == get(lower_bound(n.begin(), n.end(), q.top().j) - n.begin())) {
flag = 0;
}
}
q.pop();
}
if (flag == 0) {
cout << "NO" << endl;
continue;
}
cout << "YES" << endl;
}
return 0;
}
}
int main() {
return Code::main();
}