#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;
struct pct {
int x, y;
};
const int N = 850;
int n, m, vx[N], a[N], b[N], c[N];
pair <pct, pct> v[N];
vector <pair <double, int> > strip[N];
vector <pair <int, int> > line[N];
void read() {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++ i) {
scanf("%d%d", &v[i].first.x, &v[i].first.y);
vx[++ vx[0]] = v[i].first.x;
}
}
inline bool comp(pct A, pct B) {
if (A.x < B.x)
return true;
if (A.x > B.x)
return false;
return A.y < B.y;
}
void init() {
for (int i = 1; i < n; ++ i)
v[i].second = v[i + 1].first;
v[n].second = v[1].first;
for (int i = 1; i <= n; ++ i)
if (! comp(v[i].first, v[i].second))
swap(v[i].first, v[i].second);
}
inline double inters(pair <pct, pct> a, int x) {
double m = (double)(a.first.y - a.second.y) / (a.first.x - a.second.x);
if (m == 0)
return a.first.y;
return (double)m *((double)x - a.first.x) + (double)a.first.y;
}
void linie(int poz) {
for (int i = 1; i <= n; ++ i)
if (v[i].first.x == vx[poz] && vx[poz] == v[i].second.x)
line[poz].push_back(make_pair(v[i].first.y, v[i].second.y));
}
void fasie(int poz) {
if (poz == vx[0])
return;
for (int i = 1; i <= n; ++ i)
if (v[i].first.x <= vx[poz] && vx[poz + 1] <= v[i].second.x)
strip[poz].push_back(make_pair(inters(v[i], (vx[poz] + vx[poz + 1]) / 2), i));
}
void shiftare_stanga(int poz, int v[N]) {
for (int i = poz; i <= v[0]; ++ i)
v[i] = v[i + 1];
}
void scoate_duplicate(int v[N]) {
for (int i = 2; i <= v[0]; ++ i)
if (v[i] == v[i - 1]) {
shiftare_stanga(i, v);
-- v[0];
-- i;
}
}
void preproc() {
for (int i = 1; i <= n; ++ i) {
a[i] = v[i].first.y - v[i].second.y;
b[i] = v[i].second.x - v[i].first.x;
c[i] = v[i].first.x * v[i].second.y - v[i].second.x * v[i].first.y;
}
sort(vx + 1, vx + vx[0] + 1);
scoate_duplicate(vx);
for (int i = 1; i <= vx[0]; ++ i) {
linie(i);
fasie(i);
}
for (int i = 1; i <= vx[0]; ++ i) {
sort(line[i].begin(), line[i].end());
sort(strip[i].begin(), strip[i].end());
}
}
int cautb(int x) {
int pas = 1 << 10, i = 0;
for (i = 0; pas; pas >>= 1)
if (i + pas <= vx[0] && vx[i + pas] <= x)
i += pas;
return i;
}
bool verif(int i, int x, int y) {
return a[i] * x + b[i] * y + c[i] > 0;
}
bool verif_fasie(int x, int y, int poz) {
int i = 0, pas = 1 << 10;
for (i = - 1; pas; pas >>= 1)
if (i + pas < strip[poz].size() && verif(strip[poz][i + pas].second, x, y))
i += pas;
if ((strip[poz].size() - i - 1) % 2 == 1)
return 1;
if (i + 1 < strip[poz].size() && a[strip[poz][i + 1].second] * x + b[strip[poz][i + 1].second] * y + c[strip[poz][i + 1].second] == 0)
return 1;
return 0;
}
bool verif_linie(int x, int y, int poz) {
int i = 0, pas = 1 << 10;
for (i = - 1; pas; pas >>= 1)
if (i + pas < line[poz].size() && line[poz][i + pas].first <= y)
i += pas;
if (i == - 1 || line[poz][i].second < y)
return 0;
return 1;
}
void solve() {
int x, y, nrp = 0;
for (int i = 1; i <= m; ++ i) {
scanf("%d%d", &x, &y);
if (x < vx[1] || x > vx[vx[0]])
continue;
int poz = cautb(x);
if (verif_fasie(x, y, poz) || (x == vx[poz] && verif_linie(x, y, poz)))
++ nrp;
}
printf("%d\n", nrp);
}
int main() {
freopen("poligon.in", "r", stdin);
freopen("poligon.out", "w", stdout);
read();
init();
preproc();
solve();
return 0;
}