#include <bits/stdc++.h>
using namespace std;
const int inf = 987654321;
const long long int INF = 123456789987654321;
int N, M;
vector<vector<int> > adj;
vector<int> color;
void dfs(int now, int col) {
  color[now] = col;
  for (int i = 0; i < adj[now].size(); i++) {
    int nxt = adj[now][i];
    if (color[nxt] != -1) continue;
    dfs(nxt, 1 - col);
  }
}
void get_color() {
  color = vector<int>(N, -1);
  for (int i = 0; i < N; i++) {
    if (color[i] == -1) dfs(i, 0);
  }
}
vector<int> lpart, rpart;
void get_bipart() {
  for (int i = 0; i < N; i++) {
    if (color[i])
      rpart.push_back(i);
    else
      lpart.push_back(i);
  }
}
vector<int> ans, chk, tmp, ltmp, rtmp;
int main() {
  scanf("%d %d", &N, &M);
  adj.resize(N);
  for (int i = 0; i < M; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    u--;
    v--;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  get_color();
  get_bipart();
  if (lpart.size() % 3 == 0) {
    ans.resize(N);
    int num = 1;
    for (int i = 0; i < lpart.size(); i += 3) {
      for (int j = 0; j < 3; j++) {
        ans[lpart[i + j]] = num;
      }
      num++;
    }
    for (int i = 0; i < rpart.size(); i += 3) {
      for (int j = 0; j < 3; j++) {
        ans[rpart[i + j]] = num;
      }
      num++;
    }
    printf("YES\n");
    for (int i = 0; i < N; i++) {
      printf("%d ", ans[i]);
    }
    return 0;
  }
  if (lpart.size() % 3 == 2) {
    ltmp.clear();
    for (int i = 0; i < lpart.size(); i++) ltmp.push_back(lpart[i]);
    rtmp.clear();
    for (int i = 0; i < rpart.size(); i++) rtmp.push_back(rpart[i]);
    lpart.clear();
    for (int i = 0; i < rtmp.size(); i++) lpart.push_back(rtmp[i]);
    rpart.clear();
    for (int i = 0; i < ltmp.size(); i++) rpart.push_back(ltmp[i]);
  }
  if (lpart.size() % 3 == 1) {
    ans.resize(N);
    int found = 0;
    for (int i = 0; i < lpart.size(); i++) {
      int now = lpart[i];
      if ((int)adj[now].size() <= (int)rpart.size() - 2) {
        ans[now] = N / 3;
        tmp.clear();
        for (int j = 0; j < lpart.size(); j++)
          if (lpart[j] != now) tmp.push_back(lpart[j]);
        lpart.clear();
        for (int j = 0; j < tmp.size(); j++) lpart.push_back(tmp[j]);
        chk = vector<int>(N, 0);
        for (int j = 0; j < adj[now].size(); j++) {
          int nxt = adj[now][j];
          chk[nxt] = 1;
        }
        int cnt = 0;
        int idx1, idx2;
        for (int j = 0; j < rpart.size(); j++) {
          if (!chk[rpart[j]]) {
            ans[rpart[j]] = N / 3;
            cnt++;
            if (cnt == 1) idx1 = j;
            if (cnt == 2) idx2 = j;
            if (cnt == 2) break;
          }
        }
        tmp.clear();
        for (int j = 0; j < rpart.size(); j++) {
          if (j != idx1 && j != idx2) tmp.push_back(rpart[j]);
        }
        rpart.clear();
        for (int j = 0; j < tmp.size(); j++) rpart.push_back(tmp[j]);
        found = 1;
        break;
      }
    }
    if (!found) {
      int piv1 = -1, piv2 = -1;
      for (int i = 0; i < rpart.size(); i++) {
        int now = rpart[i];
        if ((int)adj[now].size() <= (int)lpart.size() - 2) {
          if (piv1 == -1)
            piv1 = now;
          else {
            piv2 = now;
            break;
          }
        }
      }
      if (piv1 == -1 || piv2 == -1) {
        printf("NO");
        return 0;
      }
      ans[piv1] = N / 3;
      ans[piv2] = N / 3 - 1;
      tmp.clear();
      for (int i = 0; i < rpart.size(); i++) {
        if (rpart[i] != piv1 && rpart[i] != piv2) tmp.push_back(rpart[i]);
      }
      rpart.clear();
      for (int i = 0; i < tmp.size(); i++) rpart.push_back(tmp[i]);
      chk.clear();
      chk = vector<int>(N, 0);
      for (int i = 0; i < adj[piv1].size(); i++) {
        chk[adj[piv1][i]] = 1;
      }
      int idx1, idx2;
      int cnt = 0;
      for (int i = 0; i < lpart.size(); i++) {
        if (!chk[lpart[i]]) {
          cnt++;
          ans[lpart[i]] = N / 3;
          if (cnt == 1) idx1 = i;
          if (cnt == 2) idx2 = i;
          if (cnt == 2) break;
        }
      }
      tmp.clear();
      for (int i = 0; i < lpart.size(); i++) {
        if (i != idx1 && i != idx2) tmp.push_back(lpart[i]);
      }
      lpart.clear();
      for (int i = 0; i < tmp.size(); i++) lpart.push_back(tmp[i]);
      chk = vector<int>(N, 0);
      for (int i = 0; i < adj[piv2].size(); i++) {
        chk[adj[piv2][i]] = 1;
      }
      cnt = 0;
      for (int i = 0; i < lpart.size(); i++) {
        if (!chk[lpart[i]]) {
          cnt++;
          ans[lpart[i]] = N / 3 - 1;
          if (cnt == 1) idx1 = i;
          if (cnt == 2) idx2 = i;
          if (cnt == 2) break;
        }
      }
      tmp.clear();
      for (int i = 0; i < lpart.size(); i++) {
        if (i != idx1 && i != idx2) tmp.push_back(lpart[i]);
      }
      lpart.clear();
      for (int i = 0; i < tmp.size(); i++) lpart.push_back(tmp[i]);
    }
    int num = 1;
    for (int i = 0; i < lpart.size(); i += 3) {
      for (int j = 0; j < 3; j++) {
        ans[lpart[i + j]] = num;
      }
      num++;
    }
    for (int i = 0; i < rpart.size(); i += 3) {
      for (int j = 0; j < 3; j++) {
        ans[rpart[i + j]] = num;
      }
      num++;
    }
    printf("YES\n");
    for (int i = 0; i < N; i++) {
      printf("%d ", ans[i]);
    }
    return 0;
  }
}
