#include<bits/stdc++.h>
#define mset(a,b) memset(a,b,sizeof(a))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
typedef long long ll;
const ll maxn=1e4+200;
const int inf=0x3f3f3f3f;
const double EPS=1e-10;
//typedef pair<int,int> PA;
double add(double a,double b) //考虑误差的加法运算
{
    if(abs(a+b)<EPS*(abs(a)+abs(b))) return  0;
    return a+b;
}
int sgn(double x)
{
    if(abs(x)<EPS)  return 0;
    if(x<0) return -1;
    else return 1;
}
class Point
{
public:
    double x,y;
    Point() {}
    Point(double x,double y):x(x),y(y)
    {
    }
    Point operator+ (Point p)
    {
        return Point(add(x,p.x),add(y,p.y));
    }
    Point operator -(Point p)
    {
        return Point(add(x,-p.x),add(y,-p.y));
    }
    Point operator *(double d)
    {
        return Point(x*d,y*d);
    }
    double operator *(Point p)
    {
        return add(x*p.x,y*p.y);//外积
    }
    double operator ^(Point p) //内积
    {
        return add(x*p.y,-y*p.x);
    }
    double det(Point p) //**不要也行
    {
        return add(x*p.y,-y*p.x);
    }
    double len()
    {
        return sqrt(add(x*x,y*y));
    }
};
class Line
{
public:
    Point s,e;
    Line() {}
    Line(Point s,Point e):s(s),e(e) {}
};
bool onSge(Line l,Point q)
{
    return ((l.s-q)^(l.e-q))==0&&((l.s-q)*(l.e-q))<=0;
}
Point operator *(double d,Point p)
{
    return Point(p.x*d,p.y*d);
}
Point getProject(Point p1,Point p2,Point q) //q 在直线p1,p2上的投影坐标
{
    double d1=1.0/(p2-p1).len();
    Point ans=(q-p1)*(p2-p1)*(p2-p1)*d1*d1;
    return ans+p1;
}
Point getReflect(Point p1,Point p2,Point q) //q 关于直线p1 p2的 反射坐标
{
    return 2.0*getProject(p1,p2,q)-q;
}
double getDisPP(Point a,Point b) //两点之间距离
{
    return (b-a).len();
}
double getDisPL(Line l,Point p) //点到直线距离
{
    Point x=getProject(l.s,l.e,p);
    return (p-x).len();
}
double getDisPS(Line l,Point p) //点到线段最短距离
{
    Point x=getProject(l.s,l.e,p);
    if(onSge(l,x))
        return (x-p).len();
    else
        return min((p-l.s).len(),(p-l.e).len());

}
double getDisSS(Line la,Line lb) //保证两线段不相交 isInterSS==false
{
    return min(min(getDisPS(la,lb.s),getDisPS(la,lb.e)),
               min(getDisPS(lb,la.s),getDisPS(lb,la.e)));
}

