#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:100000000000000")
using namespace std;
const long long int INF = 2e9;
vector<int> g[3000000];
int is[3000000];
int used[3000000];
vector<int> in[2];
void dfs(int id, int dole) {
  used[id] = dole;
  in[dole].push_back(id);
  for (int i = 0; i < ((int)(g[id]).size()); i++) {
    int to = g[id][i];
    if (used[to] == -1) dfs(to, 1 - dole);
  }
}
int main() {
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < (m); i++) {
    int a, b;
    scanf("%d%d", &a, &b);
    a--;
    b--;
    g[a].push_back(b);
    g[b].push_back(a);
  }
  for (int i = 0; i < (n); i++) sort(g[i].begin(), g[i].end());
  memset(used, -1, sizeof used);
  for (int i = 0; i < (n); i++) {
    if (used[i] == -1) dfs(i, 0);
  }
  for (int j = 0; j < (2); j++) sort(in[j].begin(), in[j].end());
  int color = 0;
  memset(is, -1, sizeof is);
  if ((int)(in[0]).size() % 3 != 0) {
    int fr = 0;
    if ((int)(in[0]).size() % 3 == 2) fr = 1;
    bool find = false;
    for (int i = 0; i < ((int)(in[fr]).size()); i++) {
      int id = in[fr][i];
      if ((int)(in[1 - fr]).size() - (int)(g[id]).size() >= 2) {
        find = true;
        is[id] = color;
        map<int, int> temp;
        for (int j = 0; j < ((int)(g[id]).size()); j++) {
          temp[g[id][j]]++;
        }
        int ost = 2;
        for (int j = 0; j < ((int)(in[1 - fr]).size()); j++) {
          if (!ost) break;
          int to = in[1 - fr][j];
          if (!temp.count(to)) {
            is[to] = color;
            ost--;
          }
        }
        color++;
        break;
      }
    }
    if (!find) {
      map<int, vector<int> > temp;
      for (int i = 0; i < ((int)(in[fr]).size()); i++) {
        int id = in[fr][i];
        int ptr = 0;
        bool yes = false;
        for (int j = 0; j < ((int)(g[id]).size()); j++) {
          int to = g[id][j];
          if (to != in[1 - fr][ptr]) {
            temp[in[1 - fr][ptr]].push_back(id);
            yes = true;
            break;
          }
          ptr++;
        }
        if (!yes && ptr < (int)(in[1 - fr]).size()) {
          temp[in[1 - fr][ptr]].push_back(id);
        }
      }
      for (auto it : temp) {
        if ((int)(it.second).size() >= 2) {
          is[it.first] = color;
          for (int j = 0; j < (2); j++) {
            is[it.second[j]] = color;
          }
          color++;
        }
        if (color == 2) break;
      }
      find = (color == 2);
    }
    if (!find) {
      cout << "NO";
      return 0;
    }
  }
  int ptr = 0;
  for (int i = 0; i < ((int)(in[0]).size()); i++) {
    if (is[in[0][i]] != -1) continue;
    is[in[0][i]] = color;
    if (ptr == 2) {
      color++;
    }
    ptr = (ptr + 1) % 3;
  }
  for (int i = 0; i < ((int)(in[1]).size()); i++) {
    if (is[in[1][i]] != -1) continue;
    is[in[1][i]] = color;
    if (ptr == 2) {
      color++;
    }
    ptr = (ptr + 1) % 3;
  }
  cout << "YES" << endl;
  for (int i = 0; i < (n); i++) {
    printf("%d ", is[i] + 1);
  }
}
