#include <bits/stdc++.h>
using namespace std;
const long double eps = 1e-9;
const int inf = (1 << 30) - 1;
const long long inf64 = ((long long)1 << 62) - 1;
const long double pi = acos(-1);
template <class T>
T sqr(T x) {
  return x * x;
}
template <class T>
T abs(T x) {
  return x < 0 ? -x : x;
}
const int MAXN = 250 * 1000;
vector<pair<int, int> > perem[MAXN];
vector<pair<int, pair<int, int> > > adj[MAXN];
vector<int> start_from;
int ans[MAXN], rk[MAXN], p[MAXN];
bool good[MAXN], used[MAXN], good_color[MAXN];
int get_color(int v) {
  if (p[v] == v) {
    return v;
  }
  return p[v] = get_color(p[v]);
}
bool unite_color(int v1, int v2) {
  v1 = get_color(v1);
  v2 = get_color(v2);
  if (v1 == v2) {
    return false;
  }
  if (rk[v1] < rk[v2]) {
    swap(v1, v2);
  }
  p[v2] = v1;
  if (rk[v1] == rk[v2]) {
    rk[v1]++;
  }
  return true;
}
void dfs(int v) {
  used[v] = true;
  for (int i = 0; i < ((int)(adj[v]).size()); ++i) {
    if (!used[adj[v][i].first]) {
      ans[adj[v][i].second.first] = adj[v][i].second.second;
      dfs(adj[v][i].first);
    }
  }
}
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  int tn, tmp;
  for (int i = 0; i < n; ++i) {
    scanf("%d", &tn);
    for (int j = 0; j < tn; ++j) {
      scanf("%d", &tmp);
      if (tmp > 0) {
        perem[tmp - 1].push_back(make_pair(i, 1));
      } else {
        perem[-tmp - 1].push_back(make_pair(i, 0));
      }
    }
  }
  for (int i = 0; i < m; ++i) {
    ans[i] = -1;
  }
  for (int i = 0; i < n; ++i) {
    p[i] = i;
    rk[i] = 0;
  }
  for (int i = 0; i < m; ++i) {
    if (((int)(perem[i]).size()) == 0) {
      ans[i] = 0;
      continue;
    }
    if (((int)(perem[i]).size()) == 1 ||
        perem[i][0].first == perem[i][1].first) {
      good[perem[i][0].first] = true;
      ans[i] = perem[i][0].second;
      continue;
    }
    if (perem[i][0].second == perem[i][1].second) {
      good[perem[i][0].first] = true;
      good[perem[i][1].first] = true;
      ans[i] = perem[i][0].second;
      continue;
    }
    if (unite_color(perem[i][0].first, perem[i][1].first)) {
      adj[perem[i][0].first].push_back(
          make_pair(perem[i][1].first, make_pair(i, perem[i][1].second)));
      adj[perem[i][1].first].push_back(
          make_pair(perem[i][0].first, make_pair(i, perem[i][0].second)));
    } else {
      good[perem[i][0].first] = true;
      ans[i] = perem[i][0].second;
    }
  }
  for (int i = 0; i < n; ++i) {
    if (good[i]) {
      good_color[get_color(i)] = true;
    }
  }
  bool key = true;
  for (int i = 0; i < n; ++i) {
    if (!good_color[get_color(i)]) {
      key = false;
      break;
    }
  }
  if (!key) {
    printf("NO\n");
    return 0;
  }
  for (int i = 0; i < n; ++i) {
    if (good[i] && !used[i]) {
      dfs(i);
    }
  }
  for (int i = 0; i < m; ++i) {
    if (ans[i] == -1) {
      ans[i] = 0;
    }
  }
  printf("YES\n");
  for (int i = 0; i < m; ++i) {
    printf("%d", ans[i]);
  }
  printf("\n");
  return 0;
}
