#include <bits/stdc++.h>
using namespace std;
template <class S, class T>
ostream& operator<<(ostream& o, const pair<S, T>& p) {
  return o << "(" << p.first << "," << p.second << ")";
}
template <class T>
ostream& operator<<(ostream& o, const vector<T>& vc) {
  o << "{";
  for (const T& v : vc) o << v << ",";
  o << "}";
  return o;
}
using ll = long long;
template <class T>
using V = vector<T>;
template <class T>
using VV = vector<vector<T>>;
constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); }
struct UnionFind {
  vector<int> par, rank;
  UnionFind(int N) {
    par.assign(N, 0);
    rank.assign(N, 0);
    for (int i = 0; i < (int)(N); i++) par[i] = i;
  }
  int find(int x) {
    if (par[x] == x) return x;
    return par[x] = find(par[x]);
  }
  bool same(int x, int y) { return find(x) == find(y); }
  void unite(int x, int y) {
    x = find(x), y = find(y);
    if (x == y) return;
    if (rank[x] < rank[y]) swap(x, y);
    par[y] = x;
    if (rank[x] == rank[y]) rank[x]++;
  }
};
V<int> getMinimalCycleUndirected(const VV<int>& G) {
  using P = pair<int, int>;
  int N = G.size();
  V<int> vis(N);
  V<int> par(N, -1);
  V<int> d(N);
  P U(-1, -1);
  function<void(int, int)> dfs = [&](int v, int p) {
    vis[v] = 1;
    for (int u : G[v])
      if (u != p) {
        if (vis[u] == 0) {
          par[u] = v;
          d[u] = d[v] + 1;
          dfs(u, v);
        } else if (vis[u] == 1) {
          if (U.first == -1 || d[U.first] - d[U.second] > d[v] - d[u]) {
            U = P(v, u);
          }
        } else {
        }
      }
    vis[v] = 2;
  };
  for (int v = 0; v < (int)(N); v++)
    if (vis[v] == 0) {
      dfs(v, -1);
    }
  if (U.first == -1) return {};
  V<int> c;
  {
    int v = U.first;
    while (true) {
      c.push_back(v);
      if (v == U.second) break;
      v = par[v];
    }
  }
  return c;
}
int N, M;
V<int> solve() {
  cin >> N >> M;
  VV<int> G(N);
  V<int> t(N);
  for (int i = 0; i < (int)(M); i++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  for (int i = 0; i < (int)(N); i++) t[i] = G[i].size() % 3;
  for (int i = 0; i < (int)(N); i++)
    if (t[i] == 0) {
      return {i};
    }
  VV<int> G2(N);
  for (int i = 0; i < (int)(N); i++)
    if (t[i] == 2) {
      for (int j : G[i])
        if (t[j] == 2) G2[i].push_back(j);
    }
  {
    auto c = getMinimalCycleUndirected(G2);
    if (!c.empty()) return c;
  }
  V<int> p1;
  for (int i = 0; i < (int)(N); i++)
    if (t[i] == 1) p1.push_back(i);
  if ((int)p1.size() >= 2) {
    int s = p1[0];
    queue<int> q;
    V<int> from(N, -1);
    q.push(s);
    from[s] = -2;
    int X = -1;
    while (!q.empty()) {
      int v = q.front();
      q.pop();
      if (v != s && t[v] == 1) {
        X = v;
        break;
      }
      for (int u : G[v])
        if (from[u] == -1) {
          from[u] = v;
          q.push(u);
        }
    }
    V<int> path;
    for (; X != -2; X = from[X]) path.push_back(X);
    return path;
  }
  int O = p1[0];
  UnionFind UF(N);
  for (int i = 0; i < (int)(N); i++)
    for (int j : G2[i]) UF.unite(i, j);
  V<bool> adj(N);
  for (int u : G[O]) adj[u] = true;
  V<int> ans = {O};
  int times = 0;
  for (int r = 0; r < (int)(N); r++)
    if (t[r] == 2 && UF.find(r) == r) {
      for (int s = 0; s < (int)(N); s++)
        if (UF.same(r, s) && adj[s]) {
          queue<int> q;
          V<int> from(N, -1);
          q.push(s);
          from[s] = -2;
          int X = -1;
          while (!q.empty()) {
            int v = q.front();
            q.pop();
            if (v != s && adj[v]) {
              X = v;
              break;
            }
            for (int u : G2[v])
              if (from[u] == -1) {
                from[u] = v;
                q.push(u);
              }
          }
          V<int> path;
          for (; X != -2; X = from[X]) path.push_back(X);
          ans.insert(ans.end(), path.begin(), path.end());
          break;
        }
      times++;
      if (times == 2) break;
    }
  return ans;
}
int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(20);
  int T;
  cin >> T;
  for (int t = 0; t < (int)(T); t++) {
    auto v = solve();
    V<bool> rm(N, true);
    for (int x : v) rm[x] = false;
    V<int> ans;
    for (int i = 0; i < (int)(N); i++)
      if (rm[i]) ans.push_back(i);
    if ((int)ans.size() == 0 || (int)ans.size() == N)
      cout << "No\n";
    else {
      cout << "Yes\n" << ans.size() << '\n';
      for (int v : ans) cout << v + 1 << " ";
      cout << '\n';
    }
  }
}
