#include <bits/stdc++.h>
using namespace std;
int rd() {
  int k(0), f(1);
  char c(getchar());
  while (c > '9' || c < '0') {
    if (c == '-') f = 0;
    c = getchar();
  }
  while (c >= '0' && c <= '9') k = k * 10 + c - 48, c = getchar();
  return f ? k : -k;
}
const int N = 200001;
struct E {
  int v, w, nxt;
} e[N << 1];
int n, m, _, x, en = 1, head[N], ok[N], ans[N], I[N];
vector<int> V[N];
queue<int> q;
void add(int u, int v, int w) { e[++en] = {v, w, head[u]}, head[u] = en; }
void dfs(int u) {
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].v, w = e[i].w;
    if (ans[w] < 0 && !ok[v]) ans[w] = (i & 1) ^ 1, ok[v] = 1, dfs(v);
  }
}
int search(int u) {
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].v, w = e[i].w;
    if (ans[w] < 0 && !ok[v]) {
      ans[w] = i & 1, ok[u] = 1;
      return v;
    }
  }
  return -1;
}
int main() {
  n = rd(), m = rd();
  for (int i = 1; i <= m; ++i) ans[i] = -1;
  for (int i = 1; i <= n; ++i) {
    _ = rd();
    while (_--) {
      x = rd();
      if (x > 0)
        V[x].push_back(i);
      else
        V[-x].push_back(-i);
    }
  }
  for (int i = 1; i <= m; ++i) {
    if (V[i].empty()) continue;
    sort(V[i].begin(), V[i].end());
    if (V[i].front() > 0) {
      ans[i] = 1;
      for (auto j : V[i]) ok[j] = 1;
    } else if (V[i].back() < 0) {
      ans[i] = 0;
      for (auto j : V[i]) ok[-j] = 1;
    } else {
      int u = -V[i][0], v = V[i][1];
      add(u, v, i), add(v, u, i), ++I[u], ++I[v];
    }
  }
  for (int i = 1; i <= n; ++i)
    if (ok[i]) dfs(i);
  for (int i = 1; i <= n; ++i)
    if (!ok[i] && I[i] == 1) q.push(i);
  while (!q.empty()) {
    int u = q.front(), v = search(u);
    q.pop();
    if (v < 0) {
      puts("NO");
      return 0;
    }
    if (--I[v] == 1) q.push(v);
  }
  for (int u = 1; u <= n; ++u)
    if (!ok[u]) {
      if (search(u) < 0) {
        puts("NO");
        return 0;
      }
      dfs(u);
    }
  puts("YES");
  for (int i = 1; i <= m; ++i) putchar(ans[i] == 0 ? '0' : '1');
  return 0;
}
