#include <bits/stdc++.h>
using namespace std;
long long gcd(long long a, long long b) { return b == 0 ? a : gcd(b, a % b); }
const int MAXN = 500000;
const int MAXCOMP = MAXN;
int n, m;
vector<int> adj[MAXN];
vector<int> anssteal;
int col[MAXN];
bool keep[MAXN];
void buildans() {
  anssteal.clear();
  for (int i = (0); i < (n); ++i)
    if (!keep[i]) anssteal.push_back(i);
}
int par[MAXN], dep[MAXN], comp[MAXN], ncomp;
vector<pair<int, int>> cycedges;
int lastseenby[MAXCOMP];
vector<int> compones[MAXCOMP];
vector<int> onlyones[MAXCOMP];
bool debug = false;
void dfscyc(int at) {
  for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
    int to = adj[at][i];
    if (col[to] != 2 || to == par[at] || par[to] != -2 && dep[to] > dep[at])
      continue;
    if (par[to] == -2) {
      par[to] = at;
      dep[to] = dep[at] + 1;
      comp[to] = comp[at];
      dfscyc(to);
    } else {
      cycedges.push_back(make_pair(at, to));
    }
  }
}
bool aadj[MAXN];
bool badj[MAXN];
void makepath(int a, int b, int c) {
  if (debug) printf("makepath(%d,%d,%d)\n", a + 1, b + 1, c);
  int aa = -1;
  for (int i = (0); i < (((int)(adj[a]).size())); ++i) {
    int to = adj[a][i];
    if (col[to] == 2 && comp[to] == c && (aa == -1 || dep[to] < dep[aa]))
      aa = to;
  }
  assert(aa != -1);
  int bb = -1;
  for (int i = (0); i < (((int)(adj[b]).size())); ++i) {
    int to = adj[b][i];
    if ((a != b || to != aa) && col[to] == 2 && comp[to] == c &&
        (bb == -1 || dep[to] < dep[bb]))
      bb = to;
  }
  assert(bb != -1);
  if (dep[aa] < dep[bb]) swap(aa, bb), swap(a, b);
  for (int i = (0); i < (n); ++i) aadj[i] = false;
  for (int i = (0); i < (((int)(adj[a]).size())); ++i) {
    int to = adj[a][i];
    aadj[to] = true;
  }
  for (int i = (0); i < (n); ++i) badj[i] = false;
  for (int i = (0); i < (((int)(adj[b]).size())); ++i) {
    int to = adj[b][i];
    badj[to] = true;
  }
  keep[a] = keep[b] = true;
  while (dep[aa] > dep[bb]) {
    keep[aa] = true;
    if (badj[aa] && a != b) return;
    aa = par[aa];
  }
  if (aadj[bb] && a != b) {
    keep[bb] = true;
    return;
  }
  keep[aa] = keep[bb] = true;
  while (aa != bb) aa = par[aa], bb = par[bb], keep[aa] = keep[bb] = true;
}
bool solve() {
  for (int i = (0); i < (n); ++i) col[i] = ((int)(adj[i]).size()) % 3;
  for (int i = (0); i < (n); ++i) keep[i] = false;
  for (int i = (0); i < (n); ++i)
    if (col[i] == 0) {
      keep[i] = true;
      buildans();
      return ((int)(anssteal).size()) > 0;
    }
  for (int at = (0); at < (n); ++at)
    for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
      int to = adj[at][i];
      if (col[at] == 1 && col[to] == 1) {
        keep[at] = keep[to] = true;
        buildans();
        return ((int)(anssteal).size()) > 0;
      }
    }
  for (int i = (0); i < (n); ++i) par[i] = -2;
  ncomp = 0;
  for (int i = (0); i < (n); ++i)
    if (col[i] == 2 && par[i] == -2) {
      par[i] = -1;
      dep[i] = 0;
      comp[i] = ncomp++;
      dfscyc(i);
    }
  if (debug) {
    for (int i = (0); i < (n); ++i)
      if (par[i] != -2)
        printf("%d: par=%d dep=%d\n", i + 1, par[i] + 1, dep[i]);
  }
  if (debug) {
    printf("cycedges:");
    for (int i = (0); i < (((int)(cycedges).size())); ++i)
      printf(" (%d,%d)", cycedges[i].first + 1, cycedges[i].second + 1);
    puts("");
  }
  if (((int)(cycedges).size()) >= 1) {
    pair<int, int> highest = cycedges[0];
    for (int i = (1); i < (((int)(cycedges).size())); ++i)
      if (dep[cycedges[i].first] < dep[highest.first] ||
          dep[cycedges[i].first] == dep[highest.first] &&
              dep[cycedges[i].second] > dep[highest.second])
        highest = cycedges[i];
    if (debug) {
      printf("highest=(%d,%d)\n", highest.first + 1, highest.second + 1);
    }
    cycedges.clear();
    for (int x = highest.first;; x = par[x]) {
      keep[x] = true;
      if (x == highest.second) break;
    }
    buildans();
    return ((int)(anssteal).size()) > 0;
  }
  for (int i = (0); i < (ncomp); ++i) lastseenby[i] = -1;
  for (int at = (0); at < (n); ++at)
    if (col[at] == 1)
      for (int i = (0); i < (((int)(adj[at]).size())); ++i) {
        int to = adj[at][i];
        if (col[to] != 2 || lastseenby[comp[to]] == at) continue;
        lastseenby[comp[to]] = at;
        compones[comp[to]].push_back(at);
      }
  for (int i = (0); i < (ncomp); ++i)
    if (((int)(compones[i]).size()) >= 2) {
      int a = compones[i][0], b = compones[i][1];
      for (int k = (0); k < (ncomp); ++k) compones[k].clear();
      makepath(a, b, i);
      buildans();
      return ((int)(anssteal).size()) > 0;
    }
  for (int k = (0); k < (ncomp); ++k) compones[k].clear();
  int onlyone = -1;
  for (int i = (0); i < (n); ++i)
    if (col[i] == 1) {
      assert(onlyone == -1);
      onlyone = i;
    }
  if (onlyone == -1) return false;
  for (int i = (0); i < (((int)(adj[onlyone]).size())); ++i) {
    int to = adj[onlyone][i];
    if (col[to] == 2) onlyones[comp[to]].push_back(to);
  }
  int c1 = -1, c2 = -1;
  for (int i = (0); i < (ncomp); ++i)
    if (((int)(onlyones[i]).size()) >= 2) {
      if (c1 == -1)
        c1 = i;
      else if (c2 == -1)
        c2 = i;
    }
  for (int k = (0); k < (ncomp); ++k) onlyones[k].clear();
  if (c1 == -1 || c2 == -1) return false;
  makepath(onlyone, onlyone, c1);
  makepath(onlyone, onlyone, c2);
  buildans();
  return ((int)(anssteal).size()) > 0;
}
int ncase;
void run(int casenr) {
  scanf("%d%d", &n, &m);
  for (int i = (0); i < (m); ++i) {
    int a, b;
    scanf("%d%d", &a, &b);
    --a, --b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  bool ans = solve();
  for (int i = (0); i < (n); ++i) adj[i].clear();
  printf("%s\n", ans ? "Yes" : "No");
  if (ans) {
    printf("%d\n", ((int)(anssteal).size()));
    for (int i = (0); i < (((int)(anssteal).size())); ++i) {
      if (i != 0) printf(" ");
      printf("%d", anssteal[i] + 1);
    }
    puts("");
  }
}
int main() {
  scanf("%d", &ncase);
  for (int i = (1); i <= (ncase); ++i) run(i);
  return 0;
}