int getDirPPP(Point p,Point p1,Point p2)
{
    return sgn((p1-p)^(p2-p));//1代表 p2在p1的逆时针方向  0共线 ，-1是p2在p1的顺时针方向
}
int getStatePP(Point p,Point p1,Point p2) //返回 p2 关于p 在p1的什么方向
{
    int a=sgn((p1-p)^(p2-p));
    int b=sgn((p1-p)*(p2-p));
    if(a>0) //
    {
        puts("COUNTER_CLOCKWISE");
    }
    else if(a<0)
    {
        puts("CLOCKWISE");
    }
    else if(b<0)
    {
        puts("ONLINE_BACK");
    }
    else if(b>0&&sgn((p1-p)*(p2-p1))>0)
    {
        puts("ONLINE_FRONT");
    }
    else
    {
        puts("ON_SEGMENT");
    }
    return 0;
}
bool isInterSS(Line la,Line lb) //线段是否想交
{
    int d1=getDirPPP(lb.s,lb.e,la.s);
    int d2=getDirPPP(lb.s,lb.e,la.e);
    int d3=getDirPPP(la.s,la.e,lb.s);
    int d4=getDirPPP(la.s,la.e,lb.e);
    if(d1*d2<0&&d3*d4<0)
        return true;
    else if(d1==0&&onSge(lb,la.s))
        return true;
    else if(d2==0&&onSge(lb,la.e))
        return true;
    else if(d3==0&&onSge(la,lb.s))
        return true;
    else if(d4==0&&onSge(la,lb.e))
        return true;
    else
        return false;

}
int getStateLL(Line la,Line lb) //两个直线 垂直，相交或者平行
{
    if(sgn((la.e-la.s)^(lb.e-lb.s))==0)
    {
        return 2;//平行
    }//两向量平行 内积为0
    else if(sgn((la.e-la.s)*(lb.e-lb.s))==0)
    {
        return 1;//垂直
    }
    else return 0;
}
typedef Point P;
Point getInterLL(Point p1,Point p2,Point q1, Point q2) //得到直线交点
{
    return p1+(p2-p1)*((q2-q1).det(q1-p1)/(q2-q1).det(p2-p1));
}
double getAreaPolygon(Point p[],int n) //下标从0开始  计算多边形面积
{
    double res=0.0;
    for(int i=0; i<n; ++i)
        res+=(p[i]^p[(i+1)%n])/2;
    return res;
}
Point PA[110000];
bool _cmp(Point p1,Point p2)//相对于pa[0]的
{
    double tmp=(p1-PA[0])^(p2-PA[0]);
    if(sgn(tmp)>0) return true;
    else if(sgn(tmp)==0 &&(PA[0]-p1).len()>(PA[0]-p2).len())//如果奇角相同 距离远的排在前面
        return true;
    else return false;
}
void sortPolarAngle(Point PA[],int n)//对数组进行极角排序  点将逆时针排序 WA
{
    Point p0=PA[0];
    int k=0;
    /* 找到最下边的一个点 靠左的一个点*/
    for(int i=1; i<n; ++i)
    {
        if((p0.y>PA[i].y)||(p0.y==PA[i].y&&p0.x>PA[i].x))
        {
            p0=PA[i];
            k=i;
        }
    }
    swap(PA[k],PA[0]);
    sort(PA+1,PA+n,_cmp);
    return ;
}
//判断是否为凸包
//允许共线边
//点可以是顺时针给出也可以是逆时针给出
//点的编号为0~n-1
bool isConvex(Point poly[],int n)
{
    bool s[3];
    memset(s,false,sizeof(s));
    for(int i=0; i<n; ++i)
    {
        s[sgn( (poly[(i+1)%n]-poly[i]) ^ (poly[(i+2)%n]-poly[i]) )+1]=true;
        if(s[0]&&s[2]) return false;//拐的方向不同
    }
    return true;
}
// 3 点上
// 2 边上
// 1 内部
// 0 外部
int getStatePolygonP(Point p[],int n,Point q)
{
    for(int i = 0; i < n; i++)
    {
        if(p[i].x==q.x&&p[i].y==q.y)return 3;
    }

    for(int i = 0; i < n; i++)
    {
        int j=(i+1)%n;
        if(onSge(Line(p[j],p[i]),q))return 2;
    }
    int cnt = 0;
    for(int i = 0 ; i < n; i++)
    {
        int j=(i+1)%n;
        int k = sgn((q-p[j])^(p[i]-p[j]));
        int u = sgn(p[i].y-q.y);
        int v = sgn(p[j].y-q.y);
        if(k > 0 && u < 0 && v >= 0)    cnt++;
        if(k < 0 && v < 0 && u >= 0)    cnt--;
    }
    return cnt != 0;
}
int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0; i<n; ++i)
    {
        scanf("%lf%lf",&PA[i].x,&PA[i].y);
    }
    int m;
    scanf("%d",&m);
    while(m--)
    {
        Point q;
        scanf("%lf%lf",&q.x,&q.y);
         int sta=getStatePolygonP(PA,n,q);
         if(sta==3||sta==2)
            puts("1");
         else if(sta==1)
            puts("2");
         else
            puts("0");
    }
    return 0;
}
//double getDistanceSP(Segment s,Point p){
//	if(dot(calc_minus(s.p2,s.p1),calc_minus(p,s.p1)) < 0.0)return calc_len(calc_minus(p,s.p1));
//	if(dot(calc_minus(s.p1,s.p2),calc_minus(p,s.p2)) < 0.0)return calc_len(calc_minus(p,s.p2));
//	return getDistanceLP(s,p);
//}
/*

5
0 0 1 1 2 2  2 3
*/






























Measured memory_bytes: 3260