#include <bits/stdc++.h>
using namespace std;
const int N = 500005;
int n, m, h[N], mn[N], par[N], t, num, op, uo, ra;
vector<int> adj[N];
set<int> answer, qtr;
bool finish, q[N], vis[N];
struct edge {
  int u, v;
} ed[N];
void output() {
  if ((int)answer.size() == n) {
    cout << "NO" << '\n';
    finish = true;
    return;
  }
  cout << "YES" << '\n' << n - answer.size() << '\n';
  for (int i = 0; i < n; i++)
    if (!answer.count(i)) cout << i + 1 << ' ';
  cout << '\n';
  finish = true;
}
void haveDeg3() {
  for (int i = 0; i < n && !finish; i++)
    if (!(adj[i].size() % 3)) answer.insert(i), output();
}
void oneEdge() {
  for (int i = 0; i < m; i++) {
    if (adj[ed[i].v].size() % 3 == 1 && adj[ed[i].u].size() % 3 == 1) {
      answer.insert(ed[i].u), answer.insert(ed[i].v), output();
      return;
    }
  }
}
void check(int x) {
  vector<int> po;
  for (auto v : adj[x])
    if (adj[v].size() % 3 == 1) {
      q[x] = true;
      po.push_back(v);
    }
  if (po.size() > 1) {
    answer.insert(po[0]), answer.insert(po[1]), answer.insert(x), output();
    return;
  }
}
void Vgraph() {
  for (int i = 0; i < n && !finish; i++)
    if (adj[i].size() % 3 == 2) check(i);
}
void findCycle(int x) {
  vis[x] = true;
  for (auto v : adj[x])
    if (adj[v].size() % 3 == 2 && v != par[x]) {
      if (!vis[v])
        h[v] = h[x] + 1, mn[v] = h[v], par[v] = x;
      else {
        if (mn[x] != h[x])
          mn[x] = max(mn[x], h[v]);
        else
          mn[x] = min(mn[x], h[v]);
      }
    }
  if (mn[x] < h[x] - 1) {
    int z = mn[x];
    while (h[x] != z) {
      answer.insert(x), x = par[x];
    }
    answer.insert(x), output();
    return;
  }
  for (auto v : adj[x])
    if (!vis[v] && !finish && adj[v].size() % 3 == 2) {
      findCycle(v);
    }
}
void cycle() {
  for (int i = 0; i < n && !finish; i++)
    if (adj[i].size() % 3 == 2 && !vis[i]) {
      findCycle(i);
    }
}
void dfs(int x) {
  if (finish) return;
  vis[x] = true;
  if (q[x]) {
    if (!qtr.count(x)) {
      for (auto v : adj[x])
        if (adj[v].size() % 3 == 1) answer.insert(v);
      while (x != op) answer.insert(x), x = par[x];
      answer.insert(op);
      output();
    } else if (par[x] != op) {
      vis[x] = false;
      return;
    }
  }
  for (auto v : adj[x])
    if (!vis[v] && adj[v].size() % 3 == 2) par[v] = x, dfs(v);
}
void dfsqt(int x) {
  if (finish) return;
  vis[x] = true;
  if (q[x] && par[x] != op) {
    num++;
    while (x != op) {
      for (auto v : adj[x]) vis[v] = true;
      answer.insert(x), x = par[x];
    }
    if (num > 1) {
      answer.insert(x);
      output();
    }
    dfsqt(op);
  }
  for (auto v : adj[x])
    if (!vis[v] && adj[v].size() % 3 == 2) par[v] = x, dfsqt(v);
}
void another() {
  num = 0;
  for (int i = 0; i < n; i++) par[i] = 0, vis[i] = false;
  for (int i = 0; i < n && !finish; i++)
    if (adj[i].size() % 3 == 1) {
      qtr.clear();
      for (auto v : adj[i]) qtr.insert(v);
      dfs(op = i);
      if (!finish) {
        for (int i = 0; i < n; i++) par[i] = 0, vis[i] = false;
        dfsqt(op);
      }
      return;
    }
}
void readInput() {
  answer.clear();
  finish = false;
  cin >> n >> m;
  for (int i = 0; i < n; i++)
    adj[i].clear(), h[i] = mn[i] = par[i] = 0, vis[i] = q[i] = false;
  for (int i = 0; i < m; i++) {
    int x, y;
    cin >> x >> y;
    ed[i].u = --x, ed[i].v = --y;
    adj[x].push_back(y);
    adj[y].push_back(x);
  }
}
void solve() {
  haveDeg3();
  if (finish) return;
  oneEdge();
  if (finish) return;
  Vgraph();
  if (finish) return;
  cycle();
  if (finish) return;
  another();
  if (finish) return;
  cout << "NO\n";
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> t;
  while (t--) readInput(), solve();
  return 0;
}
