#include<bits/stdc++.h>
using namespace std;
#define ll long long
char buf[1<<20],*p1,*p2;
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
template<class T> inline void read(T &n){
    char ch=GC;T w=1,x=0;
    while(!isdigit(ch)){if(ch=='-') w=-1;ch=GC;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=GC;}
    n=x*w;
}
const int maxn=100005;
const int maxm=300005;
int n,q,N,st[maxn],ed[maxn],X[maxm],Y[maxm];
pair <int,int> a[maxm];
map <pair<int,int>,int> lst;
int ans[maxn];
struct query{
	int l,r,id;
}Q[maxn];
bool cmp(query x,query y){
	return x.r<y.r;
}
int t[maxn];
inline int lowbit(int x){
	return x&(-x);
}
inline void update(int x,int val){
	for(int i=x;i<=N;i+=lowbit(i)) t[i]+=val;
}
inline int ask(int x){
	int res=0;
	for(int i=x;i>=1;i-=lowbit(i)) res+=t[i];
	return res;
}
int main(){
	read(n);
	for(int i=1,k;i<=n;i++){
		read(k);
		for(int j=1;j<=k;j++) read(X[j]),read(Y[j]);
		X[k+1]=X[1],Y[k+1]=Y[1];
		st[i]=ed[i-1]+1;
		ed[i]=ed[i-1];
		for(int j=1;j<=k;j++){
			int x=X[j+1]-X[j],y=Y[j+1]-Y[j];
			int g=__gcd(abs(x),abs(y));
			if(g) x/=g,y/=g;
			a[++ed[i]]=make_pair(x,y);
		}
	}
	N=ed[n];
	read(q);
	for(int i=1,l,r;i<=q;i++){
		read(l),read(r);
		Q[i]=(query){st[l],ed[r],i};
	}
	sort(Q+1,Q+q+1,cmp);
	for(int i=1,j=1;i<=N;i++){
		if(lst[a[i]]) update(lst[a[i]],-1);
		lst[a[i]]=i,update(i,1);
		for(;j<=q&&Q[j].r<=i;j++) ans[Q[j].id]=ask(Q[j].r)-ask(Q[j].l-1);
	}
	for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
char buf[1<<20],*p1,*p2;
#define GC (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?0:*p1++)
template<class T> inline void read(T &n){
    char ch=GC;T w=1,x=0;
    while(!isdigit(ch)){if(ch=='-') w=-1;ch=GC;}
    while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=GC;}
    n=x*w;
}
const int maxn=100005;
const int maxm=maxn*3;
int n,q,N,st[maxn],ed[maxn],X[maxm],Y[maxm];
pair <int,int> a[maxm];
map <pair<int,int>,int> lst;
int ans[maxn];
struct query{
	int l,r,id;
}Q[maxn];
bool cmp(query x,query y){
	return x.r<y.r;
}
int t[maxm];
inline int lowbit(int x){
	return x&(-x);
}
inline void update(int x,int val){
	for(int i=x;i<=N;i+=lowbit(i)) t[i]+=val;
}
inline int ask(int x){
	int res=0;
	for(int i=x;i>=1;i-=lowbit(i)) res+=t[i];
	return res;
}
int main(){
	read(n);
	for(int i=1,k;i<=n;i++){
		read(k);
		for(int j=1;j<=k;j++) read(X[j]),read(Y[j]);
		X[k+1]=X[1],Y[k+1]=Y[1];
		st[i]=ed[i-1]+1;
		ed[i]=ed[i-1];
		for(int j=1;j<=k;j++){
			int x=X[j+1]-X[j],y=Y[j+1]-Y[j];
			int g=__gcd(abs(x),abs(y));
			if(g) x/=g,y/=g;
			a[++ed[i]]=make_pair(x,y);
		}
	}
	N=ed[n];
	read(q);
	for(int i=1,l,r;i<=q;i++){
		read(l),read(r);
		Q[i]=(query){st[l],ed[r],i};
	}
	sort(Q+1,Q+q+1,cmp);
	for(int i=1,j=1;i<=N;i++){
		if(lst[a[i]]) update(lst[a[i]],-1);
		lst[a[i]]=i,update(i,1);
		for(;j<=q&&Q[j].r<=i;j++) ans[Q[j].id]=ask(Q[j].r)-ask(Q[j].l-1);
	}
	for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ljc 998244353
using namespace std;
/*
显然两个凸包的所有按照极角序连起来的边，斜率递增。
然后考虑闵可夫斯基和的构造方式，就是根据极角序归并。
所以相同斜率的边，只会出现一次（重复的点都省略了）。
对于每一个凸包，极角排序，求出相邻点的斜率，然后每一次询问等价于求区间有多少个不同的斜率。
直接离线+树状数组即可。

注意$+0,-0$算两种，$+\infty,-\infty$ 算两种。

仿佛给定的凸包已经极角排序好了，所以直接连就可以了？
注意离散化。
*/
#ifdef Fading
#define gc getchar
#endif
#ifndef Fading
inline char gc(){
	static char now[1<<16],*S,*T;
	if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
	return *S++;
}
#endif
inline ll read(){
    register ll x=0,f=1;char ch=gc();
    while (!isdigit(ch)){if(ch=='-')f=-1;ch=gc();}
    while (isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=gc();}
    return (f==1)?x:-x;
}
map<pair<int,int>,int> has;
int n,m,col[620001],id,cnt,K[620001][2],tr[620001],L[620001],R[620001];
int las[620001],pre[620001];
inline int query(int x){
	int ans=0;
	for (;x;x-=x&-x) ans+=tr[x];
	return ans;
}
inline void add(int x,int y){
	if (!x) return;
	for (;x<=cnt;x+=x&-x) tr[x]+=y;
}
int ans[1000001];
struct QUE{
	int l,r,id;
}q[1000001];
inline bool cmp(QUE a,QUE b){
	return (a.r==b.r?a.l<b.l:a.r<b.r);
}
signed main(){
	n=read();
	for (int i=1;i<=n;i++){
		L[i]=cnt+1;R[i]=L[i]+read()-1;
		for (int j=1;j<=R[i]-L[i]+1;j++){
			K[j][0]=read();K[j][1]=read();
		}
		for (int j=2;j<=R[i]-L[i]+1;j++){
			pair<int,int> P=make_pair(K[j][1]-K[j-1][1],K[j][0]-K[j-1][0]);
			int G=__gcd(abs(P.first),abs(P.second));
			P.first/=G;P.second/=G;
			if (!has.count(P)) has[P]=++id;
			col[++cnt]=has[P];
		}
		pair<int,int> P=make_pair(K[1][1]-K[R[i]-L[i]+1][1],K[1][0]-K[R[i]-L[i]+1][0]);
		int G=__gcd(abs(P.first),abs(P.second));
		P.first/=G;P.second/=G;
		if (!has.count(P)) has[P]=++id;
		col[++cnt]=has[P];
	}
	m=read();
	for (int i=1;i<=m;i++){
		q[i].id=i;q[i].l=L[read()];q[i].r=R[read()];
	}
	for (int i=1;i<=cnt;i++){
		pre[i]=las[col[i]];las[col[i]]=i;
	}
	sort(q+1,q+1+m,cmp);
	for (int tmp=1,i=1;i<=m;i++){
		for (;tmp<=q[i].r;tmp++) add(tmp,1),add(pre[tmp],-1);
		ans[q[i].id]=query(q[i].r)-query(q[i].l-1);
	}
	for (int i=1;i<=m;i++){
		printf("%d\n",ans[i]);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define ljc 998244353
using namespace std;
/*
显然两个凸包的所有按照极角序连起来的边，斜率递增。
然后考虑闵可夫斯基和的构造方式，就是根据极角序归并。
所以相同斜率的边，只会出现一次（重复的点都省略了）。
对于每一个凸包，极角排序，求出相邻点的斜率，然后每一次询问等价于求区间有多少个不同的斜率。
直接离线+树状数组即可。

注意$+0,-0$算两种，$+\infty,-\infty$ 算两种。

仿佛给定的凸包已经极角排序好了，所以直接连就可以了？
注意离散化。
*/
#ifdef Fading
#define gc getchar
#endif
#ifndef Fading
inline char gc(){
	static char now[1<<16],*S,*T;
	if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
	return *S++;
}
#endif
inline ll read(){
    register ll x=0,f=1;char ch=gc();
    while (!isdigit(ch)){if(ch=='-')f=-1;ch=gc();}
    while (isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=gc();}
    return (f==1)?x:-x;
}
map<pair<int,int>,int> has;
int n,m,col[620001],id,cnt,K[620001][2],tr[620001],L[620001],R[620001];
int las[620001],pre[620001];
inline int query(int x){
	int ans=0;
	for (;x;x-=x&-x) ans+=tr[x];
	return ans;
}
inline void add(int x,int y){
	if (!x) return;
	for (;x<=cnt;x+=x&-x) tr[x]+=y;
}
int ans[1000001];
struct QUE{
	int l,r,id;
}q[1000001];
inline bool cmp(QUE a,QUE b){
	return (a.r==b.r?a.l<b.l:a.r<b.r);
}
signed main(){
	n=read();
	for (int i=1;i<=n;i++){
		L[i]=cnt+1;R[i]=L[i]+read()-1;
		for (int j=1;j<=R[i]-L[i]+1;j++){
			K[j][0]=read();K[j][1]=read();
		}
		for (int j=2;j<=R[i]-L[i]+1;j++){
			pair<int,int> P=make_pair(K[j][1]-K[j-1][1],K[j][0]-K[j-1][0]);
			if (!has.count(P)) has[P]=++id;
			col[++cnt]=has[P];
		}
		pair<int,int> P=make_pair(K[1][1]-K[R[i]-L[i]+1][1],K[1][0]-K[R[i]-L[i]+1][0]);
		if (!has.count(P)) has[P]=++id;
		col[++cnt]=has[P];
	}
	m=read();
	for (int i=1;i<=m;i++){
		q[i].id=i;q[i].l=L[read()];q[i].r=R[read()];
	}
	for (int i=1;i<=cnt;i++){
		pre[i]=las[col[i]];las[col[i]]=i;
	}
	sort(q+1,q+1+m,cmp);
	for (int tmp=1,i=1;i<=m;i++){
		for (;tmp<=q[i].r;tmp++) add(tmp,1),add(pre[tmp],-1);
		ans[q[i].id]=query(q[i].r)-query(q[i].l-1);
	}
	for (int i=1;i<=m;i++){
		printf("%d\n",ans[i]);
	}
	return 0;
}


#include <bits/stdc++.h>

#define endl '\n'
#define fi first
#define se second
#define MOD(n,k) ( ( ((n) % (k)) + (k) ) % (k))
#define forn(i,n) for (int i = 0; i < n; i++)
#define forr(i,a,b) for (int i = a; i <= b; i++)
#define all(v) v.begin(), v.end()
#define pb emplace_back

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ii> vii;

const int MX = 100005;
int n, k[MX], q, ft[MX], res[MX], l[MX], r;
map<ii, int> mp;
vi pos[MX], x[MX], y[MX];

void update (int i, int k) {
	while (i < MX) {
		ft[i] += k;
		i += i & -i;
	}
}

int query (int i) {
	int s = 0;
	while (i) {
		s += ft[i];
		i -= i & -i;
	}
	return s;
}

int query (int a, int b) {
	return query(b) - query(a - 1);
}

int main () {
	ios_base::sync_with_stdio(0); cin.tie(0);

	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> k[i];
		x[i].resize(k[i] + 1), y[i].resize(k[i] + 1);
		for (int j = 0; j < k[i]; j++)
			cin >> x[i][j] >> y[i][j];
		x[i][k[i]] = x[i][0];
		y[i][k[i]] = y[i][0];
	}

	cin >> q;
	for (int i = 0; i < q; i++) {
		cin >> l[i] >> r;
		pos[r].pb(i);
	}

	for (int i = 1; i <= n; i++) {
		update(i, k[i]);

		for (int j = 0; j < k[i]; j++) {
			int a = x[i][j] - x[i][j+1];
			int b = y[i][j] - y[i][j+1];
			int g = __gcd(abs(a), abs(b));
			a /= g;
			b /= g;
			cout << a << " " << b << endl;
			if (b < 0) a *= -1, b *= -1;

			if (mp.count(ii(a, b)))
				update(mp[ii(a, b)], -1);
			mp[ii(a, b)] = i;
		}
		cout << endl;

		for (int j : pos[i])
			res[j] = query(l[j], i);
	}

	for (int i = 0; i < q; i++)
		cout << res[i] << endl;

	return 0;
}


#include <bits/stdc++.h>

#define endl '\n'
#define fi first
#define se second
#define MOD(n,k) ( ( ((n) % (k)) + (k) ) % (k))
#define forn(i,n) for (int i = 0; i < n; i++)
#define forr(i,a,b) for (int i = a; i <= b; i++)
#define all(v) v.begin(), v.end()
#define pb emplace_back

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<ii> vii;

const int MX = 100005;
int n, k[MX], q, ft[MX], res[MX], l[MX], r;
map<ii, int> mp;
vi pos[MX], x[MX], y[MX];

void update (int i, int k) {
	while (i < MX) {
		ft[i] += k;
		i += i & -i;
	}
}

int query (int i) {
	int s = 0;
	while (i) {
		s += ft[i];
		i -= i & -i;
	}
	return s;
}

int query (int a, int b) {
	return query(b) - query(a - 1);
}

int main () {
	ios_base::sync_with_stdio(0); cin.tie(0);

	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> k[i];
		x[i].resize(k[i] + 1), y[i].resize(k[i] + 1);
		for (int j = 0; j < k[i]; j++)
			cin >> x[i][j] >> y[i][j];
		x[i][k[i]] = x[i][0];
		y[i][k[i]] = y[i][0];
	}

	cin >> q;
	for (int i = 0; i < q; i++) {
		cin >> l[i] >> r;
		pos[r].pb(i);
	}

	for (int i = 1; i <= n; i++) {
		update(i, k[i]);

		for (int j = 0; j < k[i]; j++) {
			int a = x[i][j] - x[i][j+1];
			int b = y[i][j] - y[i][j+1];
			int g = __gcd(abs(a), abs(b));
			a /= g;
			b /= g;

			if (mp.count(ii(a, b)) && mp[ii(a, b)] != i)
				update(mp[ii(a, b)], -1);
			mp[ii(a, b)] = i;
		}

		for (int j : pos[i])
			res[j] = query(l[j], i);
	}

	for (int i = 0; i < q; i++)
		cout << res[i] << endl;

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 3e5 + 10;
int n, Q, m, a[N], lft[N], rgt[N], G[N], ans[N];
int place[N], tot;
set<int> ST;
set<int>::iterator it;

struct Point{
    int idx;
    LL x, y;
    bool sig;
    Point(){}
    Point(LL x, LL y):x(x),y(y){
        sig = y>0 || (y==0 && x>0);
    }
    void read(){
        scanf("%I64d %I64d", &x, &y);
        sig = y>0 || (y==0 && x>0);
    }
    Point operator + (Point A){
        return Point(x + A.x, y + A.y);
    }
    Point operator - (Point A){
        return Point(x - A.x, y - A.y);
    }
    bool operator < (const Point &A) const {
        if(sig != A.sig){
            return sig > A.sig;
        }
        return (x * A.y - y * A.x) > 0;
    }
};
Point P[N], p[N];

struct Que{
    int id, l, r;
    void read(int idx){
        id = idx;
        scanf("%d %d", &l, &r);
        l = lft[l];
        r = rgt[r];
    }
    bool operator < (const Que &A)const{
        return (G[l])^(G[A.l])?G[l]<G[A.l]:(((G[l])&1)?r<A.r:r>A.r);
    }
}que[N];

bool ok(int i, int j){
    if(i == -1 || j == -1)  return 0;
    return (P[i].x*P[j].y - P[i].y*P[j].x) != 0;
}

void add(int i){
    int p = place[i];
    ST.insert(p);
    it = ST.find(p);

    int j = -1;
    if(it != ST.begin()){
        it--;
        j = *it;
        it++;
    }

    it++;
    int k = -1;
    if(it != ST.end()){
        k = *it;
    }

    if(ok(j, k))    tot--;
    if(ok(j, p))    tot++;
    if(ok(p, k))    tot++;

    if(ST.size() == 1){
        tot = 1;
    }
}

void sub(int i){
    int p = place[i];
    it = ST.find(p);

    int j = -1;
    if(it != ST.begin()){
        it--;
        j = *it;
        it++;
    }

    it++;
    int k = -1;
    if(it != ST.end()){
        k = *it;
    }

    if(ok(j, k))    tot++;
    if(ok(j, p))    tot--;
    if(ok(p, k))    tot--;

    ST.erase(p);

    if(!ST.size()){
        tot = 0;
    }
}

void solve(){
    int s = (int)sqrt(m*1.0);
    for(int i=1; i<=m; i++){
        P[i].idx = i;
        G[i] = i / s;
    }
    sort(P+1, P+1+m);
    ST.clear();

    for(int i=1; i<=m; i++){
        place[P[i].idx] = i;
    }

    sort(que, que+Q);

    int L = 1, R = 0;
    tot = 0;

    for(int i=0; i<Q; i++){
        while(R < que[i].r) add(++R);
        while(R > que[i].r) sub(R--);
        while(L > que[i].l) add(--L);
        while(L < que[i].l) sub(L++);

        ans[que[i].id] = tot;
    }
}

int main(){
    scanf("%d", &n);
    m = 0;
    for(int i=1; i<=n; i++){
        scanf("%d", a+i);
        lft[i] = m+1;
        for(int j=1; j<=a[i]; j++){
            p[j].read();
            if(j!=1){
                P[++m] = p[j]-p[j-1];
            }
            if(j==a[i]){
                P[++m] = p[1]-p[j];
            }
        }
        rgt[i] = m;
    }

    scanf("%d", &Q);
    for(int i=0; i<Q; i++){
        que[i].read(i);
    }

    solve();

    for(int i=0; i<Q; i++){
        printf("%d\n", ans[i]);
    }

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 3e5 + 10;
int n, Q, m, a[N], lft[N], rgt[N], G[N], ans[N];
int place[N], tot;
set<int> ST;
set<int>::iterator it;

struct Point{
    int idx;
    LL x, y;
    bool sig;
    Point(){}
    Point(LL x, LL y):x(x),y(y){
        sig = y>0 || (y==0 && x>0);
    }
    void read(){
        scanf("%I64d %I64d", &x, &y);
        sig = y>0 || (y==0 && x>0);
    }
    Point operator + (Point A){
        return Point(x + A.x, y + A.y);
    }
    Point operator - (Point A){
        return Point(x - A.x, y - A.y);
    }
    bool operator < (const Point &A) const {
        if(sig != A.sig){
            return sig > A.sig;
        }
        return (x * A.y - y * A.x) > 0;
    }
};
Point P[N], p[N];

struct Que{
    int id, l, r;
    void read(int idx){
        id = idx;
        scanf("%d %d", &l, &r);
        l = lft[l];
        r = rgt[r];
    }
    bool operator < (const Que &A)const{
        return G[l] < G[A.l] || (G[l] == G[A.l] && r < A.r);
    }
}que[N];

bool ok(int i, int j){
    if(i == -1 || j == -1)  return 0;
    return (P[i].x*P[j].y - P[i].y*P[j].x) != 0;
}

void add(int i){
    int p = place[i];
    ST.insert(p);
    it = ST.find(p);

    int j = -1;
    if(it != ST.begin()){
        it--;
        j = *it;
        it++;
    }

    it++;
    int k = -1;
    if(it != ST.end()){
        k = *it;
    }

    if(ok(j, k))    tot--;
    if(ok(j, p))    tot++;
    if(ok(p, k))    tot++;

    if(ST.size() == 1){
        tot = 1;
    }
}

void sub(int i){
    int p = place[i];
    it = ST.find(p);

    int j = -1;
    if(it != ST.begin()){
        it--;
        j = *it;
        it++;
    }

    it++;
    int k = -1;
    if(it != ST.end()){
        k = *it;
    }

    if(ok(j, k))    tot++;
    if(ok(j, p))    tot--;
    if(ok(p, k))    tot--;

    ST.erase(i);

    if(!ST.size()){
        tot = 0;
    }
}

void solve(){
    int s = (int)sqrt(m*1.0);
    for(int i=1; i<=m; i++){
        P[i].idx = i;
        G[i] = i / s;
    }
    sort(P+1, P+1+m);
    ST.clear();

    for(int i=1; i<=m; i++){
        place[P[i].idx] = i;
    }

    sort(que, que+Q);

    int L = 1, R = 0;
    tot = 0;

    for(int i=0; i<Q; i++){
        while(R < que[i].r) add(++R);
        while(R > que[i].r) sub(R--);
        while(L > que[i].l) add(--L);
        while(L < que[i].l) sub(L++);

        ans[que[i].id] = tot;
    }
}

int main(){
    scanf("%d", &n);
    m = 0;
    for(int i=1; i<=n; i++){
        scanf("%d", a+i);
        lft[i] = m+1;
        for(int j=1; j<=a[i]; j++){
            p[j].read();
            if(j!=1){
                P[++m] = p[j]-p[j-1];
            }
            if(i==n){
                P[++m] = p[1]-p[j];
            }
        }
        rgt[i] = m;
    }

    scanf("%d", &Q);
    for(int i=0; i<Q; i++){
        que[i].read(i);
    }

    solve();

    for(int i=0; i<Q; i++){
        printf("%d\n", ans[i]);
    }

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

const int N = 3e5 + 10;
typedef long long LL;

int n, Q, m, idx[N], pre[N], s[N];
int lft[N], rgt[N], len[N], ans[N];

struct Point{
    LL x, y;
    int id;
    bool sig;
    Point(){}
    Point(LL x, LL y):x(x),y(y){
        sig = y > 0 || (y == 0 && x > 0);
    }
    void read(){
        scanf("%I64d %I64d", &x, &y);
        sig = y > 0 || (y == 0 && x > 0);
    }
    Point operator - (Point A){
        return Point(x - A.x, y - A.y);
    }
    bool operator < (const Point &A)const{
        if(sig != A.sig){
            return sig > A.sig;
        }
        return x*A.y-y*A.x >0;
    }
}P[N], p[N];

struct Que{
    int id, l, r;
    void read(int idx){
        id = idx;
        scanf("%d %d", &l, &r);
        l = lft[l];
        r = rgt[r];
    }
    bool operator < (const Que &A)const{
        return r < A.r;
    }
}que[N];

int lowbit(int x){
    return x & (-x);
}

void add(int x, int v){
    for(; x<=m; x+=lowbit(x))   s[x] += v;
}

int sum(int x){
    int ret = 0;
    for(; x>0; x-=lowbit(x))    ret += s[x];
    return ret;
}

int main(){
    while(~scanf("%d", &n)){
        m = 0;
        for(int i=1; i<=n; i++){
            scanf("%d", len+i);
            lft[i] = m+1;

            for(int j=1; j<=len[i]; j++){
                p[j].read();

                if(j != 1){
                    P[++m] = p[j] - p[j-1];
                }
                if(j == len[i]){
                    P[++m] = p[1] - p[j];
                }
            }

            rgt[i] = m;
        }

        for(int i=1; i<=m; i++){
            P[i].id = i;
            s[i] = 0;
        }

        sort(P+1, P+1+m);

        int l = 0;
        idx[P[1].id] = ++l;

        for(int i=2; i<=m; i++){
            if(P[i-1].x * P[i].y - P[i-1].y * P[i].x == 0){
                idx[P[i].id] = l;
            } else {
                idx[P[i].id] = ++l;
            }
        }

        for(int i=1; i<=l; i++){
            s[i] = 0;
            pre[i] = -1;
        }

        scanf("%d", &Q);
        for(int i=0; i<Q; i++){
            que[i].read(i);
        }
        sort(que, que+Q);

        int j = 0;
        for(int i=1; i<=m; i++){
            if(pre[idx[i]] != -1){
                add(pre[idx[i]], -1);
            }
            add(i, 1);
            pre[idx[i]] = i;

            while(j < Q && que[j].r == i){
                ans[que[j].id] = sum(que[j].r) - sum(que[j].l - 1);
                j++;
            }
        }

        for(int i=0; i<Q; i++){
            printf("%d\n", ans[i]);
        }
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 3e5 + 10;
int n, Q, m, a[N], lft[N], rgt[N], G[N], ans[N];
int place[N], tot;
set<int> ST;
set<int>::iterator it;

struct Point{
    int idx;
    LL x, y;
    bool sig;
    Point(){}
    Point(LL x, LL y):x(x),y(y){
        sig = y>0 || (y==0 && x>0);
    }
    void read(){
        scanf("%I64d %I64d", &x, &y);
        sig = y>0 || (y==0 && x>0);
    }
    Point operator + (Point A){
        return Point(x + A.x, y + A.y);
    }
    Point operator - (Point A){
        return Point(x - A.x, y - A.y);
    }
    bool operator < (const Point &A) const {
        if(sig != A.sig){
            return sig > A.sig;
        }
        return (x * A.y - y * A.x) > 0;
    }
};
Point P[N], p[N];

struct Que{
    int id, l, r;
    void read(int idx){
        id = idx;
        scanf("%d %d", &l, &r);
        l = lft[l];
        r = rgt[r];
    }
    bool operator < (const Que &A)const{
        return G[l] < G[A.l] || (G[l] == G[A.l] && r < A.r);
    }
}que[N];

bool ok(int i, int j){
    if(i == -1 || j == -1)  return 0;
    return (P[i].x*P[j].y - P[i].y*P[j].x) != 0;
}

void add(int i){
    int p = place[i];
    ST.insert(p);
    it = ST.find(p);

    int j = -1;
    if(it != ST.begin()){
        it--;
        j = *it;
        it++;
    }

    it++;
    int k = -1;
    if(it != ST.end()){
        k = *it;
    }

    if(ok(j, k))    tot--;
    if(ok(j, p))    tot++;
    if(ok(p, k))    tot++;

    if(ST.size() == 1){
        tot = 1;
    }
}

void sub(int i){
    int p = place[i];
    it = ST.find(p);

    int j = -1;
    if(it != ST.begin()){
        it--;
        j = *it;
        it++;
    }

    it++;
    int k = -1;
    if(it != ST.end()){
        k = *it;
    }

    if(ok(j, k))    tot++;
    if(ok(j, p))    tot--;
    if(ok(p, k))    tot--;

    ST.erase(p);

    if(!ST.size()){
        tot = 0;
    }
}

void solve(){
    int s = (int)sqrt(m*1.0);
    for(int i=1; i<=m; i++){
        P[i].idx = i;
        G[i] = i / s;
    }
    sort(P+1, P+1+m);
    ST.clear();

    for(int i=1; i<=m; i++){
        place[P[i].idx] = i;
    }

    sort(que, que+Q);

    int L = 1, R = 0;
    tot = 0;

    for(int i=0; i<Q; i++){
        while(R < que[i].r) add(++R);
        while(R > que[i].r) sub(R--);
        while(L > que[i].l) add(--L);
        while(L < que[i].l) sub(L++);

        ans[que[i].id] = tot;
    }
}

int main(){
    scanf("%d", &n);
    m = 0;
    for(int i=1; i<=n; i++){
        scanf("%d", a+i);
        lft[i] = m+1;
        for(int j=1; j<=a[i]; j++){
            p[j].read();
            if(j!=1){
                P[++m] = p[j]-p[j-1];
            }
            if(i==n){
                P[++m] = p[1]-p[j];
            }
        }
        rgt[i] = m;
    }

    scanf("%d", &Q);
    for(int i=0; i<Q; i++){
        que[i].read(i);
    }

    solve();

    for(int i=0; i<Q; i++){
        printf("%d\n", ans[i]);
    }

	return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long LL;
const int N = 3e5 + 10;
int n, Q, m, a[N], lft[N], rgt[N], G[N], ans[N];
int place[N], tot;
set<int> ST;
set<int>::iterator it;

struct Point{
    int idx;
    LL x, y;
    bool sig;
    Point(){}
    Point(LL x, LL y):x(x),y(y){
        sig = y>0 || (y==0 && x>0);
    }
    void read(){
        scanf("%I64d %I64d", &x, &y);
        sig = y>0 || (y==0 && x>0);
    }
    Point operator + (Point A){
        return Point(x + A.x, y + A.y);
    }
    Point operator - (Point A){
        return Point(x - A.x, y - A.y);
    }
    bool operator < (const Point &A) const {
        if(sig != A.sig){
            return sig > A.sig;
        }
        return (x * A.y - y * A.x) > 0;
    }
};
Point P[N], p[N];

struct Que{
    int id, l, r;
    void read(int idx){
        id = idx;
        scanf("%d %d", &l, &r);
        l = lft[l];
        r = rgt[r];
    }
    bool operator < (const Que &A)const{
        return G[l] < G[A.l] || (G[l] == G[A.l] && r < A.r);
    }
}que[N];

bool ok(int i, int j){
    if(i == -1 || j == -1)  return 0;
    return (P[i].x*P[j].y - P[i].y*P[j].x) != 0;
}

void add(int i){
    int p = place[i];
    ST.insert(p);
    it = ST.find(p);

    int j = -1;
    if(it != ST.begin()){
        it--;
        j = *it;
        it++;
    }

    it++;
    int k = -1;
    if(it != ST.end()){
        k = *it;
    }

    if(ok(j, k))    tot--;
    if(ok(j, p))    tot++;
    if(ok(p, k))    tot++;

    if(ST.size() == 1){
        tot = 1;
    }
}

void sub(int i){
    int p = place[i];
    it = ST.find(p);

    int j = -1;
    if(it != ST.begin()){
        it--;
        j = *it;
        it++;
    }

    it++;
    int k = -1;
    if(it != ST.end()){
        k = *it;
    }

    if(ok(j, k))    tot++;
    if(ok(j, p))    tot--;
    if(ok(p, k))    tot--;

    ST.erase(p);

    if(!ST.size()){
        tot = 0;
    }
}

void solve(){
    int s = (int)sqrt(m*1.0);
    for(int i=1; i<=m; i++){
        P[i].idx = i;
        G[i] = i / s;
    }
    sort(P+1, P+1+m);
    ST.clear();

    for(int i=1; i<=m; i++){
        place[P[i].idx] = i;
    }

    sort(que, que+Q);

    int L = 1, R = 0;
    tot = 0;

    for(int i=0; i<Q; i++){
        while(R < que[i].r) add(++R);
        while(R > que[i].r) sub(R--);
        while(L > que[i].l) add(--L);
        while(L < que[i].l) sub(L++);

        ans[que[i].id] = tot;
    }
}

int main(){
    scanf("%d", &n);
    m = 0;
    for(int i=1; i<=n; i++){
        scanf("%d", a+i);
        lft[i] = m+1;
        for(int j=1; j<=a[i]; j++){
            p[j].read();
            if(j!=1){
                P[++m] = p[j]-p[j-1];
            }
            if(j==a[i]){
                P[++m] = p[1]-p[j];
            }
        }
        rgt[i] = m;
    }

    scanf("%d", &Q);
    for(int i=0; i<Q; i++){
        que[i].read(i);
    }

    solve();

    for(int i=0; i<Q; i++){
        printf("%d\n", ans[i]);
    }

	return 0;
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <utility>
#include <sstream>
#include <iostream>
#include <algorithm>
// #include <unordered_map>
#define SZ(a) ((int)(a.size()))
#define rep(i,a,n) for(int i=a;i<n;++i)
#define per(i,a,n) for(int i=(n)-1;i>=a;--i)
#define foredge(u,i) for(int i=head[u];~i;i=l[i].nxt)
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
#ifdef LOCAL
template<class T>void print_array(T *a,T *end){printf("#[");for(;a<end;++a)cout<<(*a)<<',';cout<<"\b]\n";};
template<class T>ostream &operator<<(ostream&os,vector<T>V){os<<"[";for(auto vv:V)os<<vv<<",";return os<<"\b]";}
void dbg(){cout<<"\b \n";}
template<typename T,typename...A>void dbg(T a,A...x){cout<<(a)<<',';dbg(x...);}
#define LOG(x...) {cout<<'#';dbg(x);}
#else
#define print_array(...)
#define LOG(...)
#endif
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
typedef pair<int,int> pii;
const double PI=acos(-1.0);
const double EPS=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
inline ll readll(){
	ll x(0),op(1);char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')op=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*op;
}
ll gcd(ll a,ll b){
	if(b==0) return a;
	return gcd(b,a%b);
}
//闵可夫斯基和凸包上的点等于向量种类数
const int sz=100009;
// vector<vector<P>> cs;
struct P{
	ll x,y;
	P(ll x,ll y):x(x),y(y){}
	P operator-(P p) {return P(x-p.x,y-p.y);}
	P simp(){ll d=abs(gcd(x,y));return P(x/d,y/d);}
	bool operator<(const P &q)const {return make_pair(x,y)<make_pair(q.x,q.y);}
};
int L[sz],R[sz];
vector<P> ps;
struct Q{
	int l,r,id;
	bool operator<(const Q &q)const {return r<q.r;}
}q[sz];
int ans[sz];
struct BIT{
	#define lowbit(x) ((x)&(-x))
	static const int BIT_SZ=1e6+9;
	ll bit[BIT_SZ+1];//BIT数组
	ll p[BIT_SZ+1];//单点值
	int n;
	void init(int nn){
		rep(i,0,nn+5) bit[i]=p[i]=0;
		n=nn;
	}
	//点修改
	void add(int i,ll x){
		while(i<=n) bit[i]+=x, i+=lowbit(i);
		p[i]+=x;
	}
	//点置值
	void set(int i,ll x){
		add(i,x-p[i]);
		p[i]=x;
	}
	ll get(int i){return p[i];}
	//[1:i]区间和
	ll sum(int i){
		if(i<=0) return 0;
		ll s=0;
		while(i) s+=bit[i], i-=lowbit(i);
		return s;
	}
	//查询区间和
	ll query(int l,int r){
		if(l>=r) return 0;
		return sum(r-1)-sum(l-1);
	}
} bit;
map<P,int> mpre;
int main(){
	int n=readll();
	ps.push_back(P(INF,INF));
	rep(i,0,n){
		vector<P> v;
		int cnt=readll();
		rep(i,0,cnt){
			ll x=readll(),y=readll();
			v.push_back({x,y});
		}
		L[i]=SZ(ps);
		rep(i,0,cnt){
			ps.push_back((v[(i+1)%cnt]-v[i]).simp());
		}
		R[i]=SZ(ps);
	}
	int m=readll();
	rep(i,0,m){
		q[i].l=L[readll()-1],q[i].r=R[readll()-1];q[i].id=i;
	}
	sort(q,q+m);
	int curr=1;
	bit.init(SZ(ps)+5);
	rep(i,0,m){
		// LOG(q[i].l,q[i].r);
		while(curr<q[i].r) {//add curr
			if(mpre[ps[curr]]) bit.add(mpre[ps[curr]],-1);
			bit.add(curr,1);
			mpre[ps[curr]]=curr;
			curr++;
		}
		ans[q[i].id]=bit.query(q[i].l,q[i].r);
	}
	rep(i,0,m){
		printf("%d\n",ans[i]);
	}
	return 0;
}


#include <stdio.h>
#include <cstring>
#include <cmath>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <utility>
#include <sstream>
#include <iostream>
#include <algorithm>
// #include <unordered_map>
#define SZ(a) ((int)(a.size()))
#define rep(i,a,n) for(int i=a;i<n;++i)
#define per(i,a,n) for(int i=(n)-1;i>=a;--i)
#define foredge(u,i) for(int i=head[u];~i;i=l[i].nxt)
#define mem(a,x) memset(a,x,sizeof(a))
using namespace std;
#ifdef LOCAL
template<class T>void print_array(T *a,T *end){printf("#[");for(;a<end;++a)cout<<(*a)<<',';cout<<"\b]\n";};
template<class T>ostream &operator<<(ostream&os,vector<T>V){os<<"[";for(auto vv:V)os<<vv<<",";return os<<"\b]";}
void dbg(){cout<<"\b \n";}
template<typename T,typename...A>void dbg(T a,A...x){cout<<(a)<<',';dbg(x...);}
#define LOG(x...) {cout<<'#';dbg(x);}
#else
#define print_array(...)
#define LOG(...)
#endif
typedef long long ll;
typedef vector<ll> vec;
typedef vector<vec> mat;
typedef pair<int,int> pii;
const double PI=acos(-1.0);
const double EPS=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
inline ll readll(){
	ll x(0),op(1);char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')op=-1;ch=getchar();}
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*op;
}
//闵可夫斯基和凸包上的点等于向量种类数
const int sz=100009;
// vector<vector<P>> cs;
struct P{
	ll x,y;
	P(ll x,ll y):x(x),y(y){}
	P operator-(P p) {return P(x-p.x,y-p.y);}
	bool operator<(const P &q)const {return make_pair(x,y)<make_pair(q.x,q.y);}
};
int L[sz],R[sz];
vector<P> ps;
struct Q{
	int l,r,id;
	bool operator<(const Q &q)const {return r<q.r;}
}q[sz];
int ans[sz];
struct BIT{
	#define lowbit(x) ((x)&(-x))
	static const int BIT_SZ=1e6+9;
	ll bit[BIT_SZ+1];//BIT数组
	ll p[BIT_SZ+1];//单点值
	int n;
	void init(int nn){
		rep(i,0,nn+5) bit[i]=p[i]=0;
		n=nn;
	}
	//点修改
	void add(int i,ll x){
		while(i<=n) bit[i]+=x, i+=lowbit(i);
		p[i]+=x;
	}
	//点置值
	void set(int i,ll x){
		add(i,x-p[i]);
		p[i]=x;
	}
	ll get(int i){return p[i];}
	//[1:i]区间和
	ll sum(int i){
		if(i<=0) return 0;
		ll s=0;
		while(i) s+=bit[i], i-=lowbit(i);
		return s;
	}
	//查询区间和
	ll query(int l,int r){
		if(l>=r) return 0;
		return sum(r-1)-sum(l-1);
	}
} bit;
map<P,int> mpre;
int main(){
	int n=readll();
	ps.push_back(P(INF,INF));
	rep(i,0,n){
		vector<P> v;
		int cnt=readll();
		rep(i,0,cnt){
			ll x=readll(),y=readll();
			v.push_back({x,y});
		}
		L[i]=SZ(ps);
		rep(i,0,cnt){
			ps.push_back({v[(i+1)%cnt]-v[i]});
		}
		R[i]=SZ(ps);
	}
	int m=readll();
	rep(i,0,m){
		q[i].l=L[readll()-1],q[i].r=R[readll()-1];q[i].id=i;
	}
	sort(q,q+m);
	int curr=1;
	bit.init(SZ(ps)+5);
	rep(i,0,m){
		// LOG(q[i].l,q[i].r);
		while(curr<q[i].r) {//add curr
			if(mpre[ps[curr]]) bit.add(mpre[ps[curr]],-1);
			bit.add(curr,1);
			mpre[ps[curr]]=curr;
			curr++;
		}
		ans[q[i].id]=bit.query(q[i].l,q[i].r);
	}
	rep(i,0,m){
		printf("%d\n",ans[i]);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
#define cri const register int
#define re register
using namespace std;
int n,q,num[100010],ans[100010],c[100010],sum[100010];
inline int add(cri x,cri y){
	for(int i=x;i;i-=i&-i) c[i]+=y;
}
inline int get(cri x,int ans=0){
	for(int i=x;i<=n;i+=i&-i) ans+=c[i];
	return ans;
}
vector<pair<int,int> >has[100010],qy[100010];
map<pair<int,int>,int>mp;
inline pair<int,int> operator - (const pair<int,int>&A,const pair<int,int>&B){
	return make_pair(B.first-A.first,B.second-A.second);
}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%d",&num[i]);has[i].resize(num[i]+1);
		for(int j=0,x,y;j<num[i];j++){
			scanf("%d%d",&x,&y);
			has[i][j]=make_pair(x,y);
		}
		has[i][num[i]]=has[i][0];
		for(int j=0;j<num[i];j++){
			has[i][j]=has[i][j+1]-has[i][j];
			cri d=abs(__gcd(has[i][j].first,has[i][j].second));
			has[i][j].first/=d;has[i][j].second/=d;
		}
		sum[i]=sum[i-1]+num[i];
	}
	scanf("%d",&q);
	for(int i=1,l,r;i<=q;i++) {
		scanf("%d%d",&l,&r);
		qy[r].push_back(make_pair(l,i));
	}
	for(int i=1;i<=n;i++){
		for(int j=0;j<num[i];j++){
			add(mp[has[i][j]],-1);
			//cout<<i<<" "<<mp[has[i][j]]<<endl;
			mp[has[i][j]]=i;
		}
		for(pair<int,int>x:qy[i]) ans[x.second]=get(x.first)+sum[i]-sum[x.first-1];
	}
	for(int i=1;i<=q;i++) printf("%d\n",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> point;
#define fi first
#define se second
const int N = 1e5 + 7;

point operator - (const point &a, const point &b) {
	return point(a.fi - b.fi, a.se - b.se);
}
map<point, int> ct;
int cnt;
int k[N], aa[N*3];
struct Query {
	int l, r, id;
	bool operator < (const Query &rhs) const {
		return l < rhs.l;
	}
} Q[N];

int main() {
#ifdef local
	freopen("in.txt", "r", stdin);
#endif
	int n; scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &k[i]);
		vector<point> a(k[i]);
        for(int j = 0; j < k[i]; j++)
			scanf("%d%d", &a[j].fi, &a[j].se);
		for(int j = 0; j < k[i]; j++) {
            point t = a[j] - a[(j+1)%k[i]];
			int d = abs(__gcd(t.fi, t.se));
			t.fi /= d, t.se /= d;
			if(!ct.count(t)) ct[t] = ++cnt;
			aa[k[i-1]+j+1] = ct[t];
		}
		k[i] += k[i-1];
	}
	int q; scanf("%d", &q);
    for(int i = 0, l, r; i < q; i++) {
		scanf("%d%d", &l, &r);
		Q[i] = {k[l-1], k[r], i};
    }
    vector<int> bit(k[n] + 1, 0);
    auto add = [&](int x) {
        for(; x <= k[n]; x += x&-x)
			bit[x]++;
    };
    auto sum = [&](int x) {
        int ret = 0;
        for(; x; x -= x&-x)
			ret += bit[x];
		return ret;
    };
    sort(Q, Q + q);
    vector<int> lst(k[n] + 1, 0), nxt(k[n] + 1, 0);
    for(int i = 1; i <= k[n]; i++) {
        if(lst[aa[i]]) {
			nxt[lst[aa[i]]] = i;
        } else add(i);
        lst[aa[i]] = i;
    }
	vector<int> ans(q);
    for(int i = 0, l = 1; i < q; i++) {
        while(l <= k[n] && l <= Q[i].l) {
			if(nxt[aa[l]])add(nxt[aa[l]]);
			l++;
        }
        ans[Q[i].id] = sum(Q[i].r) - sum(Q[i].l);
    }
    for(int i = 0; i < q; i++) printf("%d\n", ans[i]);

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> point;
#define fi first
#define se second
const int N = 1e5 + 7;

point operator - (const point &a, const point &b) {
	return point(a.fi - b.fi, a.se - b.se);
}
map<point, int> ct;
int cnt;
int k[N], aa[N*3];
struct Query {
	int l, r, id;
	bool operator < (const Query &rhs) const {
		return l < rhs.l;
	}
} Q[N];

int main() {
#ifdef local
	freopen("in.txt", "r", stdin);
#endif
	int n; scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &k[i]);
		vector<point> a(k[i]);
        for(int j = 0; j < k[i]; j++)
			scanf("%d%d", &a[j].fi, &a[j].se);
		for(int j = 0; j < k[i]; j++) {
            point t = a[j] - a[(j+1)%k[i]];
			int d = abs(__gcd(t.fi, t.se));
			t.fi /= d, t.se /= d;
			if(!ct.count(t)) ct[t] = ++cnt;
			aa[k[i-1]+j+1] = ct[t];
		}
		k[i] += k[i-1];
	}
	int q; scanf("%d", &q);

    for(int i = 0, l, r; i < q; i++) {
		scanf("%d%d", &l, &r);
		Q[i] = {k[l-1], k[r], i};
    }
    vector<int> bit(k[n] + 1, 0);
    auto add = [&](int x) {
        for(; x <= k[n]; x += x&-x)
			bit[x]++;
    };
    auto sum = [&](int x) {
        int ret = 0;
        for(; x; x -= x&-x)
			ret += bit[x];
		return ret;
    };
    sort(Q, Q + q);
    vector<int> lst(k[n] + 1, 0), nxt(k[n] + 1, 0);
    for(int i = 1; i <= k[n]; i++) {
        if(lst[aa[i]]) {
			nxt[lst[aa[i]]] = i;
        } else add(i);
        lst[aa[i]] = i;
    }
	vector<int> ans(q);
    for(int i = 0, l = 1; i < q; i++) {
        while(l <= k[n] && l <= Q[i].l) {
			if(nxt[l]) add(nxt[l]);
			l++;
        }
        ans[Q[i].id] = sum(Q[i].r) - sum(Q[i].l);
    }
    for(int i = 0; i < q; i++) printf("%d\n", ans[i]);

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> point;
#define fi first
#define se second
const int N = 1e5 + 7;

point operator - (const point &a, const point &b) {
	return point(a.fi - b.fi, a.se - b.se);
}
map<point, int> ct;
int cnt;
int k[N], aa[N*3];
struct Query {
	int l, r, id;
	bool operator < (const Query &rhs) const {
		return l < rhs.l;
	}
} Q[N];

int main() {
#ifdef local
	freopen("in.txt", "r", stdin);
#endif
	int n; scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		scanf("%d", &k[i]);
		vector<point> a(k[i]);
        for(int j = 0; j < k[i]; j++)
			scanf("%d%d", &a[j].fi, &a[j].se);
		for(int j = 0; j < k[i]; j++) {
            point t = a[j] - a[(j+1)%k[i]];
			int d = abs(__gcd(t.fi, t.se));
			t.fi /= d, t.se /= d;
			if(!ct.count(t)) ct[t] = ++cnt;
			aa[k[i-1]+j+1] = ct[t];
		}
		k[i] += k[i-1];
	}
	int q; scanf("%d", &q);

    for(int i = 0, l, r; i < q; i++) {
		scanf("%d%d", &l, &r);
		int cc = 0;
		bool vis[100]; memset(vis, 0, sizeof vis);
		for(int i = k[l-1]+1; i <= k[r]; i++)
            if(!vis[aa[i]]) cc++, vis[aa[i]] = 1;
		Q[i] = {k[l-1], k[r], i};
    }
    vector<int> bit(k[n] + 1, 0);
    auto add = [&](int x) {
        for(; x <= k[n]; x += x&-x)
			bit[x]++;
    };
    auto sum = [&](int x) {
        int ret = 0;
        for(; x; x -= x&-x)
			ret += bit[x];
		return ret;
    };
    sort(Q, Q + q);
    vector<int> lst(k[n] + 1, 0), nxt(k[n] + 1, 0);
    for(int i = 1; i <= k[n]; i++) {
        if(lst[aa[i]]) {
			nxt[lst[aa[i]]] = i;
        } else add(i);
        lst[aa[i]] = i;
    }
	vector<int> ans(q);
    for(int i = 0, l = 1; i < q; i++) {
        while(l <= k[n] && l <= Q[i].l) {
			if(nxt[l]) add(nxt[l]);
			l++;
        }
        ans[Q[i].id] = sum(Q[i].r) - sum(Q[i].l);
    }
    for(int i = 0; i < q; i++) printf("%d\n", ans[i]);

	return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct node
{
	long long x,y;
	bool operator < (const node s)const
	{
		if(x==s.x)return y<s.y;
		return x<s.x;
	}
}ve[300005],poly[300005],qu[300005];
long long n,q,cnt,l[300005],r[300005],ans[300005];
vector<int> g[300005];
map<node,int>pre;
struct node2
{
	long long l,r,he;
}tree[300005<<2];

node jian(node a,node b)
{
	node s;
	s.x=a.x-b.x;
	s.y=a.y-b.y;
	long long p=__gcd(abs(s.x),abs(s.y));
	//long longp=1;
	s.x/=p;
	s.y/=p;
	return s;
}

void build(long long l,long long r,long long num)
{
	tree[num].l=l;tree[num].r=r;
	if(l+1==r)
	{
		tree[num].he=0;return ;
	}
	long long m=(l+r)>>1;
	build(l,m,num<<1);build(m,r,num<<1|1);
	tree[num].he=tree[num<<1].he+tree[num<<1|1].he;
}

void change(long long l,long long r,long long de,long long num)
{
	if(tree[num].l==l&&tree[num].r==r)
	{
		tree[num].he+=de;
		return ;
	}
	long long m=(tree[num].l+tree[num].r)>>1;
	if(r<=m)change(l,r,de,num<<1);
	else if(l>=m)change(l,r,de,num<<1|1);
	tree[num].he=tree[num<<1].he+tree[num<<1|1].he;
	return ;
}

long long qiuhe(long long l,long long r,long long num)
{
	if(l>=r)return 0;
	if(tree[num].l==l&&tree[num].r==r)
	{
		return tree[num].he;
	}
	long long m=(tree[num].l+tree[num].r)>>1;
	if(r<=m)return qiuhe(l,r,num<<1);
	else if(l>=m)return qiuhe(l,r,num<<1|1);
	else return qiuhe(l,m,num<<1)+qiuhe(m,r,num<<1|1);
}

int main()
{
	scanf("%I64d",&n);
	for(long long i=1;i<=n;i++)
	{
		long long k;
		scanf("%I64d",&k);
		for(long long j=1;j<=k;j++)
		{
			scanf("%I64d%I64d",&poly[j].x,&poly[j].y);
			//printf("***%d %d\n",poly[j].x,poly[j].y);
		}
		poly[k+1]=poly[1];
		l[i]=cnt+1;
		for(long long j=1;j<=k;j++)
		{
		//	printf("%d %d %d %d\n",poly[j+1].x,poly[j+1].y,poly[j].x,poly[j].y);
			ve[++cnt]=jian(poly[j+1],poly[j]);
		}
		r[i]=cnt;
	}
	build(1,cnt+1,1);
	scanf("%I64d",&q);
	for(long long i=1;i<=q;i++)
	{
		scanf("%I64d%I64d",&qu[i].x,&qu[i].y);
		qu[i].x=l[qu[i].x];
		qu[i].y=r[qu[i].y];
		g[qu[i].y].push_back(i);
	}
	for(long long i=1;i<=cnt;i++)
	{
		if(pre[ve[i]])change(pre[ve[i]],pre[ve[i]]+1,-1,1);
		pre[ve[i]]=i;
		change(i,i+1,1,1);
		long long len=g[i].size();
		for(long long j=0;j<len;j++)
		{
			ans[g[i][j]]=qiuhe(qu[g[i][j]].x,qu[g[i][j]].y+1,1);
		}
	}
	for(long long i=1;i<=q;i++)
	{
		printf("%I64d\n",ans[i]);
	}
	return 0;
}


#include <iostream>
#include <algorithm>
#include <cstdio>
#include <queue>
#include <map>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define pb push_back
using namespace std;
typedef pair<int,int> pii;
const int N = 1e6+10;
int n, q, cnt, x[N], y[N], c[N];
int L[N], R[N], ans[N];
struct _ {int l,r;} b[N];
vector<int> g[N];
pii a[N];
map<pii,int> pre;

int gcd(int a,int b) {return b?gcd(b,a%b):a;}
pii reduce(int x, int y) {
    int g = gcd(abs(x),abs(y));
    if (g) x/=g,y/=g;
    return pii(x,y);
}
void add(int x, int v) {
    for (; x<=cnt; x+=x&-x) c[x]+=v;
}
int query(int x) {
    int r = 0;
    for (; x; x^=x&-x) r+=c[x];
    return r;
}

int main() {
    scanf("%d", &n);
    REP(i,1,n) {
        int k;
        scanf("%d", &k);
        REP(j,0,k-1) scanf("%d%d",x+j,y+j);
        L[i] = cnt+1;
        REP(j,0,k-1) a[++cnt] = reduce(x[j]-x[(j+1)%k],y[j]-y[(j+1)%k]);
        R[i] = cnt;
    }
    scanf("%d", &q);
    REP(i,1,q) {
        int l, r;
        scanf("%d%d", &l, &r);
        b[i].l = L[l];
        b[i].r = R[r];
        g[b[i].r].pb(i);
    }
    int now = 1;
    REP(i,1,cnt) {
        if (pre[a[i]]) add(pre[a[i]],-1);
        pre[a[i]] = i;
        add(i,1);
        for (int j:g[i]) ans[j] = query(b[j].r)-query(b[j].l-1);
    }
    REP(i,1,q) printf("%d\n", ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
struct node
{
	int x,y;
	bool operator < (const node s)const
	{
		if(x==s.x)return y<s.y;
		return x<s.x;
	}
}ve[300005],poly[300005],qu[300005];
int n,q,cnt,l[300005],r[300005],ans[300005];
vector<int> g[300005];
map<node,int>pre;
struct node2
{
	int l,r,he;
}tree[1000006];

node jian(node a,node b)
{
	node s;
	s.x=a.x-b.x;
	s.y=a.y-b.y;
	int p=__gcd(abs(s.x),abs(s.y));
	//int p=1;
	s.x/=p;
	s.y/=p;
	return s;
}

void build(int l,int r,int num)
{
	tree[num].l=l;tree[num].r=r;
	if(l+1==r)
	{
		tree[num].he=0;return ;
	}
	int m=(l+r)>>1;
	build(l,m,num<<1);build(m,r,num<<1|1);
	tree[num].he=tree[num<<1].he+tree[num<<1|1].he;
}

void change(int l,int r,int de,int num)
{
	if(tree[num].l==l&&tree[num].r==r)
	{
		tree[num].he+=de;
		return ;
	}
	int m=(tree[num].l+tree[num].r)>>1;
	if(r<=m)change(l,r,de,num<<1);
	else if(l>=m)change(l,r,de,num<<1|1);
	tree[num].he=tree[num<<1].he+tree[num<<1|1].he;
	return ;
}

int qiuhe(int l,int r,int num)
{
	if(l>=r)return 0;
	if(tree[num].l==l&&tree[num].r==r)
	{
		return tree[num].he;
	}
	int m=(tree[num].l+tree[num].r)>>1;
	if(r<=m)return qiuhe(l,r,num<<1);
	else if(l>=m)return qiuhe(l,r,num<<1|1);
	else return qiuhe(l,m,num<<1)+qiuhe(m,r,num<<1|1);
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int k;
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			scanf("%d%d",&poly[j].x,&poly[j].y);
			//printf("***%d %d\n",poly[j].x,poly[j].y);
		}
		poly[k+1]=poly[1];
		l[i]=cnt+1;
		for(int j=1;j<=k;j++)
		{
		//	printf("%d %d %d %d\n",poly[j+1].x,poly[j+1].y,poly[j].x,poly[j].y);
			ve[++cnt]=jian(poly[j+1],poly[j]);
		}
		r[i]=cnt;
	}
	build(1,cnt+1,1);
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d",&qu[i].x,&qu[i].y);
		qu[i].x=l[qu[i].x];
		qu[i].y=r[qu[i].y];
		g[qu[i].y].push_back(i);
	}
	for(int i=1;i<=cnt;i++)
	{
		if(pre[ve[i]])change(pre[ve[i]],pre[ve[i]]+1,-1,1);
		pre[ve[i]]=i;
		change(i,i+1,1,1);
		int len=g[i].size();
		for(int j=0;j<len;j++)
		{
			ans[g[i][j]]=qiuhe(qu[g[i][j]].x,qu[g[i][j]].y+1,1);
		}
	}
	for(int i=1;i<=q;i++)
	{
		printf("%d\n",ans[i]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct node
{
	int x,y;
	bool operator < (const node s)const
	{
		if(x==s.x)return y<s.y;
		return x<s.x;
	}
}ve[300005],poly[300005],qu[300005];
int n,q,cnt,l[300005],r[300005],ans[300005];
vector<int> g[300005];
map<node,int>pre;
struct node2
{
	int l,r,he;
}tree[1000006];

node jian(node a,node b)
{
	node s;
	s.x=a.x-b.x;
	s.y=a.y-b.y;
//	int p=__gcd(s.x,s.y);
	int p=1;
	s.x/=p;
	s.y/=p;
	return s;
}

void build(int l,int r,int num)
{
	tree[num].l=l;tree[num].r=r;
	if(l+1==r)
	{
		tree[num].he=0;return ;
	}
	int m=(l+r)>>1;
	build(l,m,num<<1);build(m,r,num<<1|1);
	tree[num].he=tree[num<<1].he+tree[num<<1|1].he;
}

void change(int l,int r,int de,int num)
{
	if(tree[num].l==l&&tree[num].r==r)
	{
		tree[num].he+=de;
		return ;
	}
	int m=(tree[num].l+tree[num].r)>>1;
	if(r<=m)change(l,r,de,num<<1);
	else if(l>=m)change(l,r,de,num<<1|1);
	tree[num].he=tree[num<<1].he+tree[num<<1|1].he;
	return ;
}

int qiuhe(int l,int r,int num)
{
	if(l>=r)return 0;
	if(tree[num].l==l&&tree[num].r==r)
	{
		return tree[num].he;
	}
	int m=(tree[num].l+tree[num].r)>>1;
	if(r<=m)return qiuhe(l,r,num<<1);
	else if(l>=m)return qiuhe(l,r,num<<1|1);
	else return qiuhe(l,m,num<<1)+qiuhe(m,r,num<<1|1);
}

int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		int k;
		scanf("%d",&k);
		for(int j=1;j<=k;j++)
		{
			scanf("%d%d",&poly[j].x,&poly[j].y);
			//printf("***%d %d\n",poly[j].x,poly[j].y);
		}
		poly[k+1]=poly[1];
		l[i]=cnt+1;
		for(int j=1;j<=k;j++)
		{
		//	printf("%d %d %d %d\n",poly[j+1].x,poly[j+1].y,poly[j].x,poly[j].y);
			ve[++cnt]=jian(poly[j+1],poly[j]);
		}
		r[i]=cnt;
	}
	build(1,cnt+1,1);
	scanf("%d",&q);
	for(int i=1;i<=q;i++)
	{
		scanf("%d%d",&qu[i].x,&qu[i].y);
		qu[i].x=l[qu[i].x];
		qu[i].y=r[qu[i].y];
		g[qu[i].y].push_back(i);
	}
	for(int i=1;i<=cnt;i++)
	{
	//	printf("**%d %d\n",ve[i].x,ve[i].y);
		if(pre[ve[i]])change(pre[ve[i]],pre[ve[i]]+1,-1,1);
	//	printf("+1\n");
		pre[ve[i]]=i;
		change(i,i+1,1,1);
		int len=g[i].size();

		for(int j=0;j<len;j++)
		{
			ans[g[i][j]]=qiuhe(qu[g[i][j]].x,qu[g[i][j]].y+1,1);
		}
	}
	for(int i=1;i<=q;i++)
	{
		printf("%d\n",ans[i]);
	}
	return 0;
}


#include<map>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 300010
using namespace std;
int n,cnt,Q,tot,x[maxn],y[maxn],l[maxn],r[maxn],ans[maxn],s[maxn],p[maxn],pos[maxn],lst[maxn];
map< pair<int,int> ,int> mp;
struct point{
	int l,r,num;
	friend bool operator <(point a,point b){
		return a.r==b.r?a.l<b.l:a.r<b.r;
	}
}q[maxn];
int read()
{
	int x=0,f=1;char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return x*f;
}
int gcd(int a,int b)
{
	return b==0?a:gcd(b,a%b);
}
void add(int x,int y){
	if(!x) return ;
	while(x<=cnt){
		s[x]+=y; x+=x&(-x);
	}
}
int query(int x,int ret=0){
	while(x){ret+=s[x];x-=x&(-x);}
	return ret;
}
int main()
{
	n=read();
	for(int i=1;i<=n;i++){
		int k=read(); l[i]=cnt+1; r[i]=k+cnt;
		for(int j=1;j<=k;j++) x[++cnt]=read(),y[cnt]=read();
		x[cnt+1]=x[l[i]]; y[cnt+1]=y[l[i]];
		for(int j=l[i]+1;j<=r[i]+1;j++){
			int k=x[j]-x[j-1],h=y[j]-y[j-1],g=gcd(abs(k),abs(h));
			k/=g; h/=g; if(!mp[make_pair(k,h)]) mp[make_pair(k,h)]=++tot;
			p[j-1]=mp[make_pair(k,h)];//cerr<<k<<" "<<h<<" "<<p[j]<<endl;
		}
	}
	for(int i=1;i<=cnt;i++)
		lst[i]=pos[p[i]],pos[p[i]]=i;//,cerr<<lst[i]<<" ";
	Q=read();
	for(int i=1;i<=Q;i++) q[i].l=read(),q[i].r=read(),q[i].num=i;
	sort(q+1,q+Q+1); int now=1;
	for(int i=1;i<=Q;i++)
	{
		int L=l[q[i].l],R=r[q[i].r];
		while(now<=R&&now<=cnt) add(now,1),add(lst[now],-1),now++;
		ans[q[i].num]=query(R)-query(L-1);
	}
	for(int i=1;i<=Q;i++) printf("%d\n",ans[i]);
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define lowbit(x) (x&(-x))
using namespace std;
const int N=300010;
struct point{
    int x,y;
    point(){}
    point(int x,int y):
        x(x),y(y){}
    bool operator < (const point &r) const
    {
        if(x!=r.x) return x<r.x;
        else return y<r.y;
    }
};
struct ASK{
    int l,r,id;
}q[N];
int n,m,cnt=0;
int sum[N],b[N],ans[N],pre[N],ts[N],t[N];
vector<point> a[N];
map<point,int> ma;
inline int gcd(int x,int y)
{
    if(y==0) return x;
    return gcd(y,x%y);
}
inline void add(int x,int y)
{
    if(x==0) return;
    for(;x<=sum[n];x+=lowbit(x))
        t[x]+=y;
    return;
}
inline int find(int x)
{
    int u=0;
    for(;x;x-=lowbit(x))
        u+=t[x];
    return u;
}
inline bool cmp(ASK x,ASK y)
{
    return x.r<y.r;
}
int main()
{
//    freopen("1.in","r",stdin);
    scanf("%d",&n);
    for(int k=1;k<=n;k++)
    {
        int x;
        scanf("%d",&x);
        sum[k]=sum[k-1]+x;
        for(int i=1;i<=x;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            a[k].push_back(point(u,v));
        }
        a[k].push_back(a[k][0]);
        for(int i=0;i<a[k].size()-1;i++)
        {
            point u=point(a[k][i].x-a[k][i+1].x,a[k][i].y-a[k][i+1].y);
            int v=gcd(abs(u.x),abs(u.y));
            u.x/=v,u.y/=v;
            if(ma.count(u)) b[sum[k-1]+i+1]=ma[u];
            else ma[u]=b[sum[k-1]+i+1]=++cnt;
        }
    }
    scanf("%d",&m);
    for(int k=1;k<=m;k++)
    {
        scanf("%d%d",&q[k].l,&q[k].r);
        q[k].l=sum[q[k].l-1];
        q[k].r=sum[q[k].r];
        q[k].id=k;
    }
    sort(q+1,q+1+m,cmp);
    for(int k=1;k<=sum[n];k++)
    {
        pre[k]=ts[b[k]];
        ts[b[k]]=k;
    }
    int now=1;
    for(int k=1;k<=sum[n];k++)
    {
        add(k,1),add(pre[k],-1);
        while(now<=m&&q[now].r==k)
        {
            ans[q[now].id]=find(q[now].r)-find(q[now].l);
//            cout<<q[now].r<<" "<<q[now].l<<" "<<find(q[now].r)<<" "<<find(q[now].l)<<endl;
            now++;
        }
    }
    for(int k=1;k<=m;k++)
        printf("%d\n",ans[k]);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

const static int maxn = 3e5 + 5;

int bg[maxn], ed[maxn];

pair<int, int> org[maxn], plc[maxn], pos[maxn];
struct Que
{
    int l, r, p;
} que[maxn];
inline bool operator < (Que a, Que b) {return a.r < b.r;}

int id[maxn], la[maxn], ans[maxn];

inline int gcd(int x, int y)
{
    if (abs(y) > abs(x))
        swap(x, y);
    while (y != 0) {
        x %= y;
        swap(x, y);
    }
    return x;
}

int N, tot = 0;

#define lowbit(x) ((x) & (-(x)))
int bit[maxn];
inline void add(int x, int v)
{
    while (x <= tot) {
        bit[x] += v;
        x += lowbit(x);
    }
}
inline int query(int x)
{
    int res = 0;
    while (x) {
        res += bit[x];
        x -= lowbit(x);
    }
    return res;
}

int main()
{
    cin >> N;
    for (int i = 1; i <= N; ++i) {
        int k;
        cin >> k;
        const int bas = tot;
        bg[i] = bas;
        ed[i] = bas + k - 1;
        for (int j = 0; j < k; ++j)
            cin >> pos[tot].first >> pos[tot].second, ++tot;
        for (int j = 0; j < k; ++j) {
            const int p = bas + j, q = bas + (j + 1) % k;
            org[p].second = pos[p].second - pos[q].second;
            org[p].first = pos[p].first - pos[q].first;
            const int g = abs(gcd(org[p].first, org[p].second));
            org[p].first /= g;
            org[q].first /= g;
        }
    }
    copy(org, org + tot, plc);
    sort(plc, plc + tot);
    for (int i = 0; i < tot; ++i)
        id[i] = lower_bound(plc, plc + tot, org[i]) - plc;
    int Q;
    cin >> Q;
    for (int i = 0; i < Q; ++i)
        cin >> que[i].l >> que[i].r, que[i].p = i, que[i].r = ed[que[i].r], que[i].l = bg[que[i].l];
    sort(que, que + Q);
    int q = 0;
    for (int i = 0; i < Q; ++i) {
        while (q <= que[i].r) {
            add(q + 1, 1);
            if (la[id[q]])
                add(la[id[q]], -1);
            la[id[q]] = q + 1;
            ++q;
        }
        ans[que[i].p] = query(que[i].r + 1) - query(que[i].l);
    }
    copy(ans, ans + Q, ostream_iterator<int>(cout, "\n"));
    return 0;
}


#include <bits/stdc++.h>

typedef unsigned long long LL;
typedef std::pair<int, int> point;
const int N = 300005;

#define x first
#define y second

std::map<LL, int> pre;

point operator - (point a, point b) {return point(a.x - b.x, a.y - b.y);}
LL slope(point a, point b) {
	point c = a - b;
	int k = std::abs(std::__gcd(c.x, c.y));
	c.x /= k, c.y /= k;
	return (LL) c.x << 32 | (unsigned) c.y;
}

std::vector<point> query[N];
point p[N];

LL val[N];
int n, m, q, bit[N], ans[N], l[N], r[N];

void b_add(int x, int v) {
	for (; x; x &= x - 1) bit[x] += v;
}
int b_query(int x, int ret = 0) {
	for (; x <= m; x += x & -x) ret += bit[x];
	return ret;
}
int main() {
	std::ios::sync_with_stdio(0), std::cin.tie(0);
	std::cin >> n;
	for (int i = 1; i <= n; ++i) {
		int k; std::cin >> k, l[i] = m + 1, r[i] = m += k;
		for (int j = 0; j < k; ++j)
			std::cin >> p[j].x >> p[j].y;
		p[k] = p[0];
		for (int j = 0; j < k; ++j)
			val[l[i] + j] = slope(p[j], p[j + 1]);
	}
	std::cin >> q;
	for (int i = 0; i < q; ++i) {
		int L, R; std::cin >> L >> R;
		query[r[R]].emplace_back(l[L], i);
	}
	for (int i = 1; i <= m; ++i) {
		b_add(i, 1), b_add(pre[val[i]], -1), pre[val[i]] = i;
		for (point p : query[i]) ans[p.y] = b_query(p.x);
	}
	for (int i = 0; i < q; ++i) std::cout << ans[i] << '\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 300050
#define LL long long
using namespace std;
struct node{double x,y;}a[N];
vector<double>v[N];
struct node2{
	int l,r,id;
	friend bool operator<(const node2 &a,const node2 &b){
		return a.r<b.r;
	}
}q[N];
int ans[N];
int n,ls,m,las[N];
double lsh[N];
int ct[N];
inline void add(int x,int num){
	while(x<=n)ct[x]+=num,x+=x&-x;
}
inline int ask(int x,int ret=0){
	while(x)ret+=ct[x],x-=x&-x;return ret;
}
int main(){
	cin>>n;
	for(int i=1,k;i<=n;++i){
		scanf("%d",&k);
		v[i].resize(k);
		for(int j=1;j<=k;++j)
			scanf("%lf%lf",&a[j].x,&a[j].y);
		a[0]=a[k];
		for(int j=0;j<k;++j)
			lsh[++ls]=v[i][j]=atan2(a[j+1].y-a[j].y,a[j+1].x-a[j].x);
	}
	sort(lsh+1,lsh+ls+1);
	ls=unique(lsh+1,lsh+ls+1)-lsh-1;
//	for(int i=1;i<=ls;++i)cout<<lsh[i]<<" ";puts("");
	cin>>m;
	for(int i=1;i<=m;++i)
		scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
	sort(q+1,q+m+1);
	for(int i=1,j=1;i<=n;++i){
		for(double k:v[i]){
			int t=lower_bound(lsh+1,lsh+ls+1,k)-lsh;
//			cout<<k<<" "<<t<<endl;
			if(las[t]==i)continue;
			if(las[t])add(las[t],-1);
			las[t]=i;add(i,1);
		}
		while(j<=m&&q[j].r==i){
//			printf("%d %d %d %d\n",q[j].l,q[j].r,ask(q[j].r),ask(q[j].l-1));
			ans[q[j].id]=ask(q[j].r)-ask(q[j].l-1);
			++j;
		}
	}
	for(int i=1;i<=m;++i)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define N 300050
using namespace std;
struct node{int x,y;}a[N];
vector<pair<int,int> >v[N];
struct node2{
	int l,r,id;
	friend bool operator<(const node2 &a,const node2 &b){
		return a.r<b.r;
	}
}q[N];
inline int gcd(int a,int b){
	return b?gcd(b,a%b):a;
}
int ans[N];
int n,m;
map<pair<int,int>,int>h;
int tot,las[N];
int ct[N];
inline void add(int x,int num){
	while(x<=n)ct[x]+=num,x+=x&-x;
}
inline int ask(int x,int ret=0){
	while(x)ret+=ct[x],x-=x&-x;return ret;
}
int main(){
	cin>>n;
	for(int i=1,k;i<=n;++i){
		scanf("%d",&k);
		v[i].resize(k);
		for(int j=1;j<=k;++j)
			scanf("%d%d",&a[j].x,&a[j].y);
		a[0]=a[k];
		for(int j=0;j<k;++j){
			v[i][j]=make_pair(a[j+1].y-a[j].y,a[j+1].x-a[j].x);
			int gc=gcd(abs(v[i][j].first),abs(v[i][j].second));
			if(gc)v[i][j].first/=gc,v[i][j].second/=gc;
			if(!h[v[i][j]])h[v[i][j]]=++tot;
		}
	}
	cin>>m;
	for(int i=1;i<=m;++i)
		scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
	sort(q+1,q+m+1);
	for(int i=1,j=1;i<=n;++i){
		for(pair<int,int> k:v[i]){
			int t=h[k];
//			cout<<k<<" "<<t<<endl;
			if(las[t]==i)continue;
			if(las[t])add(las[t],-1);
			las[t]=i;add(i,1);
		}
		while(j<=m&&q[j].r==i){
//			printf("%d %d %d %d\n",q[j].l,q[j].r,ask(q[j].r),ask(q[j].l-1));
			ans[q[j].id]=ask(q[j].r)-ask(q[j].l-1);
			++j;
		}
	}
	for(int i=1;i<=m;++i)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
using namespace std;
const int N=3e5+7;
inline int read(){
	int x=0; bool f=0; char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f=(ch=='-');
	for(;isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return f?-x:x;
}

int n,Q,id,len;
int l[N],r[N],v[N],pre[N];
struct que{int l,r,id;}q[N];
inline bool jud(que a,que b){return a.r<b.r;}

int bit[N],ans[N];
inline void add(int p,int v){for(;p;p-=lowbit(p)) bit[p]+=v;}
inline int query(int p,int v=0){for(;p<=len;p+=lowbit(p)) v+=bit[p]; return v;}

int x[N],y[N],pr[N];
map<pair<int,int>,int>mp;
int main(){
	n=read();
	for(int i=1;i<=n;++i){
		int k=read(); l[i]=r[i-1]+1; r[i]=l[i]+k-1;
		for(int j=1;j<=k;++j) x[j]=read(),y[j]=read(); x[k+1]=x[1]; y[k+1]=y[1];
		for(int j=1;j<=k;++j){
			int &w=mp[make_pair(x[j+1]-x[j],y[j+1]-y[j])];
			if(!w) w=++id;
			v[l[i]+j-1]=w; pre[l[i]+j-1]=pr[w]; pr[w]=l[i]+j-1;
		}
	}
	len=r[n]; Q=read();
	for(int i=1;i<=Q;++i) q[i].id=i,q[i].l=l[read()],q[i].r=r[read()];
	sort(q+1,q+1+Q,jud);
	for(int i=1,j=0;i<=Q;++i){
		int L=q[i].l,R=q[i].r,w=q[i].id;
		while(j<R) ++j,add(j,1),add(pre[j],-1);
		ans[w]=query(L);
	}
	for(int i=1;i<=Q;++i) printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define lowbit(x) (x&-x)
using namespace std;
const int N=3e5+7;
inline int read(){
	int x=0; bool f=0; char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) f=(ch=='-');
	for(;isdigit(ch);ch=getchar()) x=(x<<3)+(x<<1)+(ch^48);
	return f?-x:x;
}
inline int gcd(int a,int b){while(b){int t=a;a=b;b=t%b;}return a;}

int n,Q,id,len;
int l[N],r[N],v[N],pre[N];
struct que{int l,r,id;}q[N];
inline bool jud(que a,que b){return a.r<b.r;}

int bit[N],ans[N];
inline void add(int p,int v){for(;p;p-=lowbit(p)) bit[p]+=v;}
inline int query(int p,int v=0){for(;p<=len;p+=lowbit(p)) v+=bit[p]; return v;}

int x[N],y[N],pr[N];
map<pair<int,int>,int>mp;
int main(){
	n=read();
	for(int i=1;i<=n;++i){
		int k=read(); l[i]=r[i-1]+1; r[i]=l[i]+k-1;
		for(int j=1;j<=k;++j) x[j]=read(),y[j]=read(); x[k+1]=x[1]; y[k+1]=y[1];
		for(int j=1;j<=k;++j){
			int X=x[j+1]-x[j],Y=y[j+1]-y[j],G=gcd(X,Y);
			if(G<0) G=-G;
			int &w=mp[make_pair(X/G,Y/G)];
			if(!w) w=++id;
			v[l[i]+j-1]=w; pre[l[i]+j-1]=pr[w]; pr[w]=l[i]+j-1;
		}
	}
	len=r[n]; Q=read();
	for(int i=1;i<=Q;++i) q[i].id=i,q[i].l=l[read()],q[i].r=r[read()];
	sort(q+1,q+1+Q,jud);
	for(int i=1,j=0;i<=Q;++i){
		int L=q[i].l,R=q[i].r,w=q[i].id;
		while(j<R) ++j,add(j,1),add(pre[j],-1);
		ans[w]=query(L);
	}
	for(int i=1;i<=Q;++i) printf("%d\n",ans[i]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const int MAXN = 100005;
map<P, int> mp;
struct Query { int l, id; };
vector<int> md[MAXN];
vector<Query> qr[MAXN];
int ans[MAXN], bit[MAXN], n, Q;
void add(int x, int w) {
	for (; x <= n; x += x & -x) bit[x] += w;
}
int sum(int x) {
	int res = 0;
	for (; x; x -= x & -x) res += bit[x];
	return res;
}
void extend(int x, int y, int id) {
	int d = abs(__gcd(x, y));
	x /= d, y /= d;
	int &p = mp[P(x, y)];
	md[id].push_back(p);
	p = id;
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		int t, a, b, la, lb;
		scanf("%d%d%d", &t, &a, &b);
		la = a, lb = b;
		for (int j = 1; j < t; j++) {
			int x, y; scanf("%d%d", &x, &y);
			extend(x - la, y - lb, i);
			la = x, lb = y;
		}
		extend(a - la, b - lb, i);
	}
	scanf("%d", &Q);
	for (int i = 1; i <= Q; i++) {
		int l, r; scanf("%d%d", &l, &r);
		qr[r].push_back((Query) { l, i });
	}
	for (auto p : mp) add(p.second, 1);
	for (int i = n; i > 0; i--) {
		for (Query q : qr[i]) ans[q.id] = sum(i) - sum(q.l - 1);
		for (int j : md[i]) if (j) add(j, 1);
	}
	for (int i = 1; i <= Q; i++) printf("%d\n", ans[i]);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> P;

const int MAXN = 100005;
map<P, int> mp;
struct Query { int l, id; };
vector<int> md[MAXN];
vector<Query> qr[MAXN];
int ans[MAXN], bit[MAXN], n, Q;
void add(int x, int w) {
	for (; x <= n; x += x & -x) bit[x] += w;
}
int sum(int x) {
	int res = 0;
	for (; x; x -= x & -x) res += bit[x];
	return res;
}
void extend(int x, int y, int id) {
	int &p = mp[P(x, y)];
	md[id].push_back(p);
	p = id;
}
int main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		int t, a, b, la, lb;
		scanf("%d%d%d", &t, &a, &b);
		la = a, lb = b;
		for (int j = 1; j < t; j++) {
			int x, y; scanf("%d%d", &x, &y);
			extend(x - la, y - lb, i);
			x = la, y = lb;
		}
		extend(a - la, b - lb, i);
	}
	scanf("%d", &Q);
	for (int i = 1; i <= Q; i++) {
		int l, r; scanf("%d%d", &l, &r);
		qr[r].push_back((Query) { l, i });
	}
	for (auto p : mp) add(p.second, 1);
	for (int i = n; i > 0; i--) {
		for (Query q : qr[i]) ans[q.id] = sum(i) - sum(q.l - 1);
		for (int j : md[i]) if (j) add(j, 1);
	}
	for (int i = 1; i <= Q; i++) printf("%d\n", ans[i]);
	return 0;
}


#include<bits/stdc++.h>
#define mk make_pair
using namespace std;
const int N=3e5+5;

int read()
{
	int s=0;
	char c=getchar(),lc='+';
	while (c<'0'||'9'<c) lc=c,c=getchar();
	while ('0'<=c&&c<='9') s=s*10+c-'0',c=getchar();
	return lc=='-'?-s:s;
}
void write(int x)
{
	if (x<0)
	{
		putchar('-');
		x=-x;
	}
	if (x<10) putchar(x+'0');
	else
	{
		write(x/10);
		putchar(x%10+'0');
	}
}
void print(int x,char c='\n')
{
	write(x);
	putchar(c);
}
int t[N],nn;
void add(int x,int y)
{
	for (;x<=nn;x+=x&-x) t[x]+=y;
}
int query(int x)
{
	int ret=0;
	for (;x;x-=x&-x) ret+=t[x];
	return ret;
}
int gcd(int x,int y)
{
	return y==0?x:gcd(y,x%y);
}
struct Query
{
	int l,r,id;
	bool operator <(const Query &a)const
	{
		return r==a.r?l<a.l:r<a.r;
	}
}q[N];
map<pair<int,int>,int>Map;
int x[N],y[N],col[N],pre[N],b[N],ans[N],ed[N];

signed main()
{
	memset(t,0,sizeof(t));
	Map.clear();
	int n=read(),cntcol=0,cnt=0;
	for (int i=1;i<=n;i++)
	{
		int m=read();
		x[1]=read();
		y[1]=read();
		for (int j=2;j<=m;j++)
		{
			x[j]=read();
			y[j]=read();
			int X=x[j]-x[j-1],Y=y[j]-y[j-1];
			int g=gcd(abs(X),abs(Y));
			X/=g;
			Y/=g;
			if (!Map.count(mk(X,Y))) Map[mk(X,Y)]=++cntcol;
			col[++cnt]=Map[mk(X,Y)];
		}
		int X=x[1]-x[m],Y=y[1]-y[m];
		int g=gcd(abs(X),abs(Y));
		X/=g;
		Y/=g;
		if (!Map.count(mk(X,Y))) Map[mk(X,Y)]=++cntcol;
		col[++cnt]=Map[mk(X,Y)];
		ed[i]=cnt;
	}
	nn=cnt;
	int Q=read();
	for (int i=1;i<=Q;i++)
	{
		q[i].id=i;
		q[i].l=read();
		q[i].r=read();
	}
	sort(q+1,q+1+Q);
	memset(b,0,sizeof(b));
//	for (int i=1;i<=cnt;i++) print(col[i],' ');puts("");
	for (int i=1;i<=cnt;i++)
	{
		pre[i]=b[col[i]];
		b[col[i]]=i;
	}
//	for (int i=1;i<=cnt;i++) print(pre[i],' ');puts("");
	int now=1;
	for (int i=1;i<=Q;i++)
	{
		while (now<=ed[q[i].r])
		{
			if (pre[now]) add(pre[now],-1);
			add(now,1);
			now++;
		}
//		print(q[i].id,':');
//		print(q[i].l,' ');
//		print(q[i].r);
		ans[q[i].id]=query(ed[q[i].r])-query(ed[q[i].l-1]);
	}
	for (int i=1;i<=Q;i++) print(ans[i]);

	return 0;
}


#include<bits/stdc++.h>
#define mk make_pair
using namespace std;
const int N=1e5+5;
const int M=3e5+5;

int read()
{
	int s=0;
	char c=getchar(),lc='+';
	while (c<'0'||'9'<c) lc=c,c=getchar();
	while ('0'<=c&&c<='9') s=s*10+c-'0',c=getchar();
	return lc=='-'?-s:s;
}
void write(int x)
{
	if (x<0)
	{
		putchar('-');
		x=-x;
	}
	if (x<10) putchar(x+'0');
	else
	{
		write(x/10);
		putchar(x%10+'0');
	}
}
void print(int x,char c='\n')
{
	write(x);
	putchar(c);
}
int t[M],nn;
void add(int x,int y)
{
	for (;x<=nn;x+=x&-x) t[x]+=y;
}
int query(int x)
{
	int ret=0;
	for (;x;x-=x&-x) ret+=t[x];
	return ret;
}
int gcd(int x,int y)
{
	return y==0?x:gcd(y,x%y);
}
struct Query
{
	int l,r,id;
	bool operator <(const Query &a)const
	{
		return r==a.r?l<a.l:r<a.r;
	}
}q[N];
map<pair<int,int>,int>Map;
int x[M],y[M],col[M],pre[M],b[M],ans[N],ed[M];

signed main()
{
	memset(t,0,sizeof(t));
	Map.clear();
	int n=read(),cntcol=0,cnt=0;
	for (int i=1;i<=n;i++)
	{
		int m=read();
		x[1]=read();
		y[1]=read();
		for (int j=2;j<=m;j++)
		{
			x[j]=read();
			y[j]=read();
			int X=x[j]-x[j-1],Y=y[j]-y[j-1];
			int g=gcd(abs(X),abs(Y));
			X/=g;
			Y/=g;
			if (!Map.count(mk(X,Y))) Map[mk(X,Y)]=++cntcol;
			col[++cnt]=Map[mk(X,Y)];
		}
		int X=x[1]-x[m],Y=y[1]-y[m];
		int g=gcd(abs(X),abs(Y));
		X/=g;
		Y/=g;
		if (!Map.count(mk(X,Y))) Map[mk(X,Y)]=++cntcol;
		col[++cnt]=Map[mk(X,Y)];
		ed[i]=cnt;
	}
	nn=cnt;
	int Q=read();
	for (int i=1;i<=Q;i++)
	{
		q[i].id=i;
		q[i].l=read();
		q[i].r=read();
	}
	sort(q+1,q+1+n);
	memset(b,0,sizeof(b));
//	for (int i=1;i<=cnt;i++) print(col[i],' ');puts("");
	for (int i=1;i<=cnt;i++)
	{
		pre[i]=b[col[i]];
		b[col[i]]=i;
	}
//	for (int i=1;i<=cnt;i++) print(pre[i],' ');puts("");
	int now=1;
	for (int i=1;i<=Q;i++)
	{
		while (now<=ed[q[i].r])
		{
			if (pre[now]) add(pre[now],-1);
			add(now,1);
			now++;
		}
//		print(q[i].id,':');
//		print(q[i].l,' ');
//		print(q[i].r);
		ans[q[i].id]=query(ed[q[i].r])-query(ed[q[i].l-1]);
	}
	for (int i=1;i<=Q;i++) print(ans[i]);

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

const static int maxn = 3e5 + 5;

int bg[maxn], ed[maxn];

pair<int, int> org[maxn], plc[maxn], pos[maxn];
struct Que
{
    int l, r, p;
} que[maxn];
inline bool operator < (Que a, Que b) {return a.r < b.r;}

int id[maxn], la[maxn], ans[maxn];

inline int gcd(int x, int y)
{
    while (y != 0) {
        x %= y;
        swap(x, y);
    }
    return x;
}

int N, tot = 0;

#define lowbit(x) ((x) & (-(x)))
int bit[maxn];
inline void add(int x, int v)
{
    while (x <= tot) {
        bit[x] += v;
        x += lowbit(x);
    }
}
inline int query(int x)
{
    int res = 0;
    while (x) {
        res += bit[x];
        x -= lowbit(x);
    }
    return res;
}

int main()
{
    cin >> N;
    for (int i = 1; i <= N; ++i) {
        int k;
        cin >> k;
        const int bas = tot;
        bg[i] = bas;
        ed[i] = bas + k - 1;
        for (int j = 0; j < k; ++j)
            cin >> pos[tot].first >> pos[tot].second, ++tot;
        for (int j = 0; j < k; ++j) {
            const int p = bas + j, q = bas + (j + 1) % k;
            org[p].second = pos[q].second - pos[p].second;
            org[p].first = pos[q].first - pos[p].first;
            const int g = abs(gcd(org[p].first, org[p].second));
            org[p].first /= g;
            org[p].second /= g;
        }
    }
    copy(org, org + tot, plc);
    sort(plc, plc + tot);
    for (int i = 0; i < tot; ++i)
        id[i] = lower_bound(plc, plc + tot, org[i]) - plc;
    int Q;
    cin >> Q;
    for (int i = 0; i < Q; ++i)
        cin >> que[i].l >> que[i].r, que[i].p = i, que[i].r = ed[que[i].r], que[i].l = bg[que[i].l];
    sort(que, que + Q);
    int q = 0;
    for (int i = 0; i < Q; ++i) {
        while (q <= que[i].r) {
            add(q + 1, 1);
            if (la[id[q]])
                add(la[id[q]], -1);
            la[id[q]] = q + 1;
            ++q;
        }
        ans[que[i].p] = query(que[i].r + 1) - query(que[i].l);
    }
    copy(ans, ans + Q, ostream_iterator<int>(cout, "\n"));
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define lowbit(x) (x&(-x))
using namespace std;
const int N=600010;
struct point{
    int x,y;
    point(){}
    point(int x,int y):
        x(x),y(y){}
    bool operator < (const point &r) const
    {
        if(x^r.x) return x<r.x;
        else return y<r.y;
    }
};
struct ASK{
    int l,r,id;
}q[N];
int n,m,cnt=0;
int sum[N],b[N],ans[N],pre[N],ts[N],t[N];
vector<point> a[N];
map<point,int> ma;
inline int gcd(int x,int y)
{
    if(y==0) return x;
    return gcd(y,x%y);
}
inline void add(int x,int y)
{
    if(x==0) return;
    for(;x<=sum[n];x+=lowbit(x))
        t[x]+=y;
}
inline int find(int x)
{
    int u=0;
    for(;x;x-=lowbit(x))
        u+=t[x];
    return u;
}
inline bool cmp(ASK x,ASK y)
{
    return x.r<y.r;
}
int main()
{
//    freopen("1.in","r",stdin);
    scanf("%d",&n);
    for(int k=1;k<=n;k++)
    {
        int x;
        scanf("%d",&x);
        sum[k]=sum[k-1]+x;
        for(int i=1;i<=x;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            a[k].push_back(point(u,v));
        }
        a[k].push_back(a[k][0]);
        for(int i=0;i<a[k].size();i++)
        {
            point u=point(a[k][i].x-a[k][i+1].x,a[k][i].y-a[k][i+1].y);
            int v=gcd(abs(u.x),abs(u.y));
            if(v) u.x/=v,u.y/=v;
            if(ma.count(u)) b[sum[k-1]+i+1]=ma[u];
            else ma[u]=b[sum[k-1]+i+1]=++cnt;
        }
    }
    // for(int k=1;k<=n;k++)
    //     cout<<sum[k]<<" ";
    // cout<<endl;
    // for(int k=1;k<=sum[n];k++)
    //     cout<<b[k]<<" ";
    // cout<<endl;
    scanf("%d",&m);
    for(int k=1;k<=m;k++)
    {
        scanf("%d%d",&q[k].l,&q[k].r);
        q[k].l=sum[q[k].l-1];
        q[k].r=sum[q[k].r];
        q[k].id=k;
    }
    sort(q+1,q+1+m,cmp);
    for(int k=1;k<=sum[n];k++)
    {
        pre[k]=ts[b[k]];
        ts[b[k]]=k;
    }
    int now=1;
    for(int k=1;k<=sum[n];k++)
    {
        add(k,1),add(pre[k],-1);
        while(q[now].r==k)
        {
            ans[q[now].id]=find(q[now].r)-find(q[now].l);
//            cout<<q[now].r<<" "<<q[now].l<<" "<<find(q[now].r)<<" "<<find(q[now].l)<<endl;
            now++;
        }
    }
    for(int k=1;k<=m;k++)
        printf("%d\n",ans[k]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define lowbit(x) (x&(-x))
using namespace std;
const int N=600010;
struct point{
    int x,y;
    point(){}
    point(int x,int y):
        x(x),y(y){}
    bool operator < (const point &r) const
    {
        if(x^r.x) return x<r.x;
        else return y<r.y;
    }
};
struct ASK{
    int l,r,id;
}q[N];
int n,m,cnt=0;
int sum[N],b[N],ans[N],pre[N],ts[N],t[N];
vector<point> a[N];
map<point,int> ma;
inline int gcd(int x,int y)
{
    if(y==0) return x;
    return gcd(y,x%y);
}
inline void add(int x,int y)
{
    if(x==0) return;
    for(;x<=sum[n];x+=lowbit(x))
        t[x]+=y;
}
inline int find(int x)
{
    int u=0;
    for(;x;x-=lowbit(x))
        u+=t[x];
    return u;
}
inline bool cmp(ASK x,ASK y)
{
    return x.r<y.r;
}
int main()
{
//    freopen("1.in","r",stdin);
    scanf("%d",&n);
    for(int k=1;k<=n;k++)
    {
        int x;
        scanf("%d",&x);
        sum[k]=sum[k-1]+x;
        for(int i=1;i<=x;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            a[k].push_back(point(u,v));
        }
        a[k].push_back(a[k][0]);
        for(int i=0;i<a[k].size();i++)
        {
            point u=point(a[k][i].x-a[k][i+1].x,a[k][i].y-a[k][i+1].y);
            int v=gcd(abs(u.x),abs(u.y));
            u.x/=v,u.y/=v;
            if(ma.count(u)) b[sum[k-1]+i+1]=ma[u];
            else ma[u]=b[sum[k-1]+i+1]=++cnt;
        }
    }
    // for(int k=1;k<=n;k++)
    //     cout<<sum[k]<<" ";
    // cout<<endl;
    // for(int k=1;k<=sum[n];k++)
    //     cout<<b[k]<<" ";
    // cout<<endl;
    scanf("%d",&m);
    for(int k=1;k<=m;k++)
    {
        scanf("%d%d",&q[k].l,&q[k].r);
        q[k].l=sum[q[k].l-1];
        q[k].r=sum[q[k].r];
        q[k].id=k;
    }
    sort(q+1,q+1+m,cmp);
    for(int k=1;k<=sum[n];k++)
    {
        pre[k]=ts[b[k]];
        ts[b[k]]=k;
    }
    int now=1;
    for(int k=1;k<=sum[n];k++)
    {
        add(k,1),add(pre[k],-1);
        while(q[now].r==k)
        {
            ans[q[now].id]=find(q[now].r)-find(q[now].l);
//            cout<<q[now].r<<" "<<q[now].l<<" "<<find(q[now].r)<<" "<<find(q[now].l)<<endl;
            now++;
        }
    }
    for(int k=1;k<=m;k++)
        printf("%d\n",ans[k]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define lowbit(x) (x&(-x))
using namespace std;
const int N=300010;
struct point{
    int x,y;
    point(){}
    point(int x,int y):
        x(x),y(y){}
    bool operator < (const point &r) const
    {
        if(x^r.x) return x<r.x;
        else return y<r.y;
    }
};
struct ASK{
    int l,r,id;
}q[N];
int n,m,cnt=0;
int sum[N],b[N],ans[N],pre[N],ts[N],t[N];
vector<point> a[N];
map<point,int> ma;
inline int gcd(int x,int y)
{
    if(y==0) return x;
    return gcd(y,x%y);
}
inline void add(int x,int y)
{
    if(x==0) return;
    for(;x<=sum[n];x+=lowbit(x))
        t[x]+=y;
}
inline int find(int x)
{
    int u=0;
    for(;x;x-=lowbit(x))
        u+=t[x];
    return u;
}
inline bool cmp(ASK x,ASK y)
{
    return x.r<y.r;
}
int main()
{
//    freopen("1.in","r",stdin);
    scanf("%d",&n);
    for(int k=1;k<=n;k++)
    {
        int x;
        scanf("%d",&x);
        sum[k]=sum[k-1]+x;
        for(int i=1;i<=x;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            a[k].push_back(point(u,v));
        }
        a[k].push_back(a[k][0]);
        for(int i=0;i<a[k].size();i++)
        {
            point u=point(a[k][i].x-a[k][i+1].x,a[k][i].y-a[k][i+1].y);
            int v=gcd(abs(u.x),abs(u.y));
            u.x/=v,u.y/=v;
            if(ma.count(u)) b[sum[k-1]+i+1]=ma[u];
            else ma[u]=b[sum[k-1]+i+1]=++cnt;
        }
    }
    // for(int k=1;k<=n;k++)
    //     cout<<sum[k]<<" ";
    // cout<<endl;
    // for(int k=1;k<=sum[n];k++)
    //     cout<<b[k]<<" ";
    // cout<<endl;
    scanf("%d",&m);
    for(int k=1;k<=m;k++)
    {
        scanf("%d%d",&q[k].l,&q[k].r);
        q[k].l=sum[q[k].l-1];
        q[k].r=sum[q[k].r];
        q[k].id=k;
    }
    sort(q+1,q+1+m,cmp);
    for(int k=1;k<=sum[n];k++)
    {
        pre[k]=ts[b[k]];
        ts[b[k]]=k;
    }
    int now=1;
    for(int k=1;k<=sum[n];k++)
    {
        add(k,1),add(pre[k],-1);
        while(now<=n&&q[now].r==k)
        {
            ans[q[now].id]=find(q[now].r)-find(q[now].l);
//            cout<<q[now].r<<" "<<q[now].l<<" "<<find(q[now].r)<<" "<<find(q[now].l)<<endl;
            now++;
        }
    }
    for(int k=1;k<=m;k++)
        printf("%d\n",ans[k]);
    return 0;
}


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define lowbit(x) (x&(-x))
using namespace std;
const int N=300010;
struct point{
    int x,y;
    point(){}
    point(int x,int y):
        x(x),y(y){}
    bool operator < (const point &r) const
    {
        if(x^r.x) return x<r.x;
        else return y<r.y;
    }
};
struct ASK{
    int l,r,id;
}q[N];
int n,m,cnt=0;
int sum[N],b[N],ans[N],pre[N],ts[N],t[N];
vector<point> a[N];
map<point,int> ma;
inline int gcd(int x,int y)
{
    if(y==0) return x;
    return gcd(y,x%y);
}
inline void add(int x,int y)
{
    if(x==0) return;
    for(;x<=sum[n];x+=lowbit(x))
        t[x]+=y;
}
inline int find(int x)
{
    int u=0;
    for(;x;x-=lowbit(x))
        u+=t[x];
    return u;
}
inline bool cmp(ASK x,ASK y)
{
    return x.r<y.r;
}
int main()
{
//    freopen("1.in","r",stdin);
    scanf("%d",&n);
    for(int k=1;k<=n;k++)
    {
        int x;
        scanf("%d",&x);
        sum[k]=sum[k-1]+x;
        for(int i=1;i<=x;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            a[k].push_back(point(u,v));
        }
        a[k].push_back(a[k][0]);
        for(int i=0;i<a[k].size();i++)
        {
            point u=point(a[k][i].x-a[k][i+1].x,a[k][i].y-a[k][i+1].y);
            int v=gcd(abs(u.x),abs(u.y));
            u.x/=v,u.y/=v;
            if(ma.count(u)) b[sum[k-1]+i+1]=ma[u];
            else ma[u]=b[sum[k-1]+i+1]=++cnt;
        }
    }
    // for(int k=1;k<=n;k++)
    //     cout<<sum[k]<<" ";
    // cout<<endl;
    // for(int k=1;k<=sum[n];k++)
    //     cout<<b[k]<<" ";
    // cout<<endl;
    scanf("%d",&m);
    for(int k=1;k<=m;k++)
    {
        scanf("%d%d",&q[k].l,&q[k].r);
        q[k].l=sum[q[k].l-1];
        q[k].r=sum[q[k].r];
        q[k].id=k;
    }
    sort(q+1,q+1+m,cmp);
    for(int k=1;k<=sum[n];k++)
    {
        pre[k]=ts[b[k]];
        ts[b[k]]=k;
    }
    int now=1;
    for(int k=1;k<=sum[n];k++)
    {
        add(k,1),add(pre[k],-1);
        while(now<=m&&q[now].r==k)
        {
            ans[q[now].id]=find(q[now].r)-find(q[now].l);
//            cout<<q[now].r<<" "<<q[now].l<<" "<<find(q[now].r)<<" "<<find(q[now].l)<<endl;
            now++;
        }
    }
    for(int k=1;k<=m;k++)
        printf("%d\n",ans[k]);
    return 0;
}


#include <algorithm>
#include <map>
#include <stdlib.h>
#include <cstdio>
#include <vector>
using namespace std;
#define N 300005
#define M 100005
#define ll long long int
map<pair<ll,ll>,int>f;
ll x[N],y[N];
int rec[N];
vector<int>a[N];
vector< pair<int,int> >b[N];
int n,m,sz,cnt,l,r;  int ans[N];
int tree[N];
int lowbit(int x){return x&-x;}
void ins(int pos,int val){for(;pos<=n;pos+=lowbit(pos)) tree[pos]+=val;}
int query(int pos){int sum=0;for(;pos;pos-=lowbit(pos)) sum+=tree[pos];return sum;}
int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;++i){
		scanf("%d",&sz);
		for(int j=1;j<=sz;++j)  scanf("%lld %lld",x+j,y+j);
		for(int j=1;j<=sz;++j){
			ll dx=x[j%sz+1]-x[j];  ll dy=y[j%sz+1]-y[j];
			ll tmp=abs(__gcd(dx,dy));  dx/=tmp;  dy/=tmp;
			if(!f[{dx,dy}]) f[{dx,dy}]=++cnt;   //斜率离散化
			a[i].push_back(f[{dx,dy}]);
		}
	}
	scanf("%d",&m);
	for(int i=1;i<=m;++i){
		scanf("%d %d",&l,&r);
		b[r].push_back({i,l});
	}
	for(int i=1;i<=n;++i){
		for(int j=0;j<a[i].size();++j){
			int tmp=a[i][j];
			if(rec[tmp]) ins(rec[tmp],-1);
			ins(i,1);
			rec[tmp]=i;
		}
		for(int j=0;j<b[i].size();++j){
			pair<int,int> tmp=b[i][j];
			ans[tmp.first]=query(i)-query(tmp.second-1);
		}
	}
	for(int i=1;i<=m;++i) printf("%d\n",ans[i]);
	return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>

using namespace std;

const int MN = 1e5 + 100;
const int MV = 3e5 + 100;

int N;

int gcd(int a, int b) {return a?gcd(b,b%a):b;}
struct vec
{
	int x, y;
	vec(int a = 0, int b = 0) : x(a), y(b) {}
	vec simp(void)
	{
		int k = gcd(abs(x), abs(y));
		if(k) x/=k, y/=k;
		return *this;
	}
	bool operator < (const vec& o) const {return x < o.x || (!(o.x < x) && y < o.y);}
	vec operator - (const vec& o) const {return {x-o.x,y-o.y};}
	bool operator == (const vec& o) const {return x==o.x&&y==o.y;}
};
vec nvec(void)
{
	int x, y; scanf("%d%d", &x, &y);
	return {x,y};
}

vec v[MV]; int V;
int k[MN];
vector<vec> n[MN], d[MN];
vector<int> s[MN];

int Q, H;
int q[MN], last[MV];
int h[MN];
int bit[MV];
void upd(int x, int v = 1)
{
	for(++x;x<MV;x+=-x&x)
		bit[x]+=v;
}
int cnt(int x)
{
	int r = 0;
	for(;x;x-=-x&x)//no --x
		r+=bit[x];
	return r;
}
void append(int i, int v)
{
	if(last[v])
		upd(last[v], -1);
	last[v] = i;
	upd(i);
}
int ans[MN];
struct Qry
{
	int l, r;
	int id;
	bool operator < (const Qry& o) const {return l < o.l;}
};
vector<Qry> qry;

int main(void)
{
	scanf("%d", &N);
	for(int i = 0;i < N;i++)
	{
		scanf("%d", k+i);
		for(int j = 0;j < k[i];j++)
			n[i].push_back(nvec());
		for(int j = 0;j < k[i]-1;j++)
			d[i].push_back(n[i][j+1]-n[i][j]);
		d[i].push_back(n[i].front()-n[i].back());
		for(vec& x : d[i])
			v[V++] = x.simp();
	}
	//assert(V < MV);
	sort(v, v+V);
	V = unique(v,v+V)-v;
	for(int i = 0;i < N;d[i++].clear())
		for(vec& x : d[i])
			s[i].push_back(lower_bound(v,v+V,x)-v);

	//for(int i = 0;i < N;i++) for(int j = 0;j < s[i].size();j++) printf("%d%c", s[i][j], "\n "[j+1<s[i].size()]);

	H = 1;
	for(int i = 0;i < N;i++)
	{
		q[i] = H;
		for(int x : s[i])
			h[H++] = x;
	}
	q[N] = H;

	//for(int i = 0;i < N;i++) printf("%d: %d\n", i, q[i]);
	//printf("\n"); for(int i = 1;i < H;i++) printf("%d: %d\n", i, h[i]); printf("\n");

	scanf("%d", &Q);
	for(int i = 0, l, r;i < Q;i++)
		scanf("%d%d", &l, &r), qry.push_back({q[--l], q[r], i});
	sort(qry.begin(), qry.end());
	for(int i = H-1, j = Q-1;i >= 1;i--)
	{
		append(i, h[i]);
		for(;j >= 0 && i == qry[j].l;j--)
			ans[qry[j].id] = cnt(qry[j].r);
	}
	for(int i = 0;i < Q;i++)
		printf("%d\n", ans[i]);
	return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>

using namespace std;

const int MN = 1e5 + 100;
const int MV = 3e5 + 10000;

int N;

int gcd(int a, int b) {return a?gcd(b%a,a):b;}
struct vec
{
	int x, y;
	vec(int a = 0, int b = 0) : x(a), y(b) {}
	vec simp(void)
	{
		int k = gcd(abs(x), abs(y));
		if(k) x/=k, y/=k;
		return *this;
	}
	bool operator < (const vec& o) const {return x < o.x || (!(o.x < x) && y < o.y);}
	vec operator - (const vec& o) const {return {x-o.x,y-o.y};}
	bool operator == (const vec& o) const {return x==o.x&&y==o.y;}
};
vec nvec(void)
{
	int x, y; scanf("%d%d", &x, &y);
	return {x,y};
}

vec v[MV]; int V;
int k[MN];
vector<vec> n[MN], d[MN];
vector<int> s[MN];

int Q, H;
int q[MV], last[MV];
int h[MV];
int bit[MV];
void upd(int x, int v = 1)
{
	for(++x;x<MV;x+=-x&x)
		bit[x]+=v;
}
int cnt(int x)
{
	int r = 0;
	for(;x;x-=-x&x)//no ++x
		r+=bit[x];
	return r;
}
void append(int i, int v)
{
	if(last[v])
		upd(last[v], -1);
	last[v] = i;
	upd(i);
}
int ans[MN];
struct Qry
{
	int l, r;
	int id;
	bool operator < (const Qry& o) const {return l < o.l || (!(o.l < l) && id < o.id);}
};
vector<Qry> qry;

int main(void)
{
	scanf("%d", &N);
	for(int i = 0;i < N;i++)
	{
		scanf("%d", k+i);
		for(int j = 0;j < k[i];j++)
			n[i].push_back(nvec());
		for(int j = 0;j < k[i]-1;j++)
			d[i].push_back(n[i][j+1]-n[i][j]);
		d[i].push_back(n[i].front()-n[i].back());
		for(vec& x : d[i])
			v[V++] = x.simp();
	}
	//assert(V < MV);
	sort(v, v+V);
	V = unique(v,v+V)-v;
	for(int i = 0;i < N;d[i++].clear())
		for(vec& x : d[i])
			s[i].push_back(lower_bound(v,v+V,x)-v);

	//for(int i = 0;i < N;i++) for(int j = 0;j < s[i].size();j++) printf("%d%c", s[i][j], "\n "[j+1<s[i].size()]);

	H = 1;
	for(int i = 0;i < N;i++)
	{
		q[i] = H;
		for(int x : s[i])
			h[H++] = x;
	}
	q[N] = H;

	//for(int i = 0;i < N;i++) printf("%d: %d\n", i, q[i]);
	//printf("\n"); for(int i = 1;i < H;i++) printf("%d: %d\n", i, h[i]); printf("\n");

	scanf("%d", &Q);
	for(int i = 0, l, r;i < Q;i++)
		scanf("%d%d", &l, &r), qry.push_back({q[--l], q[r], i});
	sort(qry.begin(), qry.end());
	for(int i = H-1, j = Q-1;i >= 1;i--)
	{
		append(i, h[i]);
		for(;j >= 0 && i == qry[j].l;j--)
			ans[qry[j].id] = cnt(qry[j].r);
	}
	for(int i = 0;i < Q;i++)
		printf("%d\n", ans[i]);
	return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>

using namespace std;

const int MN = 1e5 + 100;
const int MV = 3e5 + 100;

int N;

int gcd(int a, int b) {return a?gcd(b,b%a):b;}
struct vec
{
	int x, y;
	vec(int a = 0, int b = 0) : x(a), y(b) {}
	vec simp(void)
	{
		int k = gcd(abs(x), abs(y));
		if(k) x/=k, y/=k;
		return *this;
	}
	bool operator < (const vec& o) const {return x < o.x || (!(o.x < x) && y < o.y);}
	vec operator - (const vec& o) const {return {x-o.x,y-o.y};}
	bool operator == (const vec& o) const {return x==o.x&&y==o.y;}
};
vec nvec(void)
{
	int x, y; scanf("%d%d", &x, &y);
	return {x,y};
}

vec v[MV]; int V;
int k[MN];
vector<vec> n[MN], d[MN];
vector<int> s[MN];

int Q, H;
int q[MN], last[MV];
int h[MN];
int bit[MV];
void upd(int x, int v = 1)
{
	for(++x;x<MV;x+=-x&x)
		bit[x]+=v;
}
int cnt(int x)
{
	int r = 0;
	for(;x;x-=-x&x)//no --x
		r+=bit[x];
	return r;
}
void append(int i, int v)
{
	if(last[v])
		upd(last[v], -1);
	last[v] = i;
	upd(i);
}
int ans[MN];
struct Qry
{
	int l, r;
	int id;
	bool operator < (const Qry& o) const {return l < o.l;}
};
vector<Qry> qry;

int main(void)
{
	scanf("%d", &N);
	for(int i = 0;i < N;i++)
	{
		scanf("%d", k+i);
		for(int j = 0;j < k[i];j++)
			n[i].push_back(nvec());
		for(int j = 0;j < k[i]-1;j++)
			d[i].push_back(n[i][j+1]-n[i][j]);
		d[i].push_back(n[i].front()-n[i].back());
		for(vec& x : d[i])
			v[V++] = x.simp();
	}
	assert(V < MV);
	sort(v, v+V);
	V = unique(v,v+V)-v;
	for(int i = 0;i < N;d[i++].clear())
		for(vec& x : d[i])
			s[i].push_back(lower_bound(v,v+V,x)-v);

	//for(int i = 0;i < N;i++) for(int j = 0;j < s[i].size();j++) printf("%d%c", s[i][j], "\n "[j+1<s[i].size()]);

	H = 1;
	for(int i = 0;i < N;i++)
	{
		q[i] = H;
		for(int x : s[i])
			h[H++] = x;
	}
	q[N] = H;

	//for(int i = 0;i < N;i++) printf("%d: %d\n", i, q[i]);
	//printf("\n"); for(int i = 1;i < H;i++) printf("%d: %d\n", i, h[i]); printf("\n");

	scanf("%d", &Q);
	for(int i = 0, l, r;i < Q;i++)
		scanf("%d%d", &l, &r), qry.push_back({q[--l], q[r], i});
	sort(qry.begin(), qry.end());
	for(int i = H-1, j = Q-1;i >= 1;i--)
	{
		append(i, h[i]);
		for(;j >= 0 && i == qry[j].l;j--)
			ans[qry[j].id] = cnt(qry[j].r);
	}
	for(int i = 0;i < Q;i++)
		printf("%d\n", ans[i]);
	return 0;
}


#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>

using namespace std;

const int MN = 1e5 + 100;
const int MV = 3e5 + 100;

int N;

int gcd(int a, int b) {return a?gcd(b%a,a):b;}
struct vec
{
	int x, y;
	vec(int a = 0, int b = 0) : x(a), y(b) {}
	vec simp(void)
	{
		int k = gcd(abs(x), abs(y));
		if(k) x/=k, y/=k;
		return *this;
	}
	bool operator < (const vec& o) const {return x < o.x || (!(o.x < x) && y < o.y);}
	vec operator - (const vec& o) const {return {x-o.x,y-o.y};}
	bool operator == (const vec& o) const {return x==o.x&&y==o.y;}
};
vec nvec(void)
{
	int x, y; scanf("%d%d", &x, &y);
	return {x,y};
}

vec v[MV]; int V;
int k[MN];
vector<vec> n[MN], d[MN];
vector<int> s[MN];

int Q, H;
int q[MN], last[MV];
int h[MN];
int bit[MV];
void upd(int x, int v = 1)
{
	for(++x;x<MV;x+=-x&x)
		bit[x]+=v;
}
int cnt(int x)
{
	int r = 0;
	for(;x;x-=-x&x)//no ++x
		r+=bit[x];
	return r;
}
void append(int i, int v)
{
	if(last[v])
		upd(last[v], -1);
	last[v] = i;
	upd(i);
}
int ans[MN];
struct Qry
{
	int l, r;
	int id;
	bool operator < (const Qry& o) const {return l < o.l;}
};
vector<Qry> qry;

int main(void)
{
	scanf("%d", &N);
	for(int i = 0;i < N;i++)
	{
		scanf("%d", k+i);
		for(int j = 0;j < k[i];j++)
			n[i].push_back(nvec());
		for(int j = 0;j < k[i]-1;j++)
			d[i].push_back(n[i][j+1]-n[i][j]);
		d[i].push_back(n[i].front()-n[i].back());
		for(vec& x : d[i])
			v[V++] = x.simp();
	}
	//assert(V < MV);
	sort(v, v+V);
	V = unique(v,v+V)-v;
	for(int i = 0;i < N;d[i++].clear())
		for(vec& x : d[i])
			s[i].push_back(lower_bound(v,v+V,x)-v);

	//for(int i = 0;i < N;i++) for(int j = 0;j < s[i].size();j++) printf("%d%c", s[i][j], "\n "[j+1<s[i].size()]);

	H = 1;
	for(int i = 0;i < N;i++)
	{
		q[i] = H;
		for(int x : s[i])
			h[H++] = x;
	}
	q[N] = H;

	//for(int i = 0;i < N;i++) printf("%d: %d\n", i, q[i]);
	//printf("\n"); for(int i = 1;i < H;i++) printf("%d: %d\n", i, h[i]); printf("\n");

	scanf("%d", &Q);
	for(int i = 0, l, r;i < Q;i++)
		scanf("%d%d", &l, &r), qry.push_back({q[--l], q[r], i});
	sort(qry.begin(), qry.end());
	for(int i = H-1, j = Q-1;i >= 1;i--)
	{
		append(i, h[i]);
		for(;j >= 0 && i == qry[j].l;j--)
			ans[qry[j].id] = cnt(qry[j].r);
	}
	for(int i = 0;i < Q;i++)
		printf("%d\n", ans[i]);
	return 0;
}


#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx2")

#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <bitset>
#include <sstream>
#include <deque>
#include <queue>
#include <random>
#include <cassert>

using namespace std;

#define FAST ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FIXED cout << fixed << setprecision(12)
#define RANDOM srand(94385)
#define ll long long
#define ld long double
#define pii pair<int, int>
#define pll pair<ll, ll>
#define graph vector<vector<int>>
#define pb push_back
#define pf push_front
#define popb pop_back
#define popf pop_front
#define f first
#define s second
#define hashmap unordered_map
#define hashset unordered_set
#define eps 1e-9
#define mod 1000000007
#define inf 3000000000000000007ll
#define sz(a) signed(a.size())
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define shuffle(a) \
    for (int i = 0; i < sz(a); ++i) \
        swap(a[i], a[rand() % sz(a)]);

template<class T, class U> inline void checkmin(T &x, U y) { if (y < x) x = y; }
template<class T, class U> inline void checkmax(T &x, U y) { if (y > x) x = y; }
template<class T, class U> inline bool ifmax(T &x, U y) { if (y > x) return x = y, true; return false; }
template<class T, class U> inline bool ifmin(T &x, U y) { if (y < x) return x = y, true; return false; }
template<class T> inline void sort(T &a) { sort(all(a)); }
template<class T> inline void rsort(T &a) { sort(rall(a)); }
template<class T> inline void reverse(T &a) { reverse(all(a)); }
template<class T, class U> inline istream& operator>>(istream& str, pair<T, U> &p) { return str >> p.f >> p.s; }
template<class T> inline istream& operator>>(istream& str, vector<T> &a) { for (auto &i : a) str >> i; return str; }

struct Fenv {
    static const int n = 3e5 + 10;
    int fenv[n];
    void add(int r, int x) {
        for (; r < n; r |= r + 1)
            fenv[r] += x;
    }
    int get(int r) {
        int ans = 0;
        for (; r >= 0; r = (r & r + 1) - 1)
            ans += fenv[r];
        return ans;
    }
    int get(int l, int r) {
        return get(r) - get(l - 1);
    }
} fenv;

pii shrink(pii a) {
    int g = __gcd(abs(a.f), abs(a.s));
    a.f /= g;
    a.s /= g;
    return a;
}

signed main() {
    FAST; FIXED; RANDOM;
    int n;
    cin >> n;
    vector<vector<pii>> a(n);
    vector<pii> occ;
    for (int i = 0; i < n; ++i) {
        int s;
        cin >> s;
        a[i] = vector<pii>(s);
        cin >> a[i];
        vector<pii> b(s);
        for (int j = 0; j < s; ++j) {
            pii from = a[i][j], to = a[i][(j + 1) % s];
            b[j] = shrink({to.f - from.f, to.s - from.s});
        }
        for (auto i : b) occ.pb(i);
        a[i] = b;
    }
    sort(occ);
    occ.resize(unique(all(occ)) - occ.begin());
    vector<int> b;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < sz(a[i]); ++j)
            b.pb(lower_bound(all(occ), a[i][j]) - occ.begin());
    }
    vector<int> pref(n);
    for (int i = 0; i < n; ++i) pref[i] = sz(a[i]);
    for (int i = 1; i < n; ++i) pref[i] += pref[i - 1];
    int q;
    cin >> q;
    vector<pair<pii, int>> query(q);
    int cnt = 0;
    for (auto &i : query) {
        cin >> i.f;
        --i.f.f, --i.f.s;
        int left = i.f.f > 0 ? pref[i.f.f - 1] : 0;
        int right = pref[i.f.s] - 1;
        i.f = {left, right};
        i.s = cnt++;
    }
    sort(query);
    vector<vector<int>> pos(sz(occ));
    for (int i = 0; i < sz(b); ++i) pos[b[i]].pb(i);
    for (int i = 0; i < sz(pos); ++i) fenv.add(pos[i][0], 1);
    vector<int> ptr(sz(occ));
    vector<int> ans(q);
    int l = 0;
    for (auto i : query) {
        while (l < i.f.f) {
            if (++ptr[b[l]] < sz(pos[b[l]])) fenv.add(pos[b[l]][ptr[b[l]]], 1);
            ++l;
        }
        ans[i.s] = fenv.get(i.f.f, i.f.s);
    }
    for (auto i : ans) cout << i << '\n';
    return 0;
}


#include<cstdio>
#include<cstring>
#define retrun return
#define cpnst const
int gcd(int x,int y)
{
	if(x<0)x=-x;if(y<0)y=-y;
	int r=y;for(;r;r=x%y,x=y,y=r);
	return x;
}
struct pii
{int x,y;}P[333333];
bool operator<(cpnst pii x,cpnst pii y)
{return(x.y^y.y)?x.y<y.y:x.x<y.x;}
int Rl[1111111],Rr[1111111],col[1111111];
int tt=0;
int ex[1111111],ey[1111111];
int stk[1111111],top,cn;
#include<map>
std::map<pii,int>Mp;
int kth(int dx,int dy)
{
	int g=gcd(dx,dy),t;
	dx/=g,dy/=g;
	pii p=pii{dx,dy};
	if((t=Mp[p]))return t;
	return Mp[p]=++cn;
}
void readp()
{
	scanf("%d",&top);
	register int i;
	for(i=1;i<=top;i++)scanf("%d%d",ex+i,ey+i);
	for(i=1;i<top;i++)stk[i]=kth(ex[i+1]-ex[i],ey[i+1]-ey[i]);
	stk[top]=kth(ex[1]-ex[top],ey[1]-ey[top]);
}
struct query
{int l,r,k;}q[1111111];
bool operator<(cpnst query x,cpnst query y){return x.r<y.r;}
#define lowbit(x) (x&-x)
int t[1111111];
int ask(int x){int r=0;for(;x;x-=lowbit(x))r+=t[x];return r;}
void ins(int x,int d){for(;x<3e5;x+=lowbit(x))t[x]+=d;}
#include<algorithm>
int ans[1111111],las[1111111];
void insert(int x,int tp)
{
	if(las[x])ins(las[x],-1);
	ins(tp,1),las[x]=tp;
}
int main()
{
	int n;
	scanf("%d",&n);
	register int i,ii;
	for(i=1,ii=0;i<=n;Rr[i]=ii,i++)
		for(readp(),Rl[i]=ii+1;top;)col[++ii]=stk[top--];
	int m;
	for(scanf("%d",&m),i=1;i<=m;i++)
		scanf("%d%d",&q[i].l,&q[i].r),
		q[i].k=i,q[i].l=Rl[q[i].l],q[i].r=Rr[q[i].r];
	std::sort(q+1,q+m+1);
	for(i=ii=1;i<=m;i++)
	{
		for(;ii<=q[i].r;ii++)insert(col[ii],ii);
		ans[q[i].k]=ask(ii)-ask(q[i].l-1);
	}for(i=1;i<=m;i++)printf("%d\n",ans[i]);
}
/*
Just go for it.
*/


#include<cstdio>
#include<cstring>
#define retrun return
#define cpnst const
int gcd(int x,int y)
{
	if(x<0)x=-x;if(y<0)y=-y;
	int r=y;for(;r;r=x%y,x=y,y=r);
	return x;
}
struct pii
{int x,y;}P[333333];
bool operator<(cpnst pii x,cpnst pii y)
{return(x.y^y.y)?x.y<y.y:x.x<y.x;}
int Rl[1111111],Rr[1111111],col[1111111];
int tt=0;
int ex[1111111],ey[1111111];
int stk[1111111],top,cn;
#include<map>
std::map<pii,int>Mp;
int kth(int dx,int dy)
{
	int g=gcd(dx,dy),t;
	dx/=g,dy/=g;
	pii p=pii{dx,dy};
	if((t=Mp[p]))return t;
	return Mp[p]=++cn;
}
void readp()
{
	scanf("%d",&top);
	register int i;
	for(i=1;i<=top;i++)scanf("%d%d",ex+i,ey+i);
	for(i=1;i<top;i++)stk[i]=kth(ex[i+1]-ex[i],ey[i+1]-ey[i]);
	stk[top]=kth(ex[1]-ex[top],ey[1]-ey[top]);
}
struct query
{int l,r,k;}q[1111111];
bool operator<(cpnst query x,cpnst query y){return x.r<y.r;}
#define lowbit(x) (x&-x)
int t[1111111];
int ask(int x){int r=0;for(;x;x-=lowbit(x))r+=t[x];return r;}
void ins(int x,int d){for(;x<=4e5;x+=lowbit(x))t[x]+=d;}
#include<algorithm>
int ans[1111111],las[1111111];
void insert(int x,int tp)
{
	if(las[x])ins(las[x],-1);
	ins(tp,1),las[x]=tp;
}
int main()
{
	int n;
	scanf("%d",&n);
	register int i,ii;
	for(i=1,ii=0;i<=n;Rr[i]=ii,i++)
		for(readp(),Rl[i]=ii+1;top;)col[++ii]=stk[top--];
	int m;
	for(scanf("%d",&m),i=1;i<=m;i++)
		scanf("%d%d",&q[i].l,&q[i].r),
		q[i].k=i,q[i].l=Rl[q[i].l],q[i].r=Rr[q[i].r];
	std::sort(q+1,q+m+1);
	for(i=ii=1;i<=m;i++)
	{
		for(;ii<=q[i].r;ii++)insert(col[ii],ii);
		ans[q[i].k]=ask(ii)-ask(q[i].l-1);
	}for(i=1;i<=m;i++)printf("%d\n",ans[i]);
}
/*
Just go for it.
*/


#include<bits/stdc++.h>
#define ll long long
using namespace std;
#ifdef Fading
#define gc getchar
#endif
#ifndef Fading
inline char gc(){
	static char now[1<<16],*S,*T;
	if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
	return *S++;
}
#endif
inline ll read(){
    register ll x=0,f=1;char ch=gc();
    while (!isdigit(ch)){if(ch=='-')f=-1;ch=gc();}
    while (isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=gc();}
    return (f==1)?x:-x;
}
map<pair<int,int>,int> has;
int n,m,col[620001],id,cnt,K[620001][2],tr[620001],L[620001],R[620001];
int las[620001],pre[620001];
inline int query(int x){
	int ans=0;
	for (;x;x-=x&-x) ans+=tr[x];
	return ans;
}
inline void add(int x,int y){
	if (!x) return;
	for (;x<=cnt;x+=x&-x) tr[x]+=y;
}
int ans[1000001];
struct QUE{
	int l,r,id;
}q[1000001];
inline bool cmp(QUE a,QUE b){
	return (a.r==b.r?a.l<b.l:a.r<b.r);
}
signed main(){
	n=read();
	for (int i=1;i<=n;i++){
		L[i]=cnt+1;R[i]=L[i]+read()-1;
		for (int j=1;j<=R[i]-L[i]+1;j++){
			K[j][0]=read();K[j][1]=read();
		}
		for (int j=2;j<=R[i]-L[i]+1;j++){
			pair<int,int> P=make_pair(K[j][1]-K[j-1][1],K[j][0]-K[j-1][0]);
			int G=__gcd(abs(P.first),abs(P.second));
			P.first/=G;P.second/=G;
			if (!has.count(P)) has[P]=++id;
			col[++cnt]=has[P];
		}
		pair<int,int> P=make_pair(K[1][1]-K[R[i]-L[i]+1][1],K[1][0]-K[R[i]-L[i]+1][0]);
		int G=__gcd(abs(P.first),abs(P.second));
		P.first/=G;P.second/=G;
		if (!has.count(P)) has[P]=++id;
		col[++cnt]=has[P];
	}
	m=read();
	for (int i=1;i<=m;i++){
		q[i].id=i;q[i].l=L[read()];q[i].r=R[read()];
	}
	for (int i=1;i<=cnt;i++){
		pre[i]=las[col[i]];las[col[i]]=i;
	}
	sort(q+1,q+1+m,cmp);
	for (int tmp=1,i=1;i<=m;i++){
		for (;tmp<=q[i].r;tmp++) add(tmp,1),add(pre[tmp],-1);
		ans[q[i].id]=query(q[i].r)-query(q[i].l-1);
	}
	for (int i=1;i<=m;i++){
		printf("%d\n",ans[i]);
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=500010;//

int n,k,q2;
struct Point{
	int x,y;
	Point(){}
	Point(int _x,int _y):x(_x),y(_y){}
	Point operator - (const Point &b)const{
        return Point(x-b.x,y-b.y);
    }
    bool operator <(const Point &b)const{
    	return x==b.x?y<b.y:x<b.x;
	}
}p1,p2;
//struct Point
//{
//    int x,y;
//    Point(int _x = 0,int _y = 0)
//    {
//        x = _x,y = _y;
//    }
//    Point operator - (const Point &b)const
//    {
//        return Point(x-b.x,y-b.y);
//    }
//    int operator ^(const Point &b)const
//    {
//        return x*b.y - y*b.x;
//    }
//    void input()
//    {
//        scanf("%d%d",&x,&y);
//    }
//};

typedef Point Vector;
typedef Point Query;
vector<Vector> ve,tmp;
vector<Query> query;
map<Vector,int> mps;
int l[maxn],r[maxn];
int ans[maxn];
vector<int> q[maxn];
int sum[maxn];
int gcd(int x,int y)
{
	return x?gcd(y%x,x):y;
}
int lowbit(int k)
{
	return k&(-k);
}
void Add(int pos, int va) {
    while(pos < maxn) {
        sum[pos] += va;
        pos += lowbit(pos);
    }
}

int Sum(int pos) {
    if(pos <= 0) return 0;
    int Sum = 0;
    while(pos > 0) {
        Sum += sum[pos];
        pos -= lowbit(pos);
    }
    return Sum;
}

//void Add(int pos,int val)
//{
//	while(pos<maxn){
//		sum[pos]+=val;
//		pos+=lowbit(pos);
//	}
//}
//int Sum(int pos)
//{
//	int res=0;
//	while(pos){
//		res+=sum[pos];pos-=lowbit(pos);
//	}
//	return res;
// }
int main()
{
	while(~scanf("%d",&n)){
		mps.clear();
		ve.clear();
		memset(sum,0,sizeof(sum));
		ve.push_back(Vector(-1,-1));
		int a,b,len;
		for(int i=1;i<=n;i++){
			scanf("%d",&k);
			tmp.clear();
			for(int j=0;j<k;j++){
				scanf("%d%d",&a,&b);
				tmp.push_back(Point(a,b));
			}
			len=tmp.size();
			l[i]=ve.size();
			for(int i=0;i<len;i++){
				p1=tmp[i];p2=tmp[(i+1)%len];
				p2=p2-p1;
				a=gcd(abs(p2.x),abs(p2.y));
//				a=__gcd(abs(p2.x),abs(p2.y));
				p2.x/=a;p2.y/=a;
				ve.push_back(p2);
			}
			r[i]=ve.size()-1;
		}
//		for(int i=1;i<=n;i++) printf("id:%d l:%d r:%d\n",i,l[i],r[i]);
		scanf("%d",&q2);
		for(int i=0;i<q2;i++){
			scanf("%d%d",&a,&b);
			Query tmp=Query(l[a],r[b]);
//			printf("")
			query.push_back(tmp);
			q[tmp.y].push_back(i);
		}
//		for(int i=1;i<=n;i++)
//			printf("Q[%d].siz:%d \n",i,q[i].size());//
		for(int i=1;i<ve.size();i++){
			if(mps.count(ve[i])){
			//if(mps.find(ve[i])!=mps.end()){
				Add(mps[ve[i]],-1);
			}
			Add(i,1);
			mps[ve[i]]=i;
			for(int j=0;j<q[i].size();j++)
//				printf("r_sum:%d l_sum:%d\n",Sum(query[q[i][j]].y),Sum(query[q[i][j]].x)),
				ans[q[i][j]]=Sum(query[q[i][j]].y)-Sum(query[q[i][j]].x-1);
		}
		for(int i=0;i<q2;i++)
			printf("%d\n",ans[i]);
	}
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=500010;//

int n,k,q2;
struct Point{
	int x,y;
	Point(){}
	Point(int _x,int _y):x(_x),y(_y){}
	Point operator - (const Point &b)const{
        return Point(x-b.x,y-b.y);
    }
    bool operator <(const Point &b)const{
    	return x==b.x?y<b.y:x<b.x;
	}
}p1,p2;

typedef Point Vector;
typedef Point Query;
vector<Vector> ve,tmp;
vector<Query> query;
map<Vector,int> mps;
int l[maxn],r[maxn];
int ans[maxn];
vector<int> q[maxn];
int sum[maxn];
int gcd(int x,int y)
{
	return x?gcd(y%x,x):y;
}
int lowbit(int k)
{
	return k&(-k);
}
//void Add(int pos, int va) {
//    while(pos < maxn) {
//        sum[pos] += va;
//        pos += lowbit(pos);
//    }
//}
//
//int Sum(int pos) {
//    if(pos <= 0) return 0;
//    int Sum = 0;
//    while(pos > 0) {
//        Sum += sum[pos];
//        pos -= lowbit(pos);
//    }
//    return Sum;
//}

void Add(int pos,int val)
{
	while(pos<maxn){
		sum[pos]+=val;
		pos+=lowbit(pos);
	}
}
int Sum(int pos)
{
	int res=0;
	while(pos){
		res+=sum[pos];pos-=lowbit(pos);
	}
	return res;
 }
int main()
{
	while(~scanf("%d",&n)){
		mps.clear();
		ve.clear();
		memset(sum,0,sizeof(sum));
		ve.push_back(Vector(-1,-1));
		int a,b,len;
		for(int i=1;i<=n;i++){
			scanf("%d",&k);
			tmp.clear();
			for(int j=0;j<k;j++){
				scanf("%d%d",&a,&b);
				tmp.push_back(Point(a,b));
			}
			len=tmp.size();
			l[i]=ve.size();
			for(int i=0;i<len;i++){
				p1=tmp[i];p2=tmp[(i+1)%len];
				p2=p2-p1;
				a=gcd(abs(p2.x),abs(p2.y));
				p2.x/=a;p2.y/=a;
				ve.push_back(p2);
			}
			r[i]=ve.size()-1;
		}
		scanf("%d",&q2);
		for(int i=0;i<q2;i++){
			scanf("%d%d",&a,&b);
			Query tmp=Query(l[a],r[b]);
			query.push_back(tmp);
			q[tmp.y].push_back(i);
		}
//		for(int i=1;i<=n;i++)
//			printf("Q[%d].siz:%d \n",i,q[i].size());//
		for(int i=1;i<ve.size();i++){
			if(mps.find(ve[i])!=mps.end()){
				Add(mps[ve[i]],-1);
			}
			Add(i,1);
			mps[ve[i]]=i;
			for(int j=0;j<q[i].size();j++)
//				printf("r_sum:%d l_sum:%d\n",Sum(query[q[i][j]].y),Sum(query[q[i][j]].x)),
				ans[q[i][j]]=Sum(query[q[i][j]].y)-Sum(query[q[i][j]].x-1);
		}
		for(int i=0;i<q2;i++)
			printf("%d\n",ans[i]);
	}
}