#include <bits/stdc++.h>
using namespace std;
template <class T>
inline bool Up(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}
template <class T>
inline bool Down(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}
const int MAXN = 100023;
int N, M, color[MAXN], ans[MAXN];
vector<int> fir[MAXN], side[2];
int tot = 2;
void BFS() {
  static int Q[MAXN];
  int head = 0, tail = 0;
  memset(color, -1, sizeof(color));
  for (int S = (1); S <= (N); ++S)
    if (color[S] == -1)
      for (color[S] = 0, Q[++tail] = S; head < tail;) {
        int x = Q[++head], y;
        side[color[x]].push_back(x);
        for (vector<int>::iterator itr(fir[x].begin()); itr != fir[x].end();
             ++itr)
          if (color[y = *itr] == -1) {
            Q[++tail] = y;
            color[y] = color[x] ^ 1;
          }
      }
}
void Print() {
  for (int c = (0); c <= (1); ++c)
    for (vector<int>::iterator itr(side[c].begin()); itr != side[c].end();
         ++itr) {
      int x = *itr;
      if (!ans[x]) ans[x] = ++tot;
    }
  puts("YES");
  for (int i = (1); i <= (N); ++i)
    printf("%d%c", ans[i] / 3, i == N ? '\n' : ' ');
}
void Paint(int x) {
  static int forbid[MAXN];
  memset(forbid, 0, sizeof(forbid));
  for (vector<int>::iterator itr(fir[x].begin()); itr != fir[x].end(); ++itr)
    forbid[*itr] = 1;
  int cnt = 0;
  ans[x] = ++tot;
  for (vector<int>::iterator itr(side[color[x] ^ 1].begin());
       itr != side[color[x] ^ 1].end(); ++itr) {
    int y = *itr;
    if (!ans[y] && !forbid[y]) {
      ans[y] = ++tot;
      if (++cnt == 2) break;
    }
  }
}
int main() {
  memset(ans, 0, sizeof(ans));
  scanf("%d %d", &N, &M);
  for (int i = (1); i <= (M); ++i) {
    int a, b;
    scanf("%d %d", &a, &b);
    fir[a].push_back(b);
    fir[b].push_back(a);
  }
  BFS();
  if (side[0].size() % 3 == 0) {
    Print();
    return 0;
  }
  if (side[0].size() % 3 == 2) {
    side[0].swap(side[1]);
    for (int i = (1); i <= (N); ++i) color[i] ^= 1;
  }
  for (vector<int>::iterator itr(side[0].begin()); itr != side[0].end();
       ++itr) {
    int x = *itr;
    if (fir[x].size() + 2 <= side[1].size()) {
      Paint(x);
      Print();
      return 0;
    }
  }
  int cnt = 0;
  for (vector<int>::iterator itr(side[1].begin()); itr != side[1].end();
       ++itr) {
    int x = *itr;
    if (fir[x].size() + 2 <= side[0].size()) {
      Paint(x);
      if (++cnt == 2) {
        Print();
        return 0;
      }
    }
  }
  puts("NO");
  return 0;
}
