#include <bits/stdc++.h>
using namespace std;
int N, s[100050], cnt;
bool mark[100050 * 2];
vector<int> g[100050 * 2];
void init(int n) {
  N = n * 2 + 10;
  for (int i = 0; i < N; i++) g[i].clear(), mark[i] = false;
}
void add_edge(int x, int y) {
  g[x].push_back(y);
  g[y ^ 1].push_back(x ^ 1);
}
void add_true(int x) {
  x *= 2;
  add_edge(x ^ 1, x);
}
void add_false(int x) {
  x *= 2;
  add_edge(x, x ^ 1);
}
void add_or(int x, int y) {
  x *= 2;
  y *= 2;
  add_edge(x ^ 1, y);
}
void add_and(int x, int y) {
  add_true(x);
  add_true(y);
}
void add_same(int x, int y) {
  x *= 2;
  y *= 2;
  add_edge(x, y);
  add_edge(y, x);
}
void add_diff(int x, int y) {
  x *= 2;
  y *= 2;
  add_edge(x, y ^ 1);
  add_edge(x ^ 1, y);
}
bool dfs(int u) {
  if (mark[u]) return true;
  if (mark[u ^ 1]) return false;
  mark[u] = true;
  s[cnt++] = u;
  for (auto v : g[u])
    if (!dfs(v)) return false;
  return true;
}
bool solve() {
  memset(mark, 0, sizeof mark);
  for (int i = 0; i < N; i += 2)
    if (!mark[i] && !mark[i + 1]) {
      cnt = 0;
      if (!dfs(i)) {
        while (cnt > 0) mark[s[--cnt]] = false;
        if (!dfs(i + 1)) return false;
      }
    }
  return true;
}
int r[100050];
vector<int> sw[100050];
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%d", r + i);
  for (int i = 1; i <= m; i++) {
    int cnt;
    scanf("%d", &cnt);
    while (cnt--) {
      int k;
      scanf("%d", &k);
      sw[k].push_back(i);
    }
  }
  init(m);
  for (int i = 1; i <= n; i++) {
    if (!r[i])
      add_diff(sw[i][0], sw[i][1]);
    else
      add_same(sw[i][0], sw[i][1]);
  }
  puts(solve() ? "YES" : "NO");
  return 0;
}
