#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e6 + 12;
int n, m, ac[maxn][2][2], tmp, dp[maxn];
struct edge {
  int id, u;
};
struct save {
  int in;
  bool a;
};
vector<int> a[maxn];
vector<save> acv[maxn];
vector<edge> g[maxn];
queue<int> gav;
char mark[maxn];
bool ans[maxn], done[maxn];
void out() {
  for (int i = 0; i < n; i++, cout << '\n') {
    cout << i << ':';
    for (int j = 0; j < g[i].size(); j++)
      cout << g[i][j].id << "=>" << g[i][j].u << ' ';
  }
}
void er(vector<save> &vec, int v, bool b) {
  for (int i = 0; i < vec.size(); i++)
    if (vec[i].in == v && vec[i].a == b) {
      vec.erase(vec.begin() + i);
      return;
    }
}
int getatcycle(int v, int parid = -1) {
  mark[v] = 1;
  for (auto &e : g[v])
    if (e.id != parid) {
      if (mark[e.u]) return e.u;
      tmp = getatcycle(e.u, e.id);
      if (tmp != -404) return tmp;
    }
  return -404;
}
void make(int v, int d = 0, int parid = -1) {
  mark[v] = 2;
  dp[v] = d;
  for (auto &e : g[v])
    if (e.id != parid)
      if (mark[e.u] != 2)
        ans[e.id] = acv[e.id][0].in == e.u ? acv[e.id][0].a : acv[e.id][1].a,
        make(e.u, d + 1, e.id);
      else if (dp[e.u] <= d)
        ans[e.id] = acv[e.id][0].in == e.u ? acv[e.id][0].a : acv[e.id][1].a;
}
void atair(int v) {
  if (!acv[v].size()) {
    done[v] = 1;
    return;
  }
  if (acv[v].size() == 1) {
    ans[v] = acv[v][0].a;
    done[v] = 1;
    gav.push(acv[v][0].in);
    return;
  }
  if (acv[v][0].a == acv[v][1].a) {
    ans[v] = acv[v][0].a;
    done[v] = 1;
    gav.push(acv[v][0].in);
    gav.push(acv[v][1].in);
  }
  if (acv[v][0].in == acv[v][1].in) {
    ans[v] = acv[v][0].a;
    done[v] = 1;
    gav.push(acv[v][0].in);
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++) {
    int nu;
    cin >> nu;
    while (nu--) {
      int x;
      cin >> x;
      a[i].push_back(x);
      ac[abs(x)][x < 0][ac[abs(x)][x < 0][0] >= 0] = i;
      acv[abs(x)].push_back({i, x > 0});
    }
  }
  for (int i = 1; i <= m; i++) atair(i);
  while (gav.size()) {
    int v = gav.front();
    gav.pop();
    if (mark[v]) continue;
    mark[v] = 1;
    for (auto &u : a[v])
      if (!done[abs(u)]) er(acv[abs(u)], v, u >= 0), atair(abs(u));
  }
  for (int i = 1; i <= m; i++)
    if (!done[i])
      g[acv[i][0].in].push_back({i, acv[i][1].in}),
          g[acv[i][1].in].push_back({i, acv[i][0].in});
  for (int i = 0; i < n; i++)
    if (!mark[i]) {
      tmp = getatcycle(i);
      if (tmp == -404)
        cout << "NO\n", exit(0);
      else
        make(tmp);
    }
  cout << "YES\n";
  for_each(ans + 1, ans + m + 1, [](bool &x) { cout << x; });
  cout << '\n';
  return 0;
}
