#include <bits/stdc++.h>
using namespace std;
#define int long long
#define REP(i,n) for(int i = 0; i < (int)(n); ++i)
#define DEBUG(x) cerr << #x << " = " << x << endl
 
typedef double D;
const D EPS = 1e-8;
struct P {
  D x, y;
  P() {}
  P(D x_, D y_) : x(x_), y(y_) {}
};
struct L {
  P a, b;
  L() {}
  L(P a_, P b_) : a(a_), b(b_) {}
};
 
int sgn(D a, D b) {
  if(a < b - EPS) return -1;
  if(a > b + EPS) return +1;
  return 0;
}
 
P operator *(P a, D b) { return P(a.x * b, a.y * b); }
P operator +(P a, P b) { return P(a.x + b.x, a.y + b.y); }
P operator -(P a, P b) { return P(a.x - b.x, a.y - b.y); }
P operator /(P a, D b) { return P(a.x / b, a.y / b); }
D outp(P a, P b) { return a.x * b.y - a.y * b.x; }
D inp(P a, P b) { return a.x*b.x + a.y*b.y; }
D abs(P p) { return sqrt(inp(p, p)); }
P vec(P st, P en) { return en - st; }
 
int ccw(P a, P b, P c) {
  b = vec(a, b);
  c = vec(a, c);
  if(sgn(outp(b, c), 0.0) > 0) return +1;
  if(sgn(outp(b, c), 0.0) < 0) return -1;
  if(sgn(inp(b, c), 0.0) < 0) return +2;
  if(sgn(abs(b), abs(c)) < 0) return -2;
  return 0;
}
 
bool iSS(L s, L t) {
  return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) < 0 &&
    ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) < 0;
}
 
P cLL(L l, L m) {
  D d = outp(vec(m.a, m.b), vec(l.a, l.b));
  return l.a + vec(l.a, l.b) * outp(vec(m.a, m.b), vec(l.a, m.b)) / d;
}
 
typedef vector<P> Poly;
 
bool is_intersect_poly_segment(const Poly &p, const L &s) {
  REP(i,p.size()) {
    L l(p[i], p[(i + 1) % p.size()]);
    // if(s.a.x == 10 && s.a.y == 100) {
    //   cerr << "l = (" << l.a.x << "," << l.a.y << "), (" << l.b.x << "," << l.b.y << ")" << endl;
    //   cerr << "s = (" << s.a.x << "," << s.a.y << "), (" << s.b.x << "," << s.b.y << ")" << endl;
    //   DEBUG(iSS(l, s));
    // }
    if(iSS(l, s)) return true;
  }
  return false;
}
 
bool isParallel(L m, L l) {
  D d = outp(vec(m.a, m.b), vec(l.a, l.b));
  return sgn(d, 0.0) == 0;
}
 
signed main() {
  ios::sync_with_stdio(false);
  int N, M; cin >> N >> M;
  vector<Poly> PS;
  REP(i,N) {
    int L; cin >> L;
    Poly p;
    REP(j,L) {
      int x, y; cin >> x >> y;
      p.emplace_back(x, y);
    }
    PS.push_back(p);
  }
  vector<P> V;
  REP(i,M) {
    int x, y; cin >> x >> y;
    V.emplace_back(x, y);
  }
  int ans = 1;
  // O(M^2 + N * 15 * M * N)
  REP(i,M) {
    for(int j = i + 1; j < M; ++j) {
      REP(k,N) REP(l,PS[k].size()) {
        REP(k2,N) REP(l2,PS[k2].size()) {
          L a(V[i], PS[k][l]), b(V[j], PS[k2][l2]);
          if(isParallel(a, b)) continue;
          P cross_point = cLL(a, b);
          // cerr << "cross_point = (" << cross_point.x << "," << cross_point.y << ")" << endl;
          int cnt = 0;
          REP(m,M) {
            L line(cross_point, V[m]);
            bool valid = true;
            REP(n,N) {
              // if(cross_point.x == 10 && cross_point.y == 100) {
              //   DEBUG(n);
              //   DEBUG(is_intersect_poly_segment(PS[n], line));
              // }
              if(is_intersect_poly_segment(PS[n], line)) valid = false;
            }
            if(valid) cnt++;
          }
          ans = max(ans, cnt);
          // if(cnt == 2) {
          //   cerr << "cross_point = (" << cross_point.x << "," << cross_point.y << ")" << endl;
          // }
        }
      }
    }
  }
  cout << ans << endl;
}

Measured memory_bytes: 3168