#include <bits/stdc++.h>
using namespace std;
const int N = 2 * 1e5;
vector<int> E[N];
int cnt[2], color[N], ans[N];
void bfs(int n, int start) {
  queue<int> q;
  q.push(start);
  color[start] = 0;
  cnt[0]++;
  while (!q.empty()) {
    int t = q.front();
    q.pop();
    for (int ind = 0; ind < E[t].size(); ind++) {
      int to = E[t][ind];
      if (color[to] == -1) {
        color[to] = color[t] ^ 1;
        cnt[color[to]]++;
        q.push(to);
      }
    }
  }
}
void case0(int n) {
  int left = 1, right = n / 3;
  if (find(ans, ans + N, 1) != ans + N) left++;
  if (find(ans, ans + N, 2) != ans + N) left++;
  cnt[0] = cnt[1] = 0;
  for (int i = 0; i < n; i++) {
    if (ans[i] != 0) continue;
    if (color[i] == 0) {
      ans[i] = left;
      cnt[0]++;
      if (cnt[0] == 3) {
        left++;
        cnt[0] = 0;
      }
    } else {
      ans[i] = right;
      cnt[1]++;
      if (cnt[1] == 3) {
        right--;
        cnt[1] = 0;
      }
    }
  }
}
bool case1(int n) {
  for (int i = 0; i < n; i++) {
    if (color[i]) continue;
    if (cnt[1] - E[i].size() < 2) continue;
    vector<char> mark(n, 0);
    for (int ind = 0; ind < E[i].size(); ind++) {
      int to = E[i][ind];
      mark[to] = 1;
    }
    int ver[2] = {}, p = 0;
    for (int j = 0; j < n && p < 2; j++) {
      if (color[j] && !mark[j]) ver[p++] = j;
    }
    ans[i] = 1;
    ans[ver[0]] = 1;
    ans[ver[1]] = 1;
    return true;
  }
  return false;
}
bool case2(int n) {
  vector<int> left_ver[2];
  int cnt_left = 0;
  for (int i = 0; i < n && cnt_left < 2; i++) {
    if (color[i] == 0 || cnt[0] - E[i].size() < 2) continue;
    vector<char> mark(n, 0);
    for (int j = 0; j < E[i].size(); j++) {
      int to = E[i][j];
      mark[to] = 1;
    }
    int ver[2] = {}, p = 0;
    for (int j = 0; j < n && p < 2; j++) {
      if (color[j] == 0 && mark[j] == 0) {
        ver[p++] = j;
      }
    }
    left_ver[cnt_left++] = {ver[0], ver[1], i};
  }
  if (cnt_left == 2) {
    for (int i = 0; i < 2; i++)
      for (int j = 0; j < 3; j++) ans[left_ver[i][j]] = i + 1;
    return true;
  }
  return false;
}
int main() {
  ios_base::sync_with_stdio(false);
  int n, m;
  scanf("%d %d", &n, &m);
  fill(color, color + N, -1);
  for (int i = 0; i < m; i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    --a;
    --b;
    E[a].push_back(b);
    E[b].push_back(a);
  }
  for (int i = 0; i < n; i++) {
    if (color[i] == -1) {
      bfs(n, i);
    }
  }
  if (cnt[1] % 3 == 1) {
    swap(cnt[0], cnt[1]);
    for (int i = 0; i < n; i++) color[i] ^= 1;
  }
  cerr << cnt[0] << " " << cnt[1] << "\n";
  if (cnt[0] % 3 == 0 && cnt[1] % 3 == 0) {
    case0(n);
  } else if (case1(n)) {
    case0(n);
  } else if (case2(n)) {
    case0(n);
  } else {
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for (int i = 0; i < n; i++) {
    printf("%d ", ans[i]);
  }
}
