#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> edges[100010];
int col[100010];
int nv[2];
vector<int> vs[2];
void dfs(int v, int c) {
  col[v] = c;
  nv[c]++;
  vs[c].push_back(v);
  for (int i = 0; i < (int)((edges[v]).size()); i++) {
    int u = edges[v][i];
    if (col[u] == -1) {
      dfs(u, c ^ 1);
    }
  }
}
int was[100010];
int gn = 0;
int ans[100010];
void make(int v, int f) {
  ++gn;
  ans[v] = gn;
  memset(was, 0, sizeof(was));
  for (int j = 0; j < (int)((edges[v]).size()); j++) {
    was[edges[v][j]] = 1;
  }
  int q = 2;
  for (int j = 0; q && j < (int)((vs[f ^ 1]).size()); j++) {
    int u = vs[f ^ 1][j];
    if (!was[u] && ans[u] == 0) {
      ans[u] = gn;
      q--;
    }
  }
}
int find1(int f) {
  for (int i = 0; i < (int)((vs[f]).size()); i++) {
    int v = vs[f][i];
    if ((int)((edges[v]).size()) <= (int)((vs[f ^ 1]).size()) - 2) {
      make(v, f);
      return 1;
    }
  }
  return 0;
}
int find2(int f) {
  vector<int> aa;
  for (int i = 0; (int)((aa).size()) < 2 && i < (int)((vs[f]).size()); i++) {
    int v = vs[f][i];
    if ((int)((edges[v]).size()) <= (int)((vs[f ^ 1]).size()) - 2) {
      aa.push_back(v);
      make(v, f);
    }
  }
  if ((int)((aa).size()) < 2) {
    return 0;
  }
  return 1;
}
void fill() {
  for (int f = 0; f < 2; f++) {
    int a = 0;
    for (int i = 0; i < (int)((vs[f]).size()); i++) {
      if (ans[vs[f][i]] != 0) continue;
      if (a == 3) a = 0;
      if (a == 0) gn++;
      ans[vs[f][i]] = gn;
      a++;
    }
  }
}
void out() {
  puts("YES");
  for (int i = 0; i < n; i++) {
    printf("%d%c", ans[i], " \n"[i + 1 == n]);
  }
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d %d", &a, &b), a--, b--;
    edges[a].push_back(b);
    edges[b].push_back(a);
  }
  memset(col, -1, sizeof(col));
  for (int i = 0; i < n; i++) {
    if (col[i] == -1) dfs(i, 0);
  }
  if (nv[0] % 3 == 0) {
    fill();
  } else {
    int bi;
    if (nv[0] % 3 == 1) {
      bi = 0;
    } else {
      bi = 1;
    }
    if (find1(bi)) {
      fill();
    } else {
      if (nv[0] == 1 || !find2(bi ^ 1)) {
        puts("NO");
        return 0;
      }
      fill();
    }
  }
  out();
  return 0;
}
