#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 100;
vector<pair<int, int> > buc[maxn];
bool vis[maxn], mark[maxn];
int result[maxn];
vector<int> side[maxn], used[maxn], sid[maxn];
vector<pair<int, int> > re[maxn];
queue<int> q;
int top = 0;
int scnt = 0;
bool debug = 0;
int stk1[maxn];
pair<int, int> stk2[maxn];
void dfs1(int u, int fa) {
  if (debug) cout << "dfs1: " << u << ' ' << fa << endl;
  for (int i = (0), iend = ((int)(side[u].size()) - 1); i <= iend; i++) {
    int v = side[u][i];
    if (v == fa || vis[v] || used[u][i]) continue;
    vis[v] = 1;
    used[u][i] = 1;
    result[re[u][i].first] = re[u][i].second;
    dfs1(v, u);
  }
}
void dfs2(int u, int fa) {
  if (vis[u]) return;
  if (debug) cout << "dfs2: " << u << ' ' << fa << endl;
  mark[u] = 1;
  stk1[++top] = u;
  for (int i = (0), iend = ((int)(side[u].size()) - 1); i <= iend; i++) {
    int v = side[u][i];
    if (sid[u][i] == fa || vis[v] || used[u][i] || vis[u]) continue;
    stk2[top] = make_pair(u, i);
    if (mark[v]) {
      vector<int> tmp;
      tmp.clear();
      int x = 0;
      do {
        x = stk1[top];
        used[stk2[top].first][stk2[top].second] = 1;
        result[re[stk2[top].first][stk2[top].second].first] =
            re[stk2[top].first][stk2[top].second].second;
        tmp.push_back(x);
        vis[x] = 1;
        top--;
      } while (x != v);
      for (int j = (0), jend = ((int)(tmp.size()) - 1); j <= jend; j++)
        dfs1(tmp[j], 0);
      return;
    } else {
      dfs2(v, sid[u][i]);
    }
  }
  top--;
}
int main() {
  ios::sync_with_stdio(0);
  int n, m;
  cin >> n >> m;
  for (int i = (1), iend = (n); i <= iend; i++) {
    int k;
    cin >> k;
    for (int j = (1), jend = (k); j <= jend; j++) {
      int val;
      cin >> val;
      buc[abs(val)].push_back(make_pair(val, i));
    }
  }
  for (int i = (1), iend = (m); i <= iend; i++) {
    if (!buc[i].size()) continue;
    if (buc[i].size() == 1) {
      int idx = buc[i][0].second;
      result[i] = (buc[i][0].first < 0) ? 0 : 1;
      vis[idx] = 1;
    } else {
      if (buc[i][0].first == buc[i][1].first) {
        result[i] = (buc[i][0].first < 0) ? 0 : 1;
        vis[buc[i][0].second] = vis[buc[i][1].second] = 1;
      } else {
        sort(buc[i].begin(), buc[i].end());
        int u = buc[i][0].second, v = buc[i][1].second;
        if (debug) cout << "ADD edge:" << u << ' ' << v << endl;
        scnt++;
        side[u].push_back(v);
        re[u].push_back(make_pair(i, 1));
        used[u].push_back(0);
        sid[u].push_back(scnt);
        side[v].push_back(u);
        re[v].push_back(make_pair(i, 0));
        used[v].push_back(0);
        sid[v].push_back(scnt);
      }
    }
  }
  for (int i = (1), iend = (n); i <= iend; i++)
    if (vis[i]) q.push(i);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    dfs1(u, 0);
  }
  for (int i = (1), iend = (n); i <= iend; i++)
    if (!vis[i] && !mark[i]) top = 0, dfs2(i, 0);
  for (int i = (1), iend = (n); i <= iend; i++)
    if (!vis[i]) {
      printf("NO\n");
      return 0;
    }
  printf("YES\n");
  for (int i = (1), iend = (m); i <= iend; i++) printf("%d", result[i]);
  return 0;
}
