#include <bits/stdc++.h>
using namespace std;
template <class T1, class T2>
ostream& operator<<(ostream& s, pair<T1, T2> P) {
  return s << '<' << P.first << ", " << P.second << '>';
}
template <class T>
ostream& operator<<(ostream& s, vector<T> P) {
  for (int i = 0; i < P.size(); ++i) {
    if (i > 0) {
      s << " ";
    }
    s << P[i];
  }
  return s;
}
template <class T>
ostream& operator<<(ostream& s, vector<vector<T>> P) {
  for (int i = 0; i < P.size(); ++i) {
    s << endl << P[i];
  }
  return s << endl;
}
template <class T1, class T2>
ostream& operator<<(ostream& s, map<T1, T2> P) {
  for (auto it : P) {
    s << "<" << it.first << "->" << it.second << "> ";
  }
  return s << endl;
}
const int INF = 1 << 29;
struct UnionFind {
  int s, t;
  vector<int> par;
  vector<int> onum;
  UnionFind(int n)
      : s(n), t(n * 2 + 1), par(n * 2 + 2, -1), onum(n * 2 + 2, 0) {
    for (int i = n + 1; i < n * 2 + 1; ++i) onum[i] = 1;
    onum[t] = INF;
  }
  int root(int x) {
    if (par[x] < 0)
      return x;
    else
      return par[x] = root(par[x]);
  }
  bool issame(int x, int y) { return root(x) == root(y); }
  bool merge(int x, int y) {
    x = root(x);
    y = root(y);
    if (x == y) return false;
    if (par[x] > par[y]) swap(x, y);
    onum[x] += onum[y];
    par[x] += par[y];
    par[y] = x;
    return true;
  }
  int size(int x) { return -par[root(x)]; }
  int get_onum(int x) { return onum[root(x)]; }
};
ostream& operator<<(ostream& s, UnionFind uf) {
  map<int, vector<int>> res;
  cout << endl;
  for (int i = 0; i < uf.par.size(); ++i) {
    int r = uf.root(i);
    res[r].push_back(i);
    if (r == i) {
      cout << "root " << r << ": " << uf.onum[r] << endl;
    }
  }
  int iter = 0;
  for (auto it : res) {
    s << (iter++) << "-th group: ";
    for (int j = 0; j < (int)it.second.size(); ++j) {
      s << it.second[j] << ", ";
    }
    s << endl;
  }
  return s << endl;
}
int N, K;
string S;
vector<vector<int>> cls;
void solve() {
  long long res = 0;
  UnionFind uf(K);
  auto get = [&](int x) {
    x %= K + 1;
    return min(uf.get_onum(x), uf.get_onum(x + K + 1));
  };
  auto merge = [&](int x, int y) {
    if (uf.issame(x, y)) return;
    int before_cost = get(x) + get(y);
    uf.merge(x, y);
    if (x < K + 1)
      x += K + 1;
    else
      x -= K + 1;
    if (y < K + 1)
      y += K + 1;
    else
      y -= K + 1;
    uf.merge(x, y);
    int after_cost = get(x);
    res += after_cost - before_cost;
  };
  for (int i = 0; i < N; ++i) {
    int w = 1 - (int)(S[i] - '0');
    int pre_one = -1;
    int cur_one = -1;
    if (cls[i].size() == 1) {
      int x = cls[i][0];
      if (w == 0)
        merge(x, uf.s);
      else
        merge(x + K + 1, uf.s);
    } else if (cls[i].size() == 2) {
      int x = cls[i][0], y = cls[i][1];
      if (w == 0)
        merge(x, y);
      else
        merge(x, y + K + 1);
    }
    res += cur_one - pre_one;
    cout << res << endl;
  }
}
int main() {
  cin >> N >> K >> S;
  cls.assign(N, vector<int>());
  for (int k = 0; k < K; ++k) {
    int c;
    cin >> c;
    for (int i = 0; i < c; ++i) {
      int a;
      cin >> a;
      --a;
      cls[a].push_back(k);
    }
  }
  solve();
}
