#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<int> g[1000000];
int lado[1000000];
int visto[1000000];
int amount[2];
int aridad[1000000];
int sol[1000000];
int vistoelem[1000000];
int vistoelem1[1000000];
int vistoelem2[1000000];
void genera(int u, int l) {
  if (visto[u]) return;
  visto[u] = 1;
  lado[u] = l;
  amount[l]++;
  vector<int> &ar = g[u];
  for (int i = 0; i < int(ar.size()); i++) genera(ar[i], 1 - l);
}
void escribesol() {
  cout << "YES" << endl;
  for (int i = 1; i <= n; i++) {
    if (i > 1) cout << " ";
    cout << sol[i];
  }
  cout << endl;
  exit(0);
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
    aridad[u]++;
    aridad[v]++;
  }
  for (int i = 1; i <= n; i++) genera(i, 0);
  if (amount[0] % 3 == 0) {
    int k = 0;
    for (int i = 1; i <= n; i++) {
      if (lado[i] == 0) {
        sol[i] = k / 3 + 1;
        k++;
      }
    }
    for (int i = 1; i <= n; i++) {
      if (lado[i] == 1) {
        sol[i] = k / 3 + 1;
        k++;
      }
    }
    escribesol();
  }
  if (amount[0] % 3 == 2) {
    for (int i = 1; i <= n; i++) lado[i] = 1 - lado[i];
    swap(amount[0], amount[1]);
  }
  {
    int elem = 0;
    for (int i = 1; i <= n and elem == 0; i++)
      if (lado[i] == 0 and aridad[i] <= amount[1] - 2) elem = i;
    if (elem) {
      vector<int> &ar = g[elem];
      for (int i = 0; i < int(ar.size()); i++) vistoelem[ar[i]] = 1;
      int e1 = 0, e2 = 0;
      for (int i = 1; i <= n and e2 == 0; i++) {
        if (lado[i] == 1 and not vistoelem[i]) {
          if (e1 == 0)
            e1 = i;
          else
            e2 = i;
        }
      }
      sol[elem] = sol[e1] = sol[e2] = 1;
      int k = 3;
      for (int i = 1; i <= n; i++) {
        if (i != elem and lado[i] == 0) {
          sol[i] = k / 3 + 1;
          k++;
        }
      }
      for (int i = 1; i <= n; i++) {
        if (i != e1 and i != e2 and lado[i] == 1) {
          sol[i] = k / 3 + 1;
          k++;
        }
      }
      escribesol();
    }
  }
  int elem1 = 0, elem2 = 0;
  for (int i = 1; i <= n and elem2 == 0; i++) {
    if (lado[i] == 1 and aridad[i] <= amount[0] - 2) {
      if (elem1 == 0)
        elem1 = i;
      else
        elem2 = i;
    }
  }
  if (elem2) {
    {
      vector<int> &ar = g[elem1];
      for (int i = 0; i < int(ar.size()); i++) vistoelem1[ar[i]] = 1;
    }
    int e11 = 0, e12 = 0;
    for (int i = 1; i <= n and e12 == 0; i++) {
      if (lado[i] == 0 and not vistoelem1[i]) {
        if (e11 == 0)
          e11 = i;
        else
          e12 = i;
      }
    }
    {
      vector<int> &ar = g[elem2];
      for (int i = 0; i < int(ar.size()); i++) vistoelem2[ar[i]] = 1;
    }
    int e21 = 0, e22 = 0;
    for (int i = 1; i <= n and e22 == 0; i++) {
      if (lado[i] == 0 and not vistoelem2[i]) {
        if (e21 == 0)
          e21 = i;
        else
          e22 = i;
      }
    }
    sol[elem1] = sol[e11] = sol[e12] = 1;
    sol[elem2] = sol[e21] = sol[e22] = 2;
    int k = 6;
    for (int i = 1; i <= n; i++) {
      if (i != elem1 and i != elem2 and lado[i] == 1) {
        sol[i] = k / 3 + 1;
        k++;
      }
    }
    for (int i = 1; i <= n; i++) {
      if (i != e11 and i != e12 and i != e21 and i != e22 and lado[i] == 0) {
        sol[i] = k / 3 + 1;
        k++;
      }
    }
    escribesol();
  }
  cout << "NO" << endl;
}
