#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline bool chkmin(T &a, const T &b) {
  return a > b ? a = b, 1 : 0;
}
template <typename T>
inline bool chkmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
const int oo = 0x3f3f3f3f;
template <typename T>
T &Read(T &first) {
  static char c;
  while (!isdigit(c = getchar()))
    ;
  first = c - '0';
  while (isdigit(c = getchar())) (first *= 10) += c - '0';
  return first;
}
const int max0 = 1000000;
struct edge {
  int id, nxt;
  edge() {}
  edge(const int &_id, const int &_nxt) : id(_id), nxt(_nxt) {}
};
int en = 0;
edge e[max0 + 5];
int st[max0 + 5];
inline void add_edge(const int &first, const int &second) {
  e[en] = edge(second, st[first]), st[first] = en++;
}
int n, m;
int p[max0 + 5][2];
int ans[max0 + 5];
bool ok[max0 + 5];
inline void init() {
  memset(p, -1, sizeof p);
  memset(st, -1, sizeof st), en = 0;
  scanf("%d%d", &m, &n);
  for (int i = (0), _end_ = (m); i < _end_; ++i) {
    int first;
    scanf("%d", &first);
    for (int j = (0), _end_ = (first); j < _end_; ++j) {
      int second;
      scanf("%d", &second);
      int &tmp = p[abs(second) - 1][second > 0];
      if (tmp == -1)
        tmp = i;
      else
        ok[tmp] = ok[i] = 1, ans[abs(second) - 1] = second > 0;
    }
  }
  for (int i = (0), _end_ = (n); i < _end_; ++i)
    if (p[i][0] != -1 && p[i][1] != -1)
      add_edge(p[i][1], p[i][0]), add_edge(p[i][0], p[i][1]);
    else {
      for (int j = (0), _end_ = (2); j < _end_; ++j)
        if (p[i][j] != -1) ok[p[i][j]] = 1, ans[i] = j;
      add_edge(m, m), add_edge(m, m);
    }
}
int vis[max0 + 5];
int dfs(const int &first, const int &fa = -1) {
  vis[first] = 1;
  for (int i = st[first]; i != -1; i = e[i].nxt) {
    if (i >> 1 == fa) continue;
    const int &second = e[i].id;
    if (vis[second]) return second;
    if (ok[second]) return second;
    int tmp = dfs(second, i >> 1);
    if (tmp != -1) return tmp;
  }
  return -1;
}
int rt;
void dfs0(const int &first, const int &fa = -1) {
  vis[first] = 2;
  for (int i = st[first]; i != -1; i = e[i].nxt) {
    if (i >> 1 == fa) continue;
    const int &second = e[i].id;
    if (second == rt) ans[i >> 1] = i & 1;
    if (vis[second] == 2) continue;
    ans[i >> 1] = i & 1;
    dfs0(second, i >> 1);
  }
}
int main() {
  init();
  for (int i = (0), _end_ = (m); i < _end_; ++i)
    if (!ok[i] && !vis[i]) {
      int first = dfs(i);
      if (first == -1)
        printf("NO\n"), exit(0);
      else {
        rt = first;
        dfs0(first);
      }
    }
  printf("YES\n");
  for (int i = (0), _end_ = (n); i < _end_; ++i) printf("%d", ans[i]);
  return 0;
}
