#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T>
inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
const int oo = 0x3f3f3f3f;
const int maxn = 100100;
int n, m;
vector<int> adj[maxn + 5];
bool ok = 0;
int ans[maxn + 5];
bool vis[maxn + 5];
int fa[maxn + 5];
vector<int> seq;
int dep[maxn + 5];
void dfs(int first, int f = -1) {
  if (ok) return;
  seq.push_back(first);
  fa[first] = f;
  vis[first] = 1;
  for (auto second : adj[first])
    if (second != f) {
      if (vis[second]) {
        int u = first;
        while (u != second) {
          ans[u] = 1;
          u = fa[u];
        }
        ans[second] = 1;
        ok = 1;
        return;
      } else
        dep[second] = dep[first] + 1, dfs(second, first);
      if (ok) return;
    }
}
bool in_chain[maxn + 5];
inline void work(int rt) {
  seq.clear();
  dep[rt] = 0;
  dfs(rt);
  if (ok) return;
  int cnt = 0;
  for (auto u : seq)
    if ((int((adj[u]).size())) == 1) ++cnt;
  if (cnt > 3) {
    ok = 1;
    for (auto u : seq)
      if ((int((adj[u]).size())) > 1)
        ans[u] = 2;
      else
        ans[u] = 1;
    return;
  } else if (cnt == 3) {
    sort((seq).begin(), (seq).end(),
         [&](int first, int second) { return dep[first] > dep[second]; });
    vector<vector<int> > chains;
    for (auto u : seq)
      if (!in_chain[u]) {
        vector<int> chain;
        int tmp = u;
        while (~tmp) {
          in_chain[tmp] = 1;
          chain.push_back(tmp);
          tmp = fa[tmp];
        }
        reverse((chain).begin(), (chain).end());
        chains.push_back(chain);
      }
    sort((chains).begin(), (chains).end(),
         [&](const vector<int> &a, const vector<int> &b) {
           return (int((a).size())) < (int((b).size()));
         });
    long long sz0 = (int((chains[0]).size()));
    long long sz1 = (int((chains[1]).size()));
    long long sz2 = (int((chains[2]).size()));
    if ((sz0 * sz1 + sz1 * sz2 + sz0 * sz2) > sz0 * sz1 * sz2) return;
    ok = 1;
    if (sz0 >= 3) {
      chains[0].resize(3);
      chains[1].resize(3);
      chains[2].resize(3);
      sz0 = sz1 = sz2 = 3;
    } else if (sz1 >= 4) {
      chains[1].resize(4);
      chains[2].resize(4);
      sz1 = sz2 = 4;
    } else {
      assert(sz2 >= 6);
      chains[2].resize(6);
      sz2 = 4;
    }
    int tmp = sz0 * sz1 * sz2;
    ans[rt] = tmp;
    for (auto u : chains) {
      int first = tmp * ((int((u).size())) - 1) / (int((u).size()));
      for (int i = (0), i_end_ = ((int((u).size()))); i < i_end_; ++i)
        ans[u[i]] = i * first - (i - 1) * tmp;
    }
    return;
  }
}
int main() {
  int T;
  scanf("%d", &T);
  while (T--) {
    memset(in_chain, 0, sizeof in_chain);
    ok = 0;
    scanf("%d%d", &n, &m);
    for (int i = (0), i_end_ = (n); i < i_end_; ++i) adj[i].clear();
    for (int i = (0), i_end_ = (m); i < i_end_; ++i) {
      int u, v;
      scanf("%d%d", &u, &v), --u, --v;
      adj[u].push_back(v);
      adj[v].push_back(u);
    }
    memset(vis, 0, sizeof(vis[0]) * n);
    memset(ans, 0, sizeof(ans[0]) * n);
    static int pos[maxn + 5];
    for (int i = (0), i_end_ = (n); i < i_end_; ++i) pos[i] = i;
    sort(pos, pos + n, [&](int first, int second) {
      return (int((adj[first]).size())) > (int((adj[second]).size()));
    });
    for (int i = (0), i_end_ = (n); i < i_end_; ++i)
      if (!vis[pos[i]]) {
        work(pos[i]);
        if (ok) break;
      }
    if (ok) {
      puts("YES");
      for (int i = (0), i_end_ = (n); i < i_end_; ++i) printf("%d ", ans[i]);
      printf("\n");
      int sum = 0;
      for (int i = (0), i_end_ = (n); i < i_end_; ++i) {
        for (auto j : adj[i])
          if (j < i) {
            sum += ans[i] * ans[j];
          }
        sum -= ans[i] * ans[i];
      }
    } else
      puts("NO");
  }
  return 0;
}
