#ifndef ___Geometry_Library
#define ___Geometry_Library

// ------ Includes ------ //
#include <cmath>
#include <vector>
#include <complex>
#include <utility>
#include <algorithm>

// ------ Defines ------ //
typedef long double GType;
typedef std::complex<GType> Point;
typedef std::pair<Point, Point> Segment;

// ------ Constants ------ //
const GType EPS = 1.0e-10L;

// ------ Functions Level 1 ------ //
GType dot(const Point& p1, const Point& p2) {
	return (std::conj(p1) * p2).real();
}
GType cross(const Point& p1, const Point& p2) {
	return (std::conj(p1) * p2).imag();
}
int ccw(const Point& p1, const Point& p2, const Point& p3) {
	Point v1 = p2 - p1, v2 = p3 - p1;
	if (cross(v1, v2) > EPS) return +1;
	if (cross(v1, v2) < -EPS) return -1;
	if (dot(v1, v2) < -EPS) return +2;
	if (std::norm(v1) < std::norm(v2)) return -2;
	return 0;
}

// ------ Functions Level 2 ------ //
bool intersect(const Segment& s1, const Point& p1, bool segflag) {
	if (!segflag) return std::abs(cross(s1.second - p1, s1.first - p1)) < EPS;
	return (std::abs(s1.first - p1) + std::abs(s1.second - p1) - std::abs(s1.second - s1.first)) < EPS;
}
bool intersect(const Segment& s1, const Segment& s2, bool segflag) {
	if (!segflag) return cross(s1.second - s1.first, s2.first - s1.first) * cross(s1.second - s1.first, s2.second - s1.first) < EPS;
	return (ccw(s1.first, s1.second, s2.first) * ccw(s1.first, s1.second, s2.second) < 0 && ccw(s2.first, s2.second, s1.first) * ccw(s2.first, s2.second, s1.second) < 0);
}
Point crosspoint(const Segment& s1, const Segment& s2) {
	GType r1 = cross(s1.second - s1.first, s2.second - s2.first);
	GType r2 = cross(s1.second - s1.first, s1.second - s2.first);
	if (std::abs(r1) < EPS && std::abs(r2) < EPS) return s2.first;
	return s2.first + r2 / r1 * (s2.second - s2.first);
}

#endif

#include <vector>
#include <iostream>
using namespace std;
int N, M, r, x, y; vector<vector<Point> > v1; vector<Point> v2, v3;
int main() {
	cin >> N >> M;
	v1.resize(N);
	for (int i = 0; i < N; i++) {
		cin >> r;
		for (int j = 0; j < r; j++) {
			cin >> x >> y;
			v1[i].push_back(Point(x, y));
		}
		v3.insert(v3.end(), v1[i].begin(), v1[i].end());
	}
	for (int i = 0; i < M; i++) {
		cin >> x >> y;
		v2.push_back(Point(x, y));
	}
	int ret = 1;
	for (int i1 = 0; i1 < M; i1++) {
		for (int j1 = 0; j1 < v3.size(); j1++) {
			for (int i2 = i1 + 1; i2 < M; i2++) {
				for (int j2 = j1 + 1; j2 < v3.size(); j2++) {
					if (abs(cross(v2[i1] - v3[j1], v2[i2] - v3[j2])) > EPS) {
						Point p1 = crosspoint(make_pair(v2[i1], v3[j1]), make_pair(v2[i2], v3[j2]));
						int res = 0;
						for (int k = 0; k < M; k++) {
							bool ok = true;
							for (int l1 = 0; l1 < N; l1++) {
								for (int l2 = 0; l2 < v1[l1].size(); l2++) {
									if (intersect(make_pair(p1, v2[k]), make_pair(v1[l1][l2], v1[l1][(l2 + 1) % v1[l1].size()]), true)) ok = false;
								}
							}
							if (ok) res++;
						}
						ret = max(ret, res);
					}
				}
			}
		}
	}
	for (int i = 0; i < v3.size(); i++) {
		int res = 0;
		for (int k = 0; k < M; k++) {
			bool ok = true;
			for (int l1 = 0; l1 < N; l1++) {
				for (int l2 = 0; l2 < v1[l1].size(); l2++) {
					Point p2 = v1[l1][l2], p3 = v1[l1][(l2 + 1) % v1[l1].size()];
					if (v3[i] == p2 || v3[i] == p3) continue;
					if (intersect(make_pair(v3[i], v2[k]), make_pair(p2, p3), true)) ok = false;
				}
			}
			if (ok) res++;
		}
		ret = max(ret, res);
	}
	cout << ret << endl;
	return 0;
}

Measured memory_bytes: 3160