#include <bits/stdc++.h>
using namespace std;
const int N = 500 * 1000 + 20;
int n, m, ver_3k, root, par[N], h[N], d[N], cnt;
set<int> st, pap1;
bool vis[N], ok, seen;
vector<int> gr[N];
void find_3k_ver() {
  for (int i = 1; i <= n; i++)
    if (d[i] % 3 == 0)
      if (st.empty()) st.insert(i);
}
void dfs_find_cycle(int v) {
  vis[v] = true;
  int mx = -1;
  for (auto u : gr[v]) {
    if (st.size()) return;
    if (vis[u] && u != par[v]) {
      if (mx == -1)
        mx = u;
      else if (h[u] > h[mx])
        mx = u;
    }
  }
  if (mx != -1) {
    st.insert(v);
    while (v != mx && v) v = par[v], st.insert(v);
    return;
  }
  if (st.size()) return;
  for (auto u : gr[v]) {
    if (st.size()) return;
    if (!vis[u] && d[u] % 3 == 2)
      par[u] = v, h[u] = h[v] + 1, dfs_find_cycle(u);
  }
}
void find_2_cycle() {
  root = 0;
  for (int i = 1; i <= n; i++) vis[i] = false, h[i] = 0;
  for (int i = 1; i <= n; i++) {
    if (!vis[i] && d[i] % 3 == 2) dfs_find_cycle(i);
    if (st.size()) return;
  }
}
bool bfs(int v) {
  queue<int> q;
  q.push(v);
  vis[v] = true;
  while (!q.empty()) {
    int f = q.front();
    q.pop();
    if (d[f] % 3 == 1 && f != v) {
      st.insert(f);
      while (f != v) f = par[f], st.insert(f);
      return true;
    }
    for (auto u : gr[f])
      if (!vis[u]) par[u] = f, vis[u] = true, q.push(u);
  }
  return false;
}
void find_1_1_path() {
  root = 0;
  for (int i = 1; i <= n; i++) vis[i] = false, h[i] = 0, par[i] = 0;
  for (int i = 1; i <= n; i++)
    if (d[i] % 3 == 1 && !vis[i])
      if (bfs(i)) return;
}
void dfs(int v, int p) {
  vis[v] = true;
  for (auto u : gr[v]) {
    if (root != p && u == root) {
      seen = true;
      st.insert(v);
      while (v != root) v = par[v], st.insert(v);
      return;
    }
  }
  if (seen) return;
  for (auto u : gr[v]) {
    if (seen) return;
    if (!vis[u]) par[u] = v, dfs(u, v);
  }
  if (seen) return;
}
void dfs_vis_cmp(int v) {
  vis[v] = true;
  for (auto u : gr[v])
    if (u != root && !vis[u]) dfs_vis_cmp(u);
}
void find_papion() {
  root = 0, cnt = 0;
  for (int i = 1; i <= n; i++) {
    vis[i] = false;
    if (d[i] % 3 == 1) root = i;
  }
  if (!root) return;
  seen = false;
  dfs(root, -1);
  for (auto u : st) {
    pap1.insert(u);
    if (u != root) dfs_vis_cmp(u);
  }
  st.clear();
  seen = false;
  dfs(root, -1);
  if (!st.size()) return;
  for (auto u : pap1) st.insert(u);
  pap1.clear();
}
void print_ans() {
  ok = true;
  cout << "YES\n" << n - st.size() << "\n";
  for (int i = 1; i <= n; i++)
    if (!st.count(i)) cout << i << " ";
  cout << '\n';
}
void solve() {
  find_3k_ver();
  if (st.size() && st.size() < n) {
    print_ans();
    return;
  }
  find_2_cycle();
  if (st.size() && st.size() < n) {
    print_ans();
    return;
  }
  find_1_1_path();
  if (st.size() && st.size() < n) {
    print_ans();
    return;
  }
  find_papion();
  if (st.size() && st.size() < n) {
    print_ans();
    return;
  }
}
void reset() {
  for (int i = 1; i <= n; i++)
    d[i] = par[i] = h[i] = 0, vis[i] = false, gr[i].clear();
  pap1.clear(), st.clear();
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int t;
  cin >> t;
  while (t--) {
    ok = false;
    cin >> n >> m;
    reset();
    for (int i = 0; i < m; i++) {
      int u, v;
      cin >> u >> v;
      gr[u].push_back(v), gr[v].push_back(u);
      d[u]++, d[v]++;
    }
    solve();
    if (!ok) cout << "NO\n";
  }
  return 0;
}
