#include <bits/stdc++.h>
using namespace std;
set<pair<int, pair<int, int> > > AdjList[400010], G[400010];
set<pair<int, pair<int, int> > >::iterator it;
int N, M;
bool visited[400010];
vector<pair<int, int> > vp[400010];
int ans[400010];
int ins[400010];
vector<int> pivots;
inline void ReadInput(void) {
  scanf("%d", &N);
  scanf("%d", &M);
  for (int i = 1; i <= N; i++) {
    int k;
    scanf("%d", &k);
    for (int j = 1; j <= k; j++) {
      int a;
      scanf("%d", &a);
      int x = 1;
      if (a < 0) x = -1;
      vp[abs(a)].push_back(pair<int, int>(x, i));
    }
  }
}
bool flag = false;
void check(int node) {
  if (ins[node] >= 1) {
    flag = true;
    pivots.push_back(node);
  }
  visited[node] = true;
  while (G[node].begin() != G[node].end()) {
    it = G[node].begin();
    int type, v, u;
    pair<int, int> temp = it->second;
    type = temp.first;
    u = temp.second;
    v = it->first;
    if (visited[v]) {
      pivots.push_back(v);
      flag = true;
    }
    G[node].erase(pair<int, pair<int, int> >(v, pair<int, int>(type, u)));
    G[v].erase(pair<int, pair<int, int> >(node, pair<int, int>(0 - type, u)));
    check(v);
  }
}
void orient(int node) {
  while (AdjList[node].begin() != AdjList[node].end()) {
    it = AdjList[node].begin();
    int type, v, u;
    pair<int, int> temp = it->second;
    type = temp.first;
    u = temp.second;
    v = it->first;
    AdjList[node].erase(pair<int, pair<int, int> >(v, pair<int, int>(type, u)));
    AdjList[v].erase(
        pair<int, pair<int, int> >(node, pair<int, int>(0 - type, u)));
    ans[u] = type;
    if (ans[u] == -1) ans[u] = 0;
    orient(v);
  }
}
inline void solve(void) {
  for (int i = 1; i <= M; i++) {
    if (vp[i].size() == 0) continue;
    int x = vp[i][0].second;
    if (vp[i].size() == 1) {
      if (vp[i][0].first == -1) {
        ans[i] = 0;
      } else {
        ans[i] = 1;
      }
      ins[x]++;
    } else {
      if (vp[i][0].first == vp[i][1].first) {
        ins[x]++;
        ins[vp[i][1].second]++;
        if (vp[i][0].first == -1) {
          ans[i] = 0;
        } else {
          ans[i] = 1;
        }
      } else {
        sort(vp[i].begin(), vp[i].end());
        AdjList[vp[i][0].second].insert(
            pair<int, pair<int, int> >(vp[i][1].second, pair<int, int>(1, i)));
        AdjList[vp[i][1].second].insert(
            pair<int, pair<int, int> >(vp[i][0].second, pair<int, int>(-1, i)));
        G[vp[i][0].second].insert(
            pair<int, pair<int, int> >(vp[i][1].second, pair<int, int>(1, i)));
        G[vp[i][1].second].insert(
            pair<int, pair<int, int> >(vp[i][0].second, pair<int, int>(-1, i)));
      }
    }
  }
  for (int i = 1; i <= N; i++) {
    if (!visited[i]) {
      flag = false;
      check(i);
      if (!flag) {
        cout << "NO\n";
        return;
      }
    }
  }
  for (int i = 0; i < pivots.size(); i++) {
    orient(pivots[i]);
  }
  cout << "YES\n";
  for (int i = 1; i <= M; i++) {
    printf("%d", ans[i]);
  }
  printf("\n");
}
inline void Refresh(void) {}
int main() {
  ReadInput();
  solve();
  return 0;
}
