#include <bits/stdc++.h>
using namespace std;
template <typename T, typename U>
inline void smin(T &a, U b) {
  if (a > b) a = b;
}
template <typename T, typename U>
inline void smax(T &a, U b) {
  if (a < b) a = b;
}
int ans[200200], vst[200200], pos[200200], neg[200200];
set<int> s[200200];
priority_queue<pair<int, int> > q;
int main() {
  int n, m, k, first;
  cin >> n >> m;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &k);
    q.push(pair<int, int>(-k, i));
    while (k--) {
      scanf("%d", &first);
      s[i].insert(first);
      if (first > 0)
        pos[first] = i;
      else
        neg[-first] = i;
    }
  }
  for (int i = 1; i <= m; i++) {
    if (!pos[i] || !neg[i]) {
      int u = pos[i] ? pos[i] : neg[i];
      vst[u] = 1;
      ans[i] = (pos[i] == u);
    }
  }
  while (!q.empty()) {
    int u = q.top().second;
    q.pop();
    if (vst[u]) continue;
    vst[u] = 1;
    if (s[u].empty()) {
      puts("NO");
      return 0;
    }
    first = *s[u].begin();
    if (first > 0) {
      ans[first] = 1;
      if (neg[first]) {
        s[neg[first]].erase(-first);
        q.push(pair<int, int>(-s[neg[first]].size(), neg[first]));
      }
    } else {
      first = -first;
      ans[first] = 0;
      if (pos[first]) {
        s[pos[first]].erase(first);
        q.push(pair<int, int>(-s[pos[first]].size(), pos[first]));
      }
    }
  }
  puts("YES");
  for (int i = 1; i <= m; i++) putchar(ans[i] + '0');
  return 0;
}
