#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using ll = long long;
#define SZ(v) (ll)((v).size())
#define pb emplace_back
#define AI(i) begin(i), end(i)
#define X first
#define Y second
template<class T> bool chmin(T &a, T b) { return b < a && (a = b, true); }
template<class T> bool chmax(T &a, T b) { return a < b && (a = b, true); }
#ifdef KEV
#define DE(args...) kout("[ " + string(#args) + " ] = ", args)
void kout() { cerr << endl; }
template<class T, class ...U> void kout(T a, U ...b) { cerr << a << ' ', kout(b...); }
template<class T> void debug(T l, T r) { while (l != r) cerr << *l << " \n"[next(l)==r], ++l; }
#else
#define DE(...) 0
#define debug(...) 0
#endif
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int t;
cin >> t;
auto solve = [&]() {
int n, m;
cin >> n >> m;
vector<vector<pair<int, int>>> adj(n);
for (int i = 0; i < m; i++) {
int u, v, c;
cin >> u >> v >> c;
u--, v--, c--;
adj[u].emplace_back(v, c);
adj[v].emplace_back(u, c);
}
vector<int> dfn(n, -1), low(n, -1), stk, cnt(n);
vector<vector<int>> comps;
int T = 0;
auto dfs = [&](auto dfs, int u, int p) -> void {
dfn[u] = low[u] = T++;
for (auto [v, c] : adj[u]) {
if (v == p) { continue; }
if (dfn[v] == -1) {
stk.push_back(v);
dfs(dfs, v, u);
low[u] = min(low[u], low[v]);
if (low[v] >= dfn[u]) {
comps.emplace_back();
int x;
do {
x = stk.back();
comps.back().push_back(x);
cnt[x]++;
stk.pop_back();
} while (x != v);
comps.back().push_back(u);
cnt[u]++;
}
} else {
low[u] = min(low[u], dfn[v]);
}
}
};
dfs(dfs, 0, -1);
vector<int> in(n);
for (const auto &comp : comps) {
for (auto u : comp) {
in[u] = true;
}
vector<int> has(3);
int cnt = 0;
for (auto u : comp) {
vector<int> has2(3);
for (auto [v, c] : adj[u]) {
if (!in[v]) {
continue;
}
has[c] = has2[c] = true;
}
cnt += count(has2.begin(), has2.end(), true) > 1;
}
if (has == vector<int>(3, true) && cnt >= 3) {
cout << "Yes\n";
return;
}
for (auto u : comp) {
in[u] = false;
}
}
cout << "No\n";
};
while (t--) {
solve();
}
return 0;
}