#include <bits/stdc++.h>
const int N = 100010;
const int inf = 0x3f3f3f3f;
using namespace std;
int n, m;
vector<int> vt[N];
int res[N], l, r, col[N], lz, rz, vis[N], lcnt, rcnt;
void dfs(int u, int c) {
  col[u] = c;
  vis[u] = 1;
  int sz = vt[u].size();
  for (int i = 0; i < sz; i++)
    if (!vis[vt[u][i]]) dfs(vt[u][i], c ^ 1);
  return;
}
bool other[N];
bool solve(int s, int &cnt) {
  int sd = s, sz = rz;
  if (s) sz = lz;
  memset(other, 0, sizeof(other));
  for (int i = 1; i <= n; ++i)
    if (col[i] == sd && vt[i].size() + 2 <= sz) {
      for (int j = 0; j < vt[i].size(); ++j) other[vt[i][j]] = 1;
      int n1 = -1, n2 = -1;
      for (int j = 1; j <= n; ++j)
        if (!other[j] && col[i] != col[j] && col[j] != -1)
          if (n1 != -1)
            n2 = j;
          else
            n1 = j;
      col[i] = -1;
      col[n1] = -1;
      col[n2] = -1;
      res[i] = cnt;
      res[n1] = cnt;
      res[n2] = cnt;
      cnt++;
      return 1;
    }
  return 0;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    vt[a].push_back(b);
    vt[b].push_back(a);
  }
  for (int i = 1; i <= n; i++)
    if (!vis[i]) dfs(i, 0);
  for (int i = 1; i <= n; i++)
    if (col[i])
      rz++;
    else
      lz++;
  if (lz % 3 == 2) {
    swap(l, r);
    swap(rz, lz);
    for (int i = 1; i <= n; i++) col[i] = col[i] ^ 1;
  }
  lcnt = 1;
  rcnt = n / 3;
  if (lz % 3 == 1) {
    if (!solve(0, lcnt)) {
      if (lz >= 4 && solve(1, lcnt) && solve(1, lcnt))
        ;
      else {
        puts("NO");
        return 0;
      }
    }
  }
  puts("YES");
  for (int i = 1; i <= n; i++) {
    if (col[i] == 1) {
      res[i] = rcnt;
      r++;
      if (r == 3) r = 0, rcnt--;
    } else if (col[i] == 0) {
      res[i] = lcnt;
      l++;
      if (l == 3) l = 0, lcnt++;
    }
  }
  for (int i = 1; i <= n; i++) printf("%d ", res[i]);
  puts("");
  return 0;
}
