#include <bits/stdc++.h>
using namespace std;
int n, m, a, b, wsk, ile;
vector<int> v[((int)(1e5) + 5)];
vector<int> zbior[2];
bitset<((int)(1e5) + 5)> odw, sasiad;
int odp[((int)(1e5) + 5)];
int inf = (1e9) + 2137;
void wypisz_wejscie() {
  fprintf(stdout, "%d %d\n", n, m);
  for (int i = 1; i <= n; ++i) {
    int l = v[i].size();
    for (int j = 0; j < l; ++j) {
      if (i < v[i][j]) {
        fprintf(stdout, "%d %d\n", i, v[i][j]);
      }
    }
  }
}
bool comp(int a, int b) {
  if (v[a].size() < v[b].size()) {
    return true;
  }
  if (v[a].size() > v[b].size()) {
    return false;
  }
  if (a < b) {
    return true;
  }
  return false;
}
void dfs(int x, int y) {
  odw[x] = true;
  int l = v[x].size();
  zbior[y].emplace_back(x);
  for (int i = 0; i < l; ++i) {
    if (!odw[v[x][i]]) {
      dfs(v[x][i], y ^ 1);
    }
  }
}
void ustaw(int x) {
  odp[x] = wsk;
  ++ile;
  if (ile == 3) {
    ile = 0;
    ++wsk;
  }
}
int deg(int x) { return v[x].size(); }
void ustaw_sasiadow(int x) {
  sasiad.reset();
  int l = v[x].size();
  for (int i = 0; i < l; ++i) {
    sasiad[v[x][i]] = true;
  }
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= m; ++i) {
    scanf("%d%d", &a, &b);
    v[a].emplace_back(b);
    v[b].emplace_back(a);
  }
  for (int i = 1; i <= n; ++i) {
    if (!odw[i]) {
      dfs(i, 0);
    }
  }
  odw.reset();
  wsk = 1;
  if (zbior[0].size() % 3) {
    if (zbior[0].size() % 3 == 2) {
      swap(zbior[0], zbior[1]);
    }
    sort(zbior[0].begin(), zbior[0].end(), comp);
    sort(zbior[1].begin(), zbior[1].end(), comp);
    bool ok = false;
    if (zbior[0].size() >= 1 && zbior[1].size() >= 2) {
      if (deg(zbior[0][0]) <= zbior[1].size() - 2) {
        ok = true;
        ustaw(zbior[0][0]);
        ustaw_sasiadow(zbior[0][0]);
        int l = zbior[1].size();
        for (int i = 0; i < l; ++i) {
          if (!sasiad[zbior[1][i]]) {
            ustaw(zbior[1][i]);
            if (!ile) {
              break;
            }
          }
        }
      }
    }
    if (!ok && zbior[0].size() >= 4 && zbior[1].size() >= 2) {
      if (deg(zbior[1][0]) <= zbior[0].size() - 2 &&
          deg(zbior[1][1]) <= zbior[0].size() - 2) {
        ok = true;
        ustaw_sasiadow(zbior[1][0]);
        ustaw(zbior[1][0]);
        int l = zbior[0].size();
        for (int i = 0; i < l; ++i) {
          if (!sasiad[zbior[0][i]]) {
            ustaw(zbior[0][i]);
            if (!ile) {
              break;
            }
          }
        }
        ustaw_sasiadow(zbior[1][1]);
        ustaw(zbior[1][1]);
        for (int i = 0; i < l; ++i) {
          if (odp[zbior[0][i]]) {
            continue;
          }
          if (!sasiad[zbior[0][i]]) {
            ustaw(zbior[0][i]);
            if (!ile) {
              break;
            }
          }
        }
      }
    }
    if (!ok) {
      fprintf(stdout, "NO\n");
      return 0;
    }
  }
  int l = zbior[0].size();
  for (int i = 0; i < l; ++i) {
    if (odp[zbior[0][i]]) {
      continue;
    }
    ustaw(zbior[0][i]);
  }
  l = zbior[1].size();
  for (int i = 0; i < l; ++i) {
    if (odp[zbior[1][i]]) {
      continue;
    }
    ustaw(zbior[1][i]);
  }
  fprintf(stdout, "YES\n");
  for (int i = 1; i <= n; ++i) {
    fprintf(stdout, "%d ", odp[i]);
  }
  return 0;
}
