#pragma GCC optimize("Ofast,unroll-loops")
// #pragma comment(linker, "/stack:200000000")
// #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2,fma,tune=native")

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef int ll;
typedef long double ld;
typedef pair <ll, ll> pll;

#ifdef SINA
#define dbg(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char* name, Arg1&& arg1) { cout << name << " : " << arg1 << std::endl; }
template <typename Arg1, typename... Args> void __f (const char* names, Arg1&& arg1, Args&&... args) {
	const char* comma = strchr(names + 1, ',');cout.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...); }
#define dbg2(x, j, n) cout<< #x << " : "; output((j), (n), x, 1); cout.flush();
#else
#define dbg(...) 0
#define dbg2(x, j, n) 0
#endif
#define SZ(x) ((ll)((x).size()))
#define File(s, t) freopen(s ".txt", "r", stdin); freopen(t ".txt", "w", stdout);
#define input(j, n, a) for (int _i = (j); _i < (n)+(j); _i++) cin>> a[_i];
#define output(j, n, a, t) for (int _i = (j); _i < (n)+(j); _i++) cout<< a[_i] << (((t) && _i != (n)+(j)-1)? ' ' : '\n');
#define kill(x) return cout<< (x) << endl, 0
#define cl const ll
#define fr first
#define sc second
#define lc (v << 1)
#define rc (lc | 1)
#define mid ((l + r) >> 1)
#define All(x) (x).begin(), (x).end()

cl inf = sizeof(ll) == 4 ? (1e9 + 10) : (3e18), mod = 1e9 + 7, MOD = 998244353;

template <class A,class B> ostream& operator << (ostream& out,const pair<A,B>&a){return out<<'('<<a.first<<", "<<a.second<<')';}
template <class A> ostream& operator << (ostream& out, const vector<A> &a) {
	out<< '['; for (int i = -1; ++i < int(a.size());) out<< a[i] << (i + 1 < int(a.size()) ? ", " : ""); return out<<']'; }
template <class T, typename _t = less <T> > using Tree = tree <T, null_type, _t, rb_tree_tag, tree_order_statistics_node_update>;

cl N = 5e5 + 7;

ll par [N], n, m, cnt;
pll d [N];
bool rmv [N], mark [N];
vector <ll> adj [N];

inline void prt (bool trm) {
	if (!trm) { cout<< "No\n"; return; }
	cnt = 0;
	for (ll i = 1; i <= n; i++) if (rmv[i]) cnt++;
	cout<< "Yes\n" << cnt << '\n';
	for (ll i = 1; i <= n; i++) if (rmv[i]) cout<< i << ' ';
	cout<< '\n';
}

bool mod3_0 () {
	if (n == 1) { prt(0); return true; }
	ll i;
	for (i = 1; i <= n && SZ(adj[i]) % 3; i++);
	if (i > n) return false;
	for (ll j = 1; j <= n; j++) if (j != i) rmv[j] = 1;
	prt(1);
	return true;
}

bool shit1, shit2 = 1;
void path (ll v, ll u) {
	shit1 = 1;
	if (shit2) fill(rmv, rmv + n + 1, 1);
	while (v != par[u]) rmv[v] = 0, v = par[v];
}

void dfs1 (cl &v, cl &pr = 0) {
	if (shit1) return;
	mark[v] = 1;
	par[v] = pr;
	for (auto &u : adj[v]) if (u != pr && SZ(adj[u]) % 3 == 2) {
		if (shit1) break;
		if (mark[u]) path(v, u);
		else dfs1(u, v);
	}
}

bool mod3_2_cycle () {
	if (d[1].fr == 2 && d[n].fr == 2) { prt(0); return 1; }
	shit1 = 0;
	for (ll i = 1; i <= n; i++) {
		if (!mark[i] && SZ(adj[i]) % 3 == 2) dfs1(i);
		if (shit1) { prt(1); return true; }
	}
	return false;
}

ll root;

ll B [N], lst;
void bfs2 () {
	mark[root] = 1;
	B[lst = 0] = root;
	for (ll l = 0, v; l <= lst; l++) {
		v = B[l];
		if (v != root && SZ(adj[v]) % 3 == 1) { path(v, root); return; }
		for (auto &u : adj[v]) if (!mark[u]) par[u] = v, B[++lst] = u, mark[u] = 1;
	}
}

bool path_1_2_1 () {
	if (d[1].fr == 1 && d[2].fr == 1 && (n == 2 || d[3].fr == 2)) { prt(0); return true; }
	
	fill(mark, mark + n + 1, 0);

	shit1 = 0;
	for (ll i = 1; i <= n; i++) if (SZ(adj[i]) % 3 == 1) {
		root = i;
		bfs2();
		break;
	}

	if (!shit1) return false;
	prt(1);
	return true;
}

void dfs3 (cl &v, cl &pr) {
	if (shit1) return;
	mark[v] = 1;
	par[v] = pr;
	for (auto &u : adj[v]) {
		if (shit1) break;
		if (v != root && u == d[n].sc) {
			path(v, root);
			break;
		}
		if (!mark[u]) dfs3(u, v);
	}
}

bool pedarat () {
	if (d[n].fr == 4) { prt(0); return 1; }
	fill(rmv, rmv + n + 1, 1);
	fill(mark, mark + n + 1, 0);
	rmv[d[n].sc] = 0;
	mark[d[n].sc] = 1;
	shit1 = shit2 = 0;
	for (auto &u : adj[d[n].sc]) if (!mark[u]) {
		if (shit1) break;
		root = u;
		dfs3(u, 0);
	}
	shit1 = 0;
	for (auto &u : adj[d[n].sc]) if (!mark[u]) {
		if (shit1) break;
		root = u;
		dfs3(u, 0);
	}
	shit2 = 1;
	prt(1);
	return true;
}

void solve () {
	cin>> n >> m;

	for (ll i = 1; i <= n; i++) adj[i].clear(), rmv[i] = mark[i] = false;

	for (ll i = 0, v, u; i < m; i++) {
		cin>> v >> u;
		adj[v].push_back(u); adj[u].push_back(v);
	}

	for (ll i = 1; i <= n; i++) d[i] = {SZ(adj[i]), i};
	sort(d + 1, d + n + 1);

	if (mod3_0()) return;
	if (mod3_2_cycle()) return;
	if (path_1_2_1()) return;
	if (pedarat()) return;
	prt(0); // :sob:
}

int main ()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	ll test;
	for (cin>> test; test--;) solve();

	cerr<< "\nTime elapsed: " << 1000 * clock() / CLOCKS_PER_SEC << "ms\n";

	return 0;
}
/*
3
3 3
1 2
2 3
3 1

6 6
1 2
1 3
2 3
2 5
2 6
2 4

8 12
1 2
1 3
2 3
1 4
4 5
5 1
3 6
3 7
3 8
6 1
7 1
8 1

*/