#include <bits/stdc++.h>
using namespace std;
int n, m, x, y, col[111111], used[111111], size;
vector<int> g[111111], L, R, mat[111111];
void paint(int id, int c) {
  col[id] = c;
  c == 1 ? L.push_back(id) : R.push_back(id);
  for (vector<int>::iterator ii = g[id].begin(); ii != g[id].end(); ii++)
    if (!col[*ii]) paint(*ii, c ^ 3);
}
void construct() {
  int now = ++size, cnt = 0;
  for (vector<int>::iterator ii = L.begin(); ii != L.end(); ii++) {
    if (used[*ii]) continue;
    used[*ii] = now;
    cnt++;
    if (cnt == 3) {
      cnt = 0;
      now = ++size;
    }
  }
  for (vector<int>::iterator ii = R.begin(); ii != R.end(); ii++) {
    if (used[*ii]) continue;
    used[*ii] = now;
    cnt++;
    if (cnt == 3) {
      cnt = 0;
      now = ++size;
    }
  }
}
void print() {
  printf("YES\n");
  for (int i = 1; i <= n; i++) printf("%d ", used[i]);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for (int i = 1; i <= n; i++)
    if (!col[i]) paint(i, 1);
  if (L.size() % 3 == 0 && R.size() % 3 == 0) {
    construct();
    print();
    return 0;
  } else {
    if (L.size() % 3 == 2 && R.size() % 3 == 1) L.swap(R);
    sort(L.begin(), L.end());
    sort(R.begin(), R.end());
    for (int i = 1; i <= n; i++) sort(g[i].begin(), g[i].end());
    for (vector<int>::iterator ii = L.begin(); ii != L.end(); ii++)
      if (R.size() - g[*ii].size() > 1) {
        int cnt = 0;
        used[*ii] = 1;
        vector<int>::iterator pp = g[*ii].begin();
        for (vector<int>::iterator jj = R.begin(); jj != R.end() && cnt < 2;
             jj++) {
          while (pp != g[*ii].end() && *jj > *pp) pp++;
          if (pp != g[*ii].end() && *pp == *jj) continue;
          used[*jj] = 1;
          cnt++;
        }
        size = 1;
        construct();
        print();
        return 0;
      }
    for (vector<int>::iterator ii = R.begin(); ii != R.end(); ii++)
      if (L.size() - g[*ii].size() > 1) {
        int cnt = 0;
        vector<int>::iterator pp = g[*ii].begin();
        for (vector<int>::iterator jj = L.begin(); jj != L.end() && cnt < 2;
             jj++) {
          while (pp != g[*ii].end() && *jj > *pp) pp++;
          if (pp != g[*ii].end() && *pp == *jj) continue;
          cnt++;
          mat[*ii].push_back(*jj);
        }
      }
    for (vector<int>::iterator ii = R.begin(); ii != R.end(); ii++)
      if (mat[*ii].size() > 1)
        for (vector<int>::iterator jj = ii + 1; jj != R.end(); jj++)
          if (mat[*jj].size() > 1) {
            used[*ii] = used[mat[*ii][0]] = used[mat[*ii][1]] = 1;
            used[*jj] = used[mat[*jj][0]] = used[mat[*jj][1]] = 2;
            size = 2;
            construct();
            print();
            return 0;
          }
  }
  printf("NO\n");
}
