#include<bits/stdc++.h> #define LL long long #define VIT vector<int>::iterator usingnamespace std; constint N = 1e4 + 5; int n, m, e, v; int c[N], du[N]; bool f; //true-No,false-Yes vector<int> to[N], cir; voidclear() { for (int i = 1; i <= n; ++i) to[i].clear(), c[i] = 0; f = false; } voiddfs(int x, int _c)//染色法判奇环 { if (f) return ; if (c[x]) { if (c[x] != _c) f = true; return ; } c[x] = _c; ++v; e += to[x].size(); cir.push_back(x); for (VIT i = to[x].begin(); i != to[x].end(); ++i) dfs(*i, 3 - _c); } voidtopu()//拓扑处理非环节点 { queue<int> q; for (VIT i = cir.begin(); i != cir.end(); ++i) { du[*i] = to[*i].size(); if (du[*i] == 1) q.push(*i); } int x; while (!q.empty()) { x = q.front(), q.pop(); for (VIT i = to[x].begin(); i != to[x].end(); ++i) if(--du[*i] == 1) q.push(*i); } } intmain() { int T, t, tt; scanf("%d", &T); while (T--) { scanf("%d%d", &n, &m); clear(); for (int i = 1, x, y; i <= m; i++) { scanf("%d%d", &x, &y); to[x].push_back(y); to[y].push_back(x); } for (int i = 1; i <= n; ++i) if (!c[i]) { e = v = 0; cir.clear(); dfs(i, 1); e /= 2; //存的是双向边,真正的边数要除以2 if (e > v + 1) f = true; if (f) break; if (e <= v) continue; topu(); tt = 0; for (VIT j = cir.begin(); j != cir.end(); ++j) if (du[*j] == 2) { t = 0; for (VIT k = to[*j].begin(); k != to[*j].end(); ++k) if (du[*k] == 3) ++t; if (t == 2) ++tt; } if (tt < 2) { f = true; break; } } if (f) puts("NO"); else puts("YES"); } return0; }