#pragma warning(disable:4786) #include<list> #include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<set> #include<map> #include<functional> #include<string> #include<cstring> #include<cstdlib> #include<queue> #include<utility> #include<fstream> #include<sstream> #include<cmath> #include<stack> #include<assert.h> using namespace std; #define MEM(a, b) memset(a, (b), sizeof(a)) #define CLR(a) memset(a, 0, sizeof(a)) #define MAX(a, b) ((a) > (b) ? (a) : (b)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define ABS(X) ( (X) > 0 ? (X) : ( -(X) ) ) #define S(X) ( (X) * (X) ) #define SZ(V) (int )V.size() #define FORN(i, n) for(i = 0; i < n; i++) #define FORAB(i, a, b) for(i = a; i <= b; i++) #define ALL(V) V.begin(), V.end() #define IN(A, B, C) ((B) <= (A) && (A) <= (C)) typedef pair<int, int> PII; typedef pair<double, double> PDD; typedef vector<int> VI; typedef vector<PII > VP; #define AIN(A, B, C) assert(IN(A, B, C)) //typedef int LL; //typedef long long int LL; //typedef __int64 LL; const int MAXN = 100; int n; vector<int> g[MAXN]; int match[MAXN], p[MAXN], base[MAXN], q[MAXN]; bool used[MAXN], blossom[MAXN]; int lca (int a, int b) { bool used[MAXN] = { 0 }; for (;;) { a = base[a]; used[a] = true; if (match[a] == -1) break; a = p[match[a]]; } for (;;) { b = base[b]; if (used[b]) return b; b = p[match[b]]; } } void mark_path (int v, int b, int children) { while (base[v] != b) { blossom[base[v]] = blossom[base[match[v]]] = true; p[v] = children; children = match[v]; v = p[match[v]]; } } int find_path (int root) { memset (used, 0, sizeof used); memset (p, -1, sizeof p); for (int i=0; i<n; ++i) base[i] = i; used[root] = true; int qh=0, qt=0; q[qt++] = root; while (qh < qt) { int v = q[qh++]; for (size_t i=0; i<g[v].size(); ++i) { int to = g[v][i]; if (base[v] == base[to] || match[v] == to) continue; if (to == root || match[to] != -1 && p[match[to]] != -1) { int curbase = lca (v, to); memset (blossom, 0, sizeof blossom); mark_path (v, curbase, to); mark_path (to, curbase, v); for (int i=0; i<n; ++i) if (blossom[base[i]]) { base[i] = curbase; if (!used[i]) { used[i] = true; q[qt++] = i; } } } else if (p[to] == -1) { p[to] = v; if (match[to] == -1) return to; to = match[to]; used[to] = true; q[qt++] = to; } } } return -1; } /* memset (match, -1, sizeof match); for (int i=0; i<n; ++i) if (match[i] == -1) { int v = find_path (i); while (v != -1) { int pv = p[v], ppv = match[pv]; match[v] = pv, match[pv] = v; v = ppv; } } */ int M[100][100]; int main() { int T, m, a, b, ans; int i, j, v, pv, ppv, flag; scanf("%d", &T); AIN(T, 1, 10); while(T--) { scanf("%d %d", &n, &m); AIN(n, 1, 100); AIN(m, 1, 100); CLR(M); while(m--) { scanf("%d %d", &a, &b); AIN(a, 1, n); AIN(b, 1, n); a--, b--; M[a][b] = M[b][a] = 1; } FORN(i, n) g[i].clear(); FORN(i, n) FORN(j, n) if(M[i][j]) g[i].push_back(j); flag = 1; if(n % 2) flag = 0; memset (match, -1, sizeof match); for (i=0; i<n && flag; ++i) if (match[i] == -1) { v = find_path (i); while (v != -1) { pv = p[v], ppv = match[pv]; match[v] = pv, match[pv] = v; v = ppv; } if(match[i] == -1) flag = 0; } printf("%s\n", flag ? "YES" : "NO"); } return 0; }