#include <bits/stdc++.h>
using namespace std;
vector<int> hijos[300005];
int padres[300005][2];
int color[300005];
int cnt[300005][2];
int par[300005], card[300005];
string inicial;
int n, k;
int rta = 0;
int find_par(int x) {
  if (x == par[x]) return x;
  return par[x] = find_par(par[x]);
}
void actualizar(int v, int c0, int c1) {
  v = find_par(v);
  rta -= min(cnt[v][0], cnt[v][1]);
  cnt[v][0] = min(300005, cnt[v][0] + c0);
  cnt[v][1] = min(300005, cnt[v][1] + c1);
  rta += min(cnt[v][0], cnt[v][1]);
}
void mezclar(int x, int y) {
  int a = find_par(x), b = find_par(y);
  if (a == b) return;
  if (card[a] < card[b]) swap(a, b);
  actualizar(a, cnt[b][0], cnt[b][1]);
  actualizar(b, -cnt[b][0], -cnt[b][1]);
  par[b] = a;
  card[a] += card[b];
}
void dfs(int v, int p = 0) {
  int otro;
  cnt[v][color[v]] = 1;
  for (auto x : hijos[v]) {
    if (padres[x][1] != -1) {
      otro = padres[x][0] + padres[x][1] - v;
      if (color[otro] == -1) {
        color[otro] = color[v] ^ (inicial[x] == '0');
        dfs(otro, p + 1);
      }
    }
  }
}
int main() {
  cin >> n >> k;
  cin >> inicial;
  int tam, x;
  memset(padres, -1, sizeof(padres));
  memset(color, -1, sizeof(color));
  iota(par, par + 300005, 0);
  fill(card, card + 300005, 1);
  for (int i = 0; i < k; ++i) {
    cin >> tam;
    for (int j = 0; j < tam; ++j) {
      cin >> x;
      --x;
      hijos[i].push_back(x);
      if (padres[x][0] == -1) {
        padres[x][0] = i;
      } else {
        padres[x][1] = i;
      }
    }
  }
  for (int i = 0; i < k; ++i) {
    if (color[i] == -1) {
      color[i] = 0;
      dfs(i);
    }
  }
  for (int i = 0; i < n; ++i) {
    if (padres[i][1] == -1 && padres[i][0] != -1) {
      bool compro1 = !(color[padres[i][0]] ^ (inicial[i] == '0'));
      if (compro1)
        actualizar(padres[i][0], 300005, 0);
      else
        actualizar(padres[i][0], 0, 300005);
    } else if (padres[i][0] != -1) {
      mezclar(padres[i][0], padres[i][1]);
    }
    cout << rta << endl;
  }
}
