#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5e5 + 100, INF = 5e6;
bool done, mark[MAXN];
int t, n, m, root, want;
int h[MAXN];
int dis[MAXN], par[MAXN];
queue<int> q;
vector<int> vec, vec_dfs, comp, adj[MAXN];
vector<vector<int> > all;
void reset(void);
void find_0(void);
void act(int v);
void input() {
  cin >> n >> m;
  reset();
  while (m--) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (int i = 0; i < n; i++) sort(adj[i].begin(), adj[i].end());
}
void print(vector<int> X = vec) {
  done = true;
  if (X.empty() || X.size() == n) {
    cout << "NO" << '\n';
    return;
  }
  for (int i = 0; i < n; i++) mark[i] = false;
  for (int x : X) mark[x] = true;
  cout << "YES" << '\n' << n - X.size() << '\n';
  for (int v = 0; v < n; v++)
    if (mark[v] == false) cout << v + 1 << " ";
  cout << '\n';
  return;
}
void dfs_2(int v, int par = -1) {
  comp.push_back(v);
  h[v] = vec_dfs.size();
  vec_dfs.push_back(v);
  mark[v] = true;
  int U = n;
  for (int u : adj[v])
    if ((adj[u].size() % 3 == 2) && (u ^ par)) {
      if (mark[u] == false)
        continue;
      else if (h[u] < h[v] && (U == n || h[u] > h[U]))
        U = u;
    }
  if (U != n) {
    for (int i = h[U]; i < vec_dfs.size(); i++) vec.push_back(vec_dfs[i]);
    done = true;
    print();
    return;
  }
  for (int u : adj[v])
    if ((u ^ par) && (adj[u].size() % 3 == 2) && mark[u] == false) {
      dfs_2(u, v);
      if (done) return;
    }
  vec_dfs.pop_back();
}
void BFS(int v, int bad = n) {
  for (int i = 0; i < n; i++) dis[i] = INF;
  dis[bad] = 0;
  dis[v] = 0;
  q.push(v);
  while (q.size()) {
    act(q.front());
    q.pop();
  }
}
void find_121() {
  for (int v = 0; v < n; v++)
    if (adj[v].size() % 3 == 1) {
      BFS(v);
      int ans = n;
      for (int u = v + 1; u < n; u++)
        if ((adj[u].size() % 3 == 1) && (ans == n || dis[u] < dis[ans]))
          ans = u;
      if (ans != n) {
        vec.push_back(ans);
        while (ans != v) vec.push_back(ans = par[ans]);
        print();
      }
      break;
    }
}
vector<int> f(vector<int> comp) {
  vector<int> vec;
  for (int x : comp)
    if (binary_search(adj[root].begin(), adj[root].end(), x)) vec.push_back(x);
  return vec;
}
void add(vector<int> comp) {
  for (int i = 0; i < n; i++) mark[i] = false;
  int u = comp[0], v = comp[1];
  BFS(u, root);
  for (int x : comp)
    if (dis[x] && dis[x] < dis[v]) v = x;
  vec.push_back(v);
  while (v != u) vec.push_back(v = par[v]);
}
void solve() {
  input();
  if (n <= 3) {
    print();
    return;
  }
  find_0();
  if (done) return;
  find_121();
  if (done) return;
  for (int v = 0; v < n; v++)
    if ((adj[v].size() % 3 == 2) && mark[v] == false) {
      comp.clear();
      vec_dfs.clear();
      dfs_2(v);
      if (done) return;
      all.push_back(comp);
    }
  if (all.size() < 2) {
    cout << "NO\n";
    return;
  }
  for (int i = 0; i < n; i++)
    if (mark[i] == false) root = i;
  vector<int> a = f(all[0]), b = f(all[1]);
  if (max(all.size(), max(a.size(), b.size())) == 2) {
    cout << "NO" << '\n';
    return;
  }
  vec = {root};
  add(a);
  add(b);
  print();
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  cin >> t;
  while (t--) solve();
  return 0;
}
void reset() {
  memset(h, 0, sizeof(h));
  done = false;
  for (int i = 0; i < n; i++) mark[i] = false;
  vec.clear();
  vec_dfs.clear();
  comp.clear();
  for (int i = 0; i < n; i++) adj[i].clear();
  all.clear();
}
void find_0() {
  for (int i = 0; i < n; i++)
    if (adj[i].size() % 3 == 0) {
      vec = {i};
      print();
      return;
    }
}
void act(int v) {
  for (int u : adj[v])
    if (dis[u] == INF) {
      dis[u] = dis[par[u] = v] + 1;
      q.push(u);
    }
}
