#include <bits/stdc++.h>
int n, m, edge_number, vertex_number;
std::vector<int> *adjacent_vertexes, current, *remember;
bool ok;
int *visit, *answer, *father;
void graph_dfs(int u) {
  current.push_back(u);
  ++vertex_number;
  visit[u] = 1;
  for (int v : adjacent_vertexes[u]) {
    ++edge_number;
    if (!visit[v]) {
      graph_dfs(v);
    }
  }
  return;
}
void find_path(int u, int destination, int parent) {
  father[u] = parent;
  if (u == destination) {
    while (~u) {
      answer[u] = 2;
      u = father[u];
    }
    return;
  }
  for (int v : adjacent_vertexes[u]) {
    if (v != parent) {
      find_path(v, destination, u);
    }
  }
  return;
}
void tree_dfs(int u, int parent, int depth) {
  remember[depth].push_back(u);
  father[u] = parent;
  for (int v : adjacent_vertexes[u]) {
    if (v != parent) {
      tree_dfs(v, u, depth + 1);
    }
  }
  return;
}
int main() {
  int test_case;
  scanf("%d", &test_case);
  while (test_case--) {
    scanf("%d%d", &n, &m);
    adjacent_vertexes = new std::vector<int>[n];
    visit = new int[n];
    answer = new int[n];
    father = new int[n];
    memset(visit, 0, sizeof(int) * n);
    memset(answer, 0, sizeof(int) * n);
    for (int i = 0; i < m; ++i) {
      int u, v;
      scanf("%d%d", &u, &v);
      adjacent_vertexes[--u].push_back(--v);
      adjacent_vertexes[v].push_back(u);
    }
    ok = 0;
    for (int u = 0; u < n; ++u) {
      if (!visit[u]) {
        current.clear();
        edge_number = 0;
        vertex_number = 0;
        graph_dfs(u);
        edge_number >>= 1;
        if (edge_number >= vertex_number) {
          ok = 1;
          puts("YES");
          for (int v : current) {
            answer[v] = 1;
          }
          for (int v = 0; v < n; ++v) {
            printf("%d%c", answer[v], " \n"[v == n - 1]);
          }
          break;
        }
        std::vector<std::pair<int, int> > vertexes;
        for (int v : current) {
          vertexes.push_back(std::make_pair(adjacent_vertexes[v].size(), v));
        }
        std::sort(vertexes.begin(), vertexes.end());
        std::reverse(vertexes.begin(), vertexes.end());
        if (vertexes[0].first >= 4) {
          ok = 1;
          puts("YES");
          for (int v : current) {
            answer[v] = 1;
          }
          answer[vertexes[0].second] = 2;
          for (int v = 0; v < n; ++v) {
            printf("%d%c", answer[v], " \n"[v == n - 1]);
          }
          break;
        }
        if (vertexes[0].first == 3 && vertexes[1].first == 3) {
          ok = 1;
          puts("YES");
          for (int v : current) {
            answer[v] = 1;
          }
          find_path(vertexes[0].second, vertexes[1].second, -1);
          for (int v = 0; v < n; ++v) {
            printf("%d%c", answer[v], " \n"[v == n - 1]);
          }
          break;
        }
        if (vertexes[0].first == 3) {
          remember = new std::vector<int>[vertex_number];
          tree_dfs(vertexes[0].second, -1, 0);
          if (remember[2].size() == 3) {
            ok = 1;
            puts("YES");
            for (int v : current) {
              answer[v] = 1;
            }
            for (int v : remember[2]) {
              answer[father[v]] = 2;
            }
            answer[vertexes[0].second] = 3;
            for (int v = 0; v < n; ++v) {
              printf("%d%c", answer[v], " \n"[v == n - 1]);
            }
            break;
          }
          if (remember[3].size() == 2) {
            ok = 1;
            puts("YES");
            for (int v : current) {
              answer[v] = 1;
            }
            for (int v : remember[1]) {
              answer[v] = 2;
            }
            for (int v : remember[2]) {
              answer[v] = 2;
              answer[father[v]] = 3;
            }
            answer[vertexes[0].second] = 4;
            for (int v = 0; v < n; ++v) {
              printf("%d%c", answer[v], " \n"[v == n - 1]);
            }
            break;
          }
          if (remember[5].size() == 1 && remember[2].size() == 2) {
            ok = 1;
            puts("YES");
            for (int v : current) {
              answer[v] = 1;
            }
            for (int v : remember[1]) {
              answer[v] = 3;
            }
            for (int v : remember[2]) {
              answer[v] = 2;
              answer[father[v]] = 4;
            }
            for (int v : remember[5]) {
              answer[father[v]] = 2;
              answer[father[father[v]]] = 3;
              answer[father[father[father[v]]]] = 4;
              answer[father[father[father[father[v]]]]] = 5;
            }
            answer[vertexes[0].second] = 6;
            for (int v = 0; v < n; ++v) {
              printf("%d%c", answer[v], " \n"[v == n - 1]);
            }
            break;
          }
        }
      }
    }
    if (!ok) {
      puts("NO");
    }
  }
  return 0;
}
