#include <stdio.h>
#define TRUE 1
#define FALSE 0
typedef struct{
int x;
int y;
} PT;
// 左に90度回転させる
void rot(int m, PT z[10])
{
int i;
int xx,yy;
for(i=0; i<m; i++){
xx=z[i].x;
yy=z[i].y;
z[i].x = -yy;
z[i].y = xx;
}
}
// 最初の点を原点にする
void jushin1(int m, PT z[10])
{
int i;
PT zz;
zz.x=z[0].x;
zz.y=z[0].y;
for(i=0; i<m; i++){
z[i].x-=zz.x;
z[i].y-=zz.y;
}
}
// 最後の点を原点にする
void jushin2(int m, PT z[10])
{
int i;
PT zz;
zz.x=z[m-1].x;
zz.y=z[m-1].y;
for(i=0; i<m; i++){
z[i].x-=zz.x;
z[i].y-=zz.y;
}
}
// 同じ折れ線か確認する i番目が同じだったらf[i]にTRUEが入る
void kakunin(int n, int f[50], int m0, PT z0[10], int m[50], PT z[50][10])
{
int i,j,flag;
for(i=0; i<n; i++){
// 順方向
flag=TRUE;
if(m0!=m[i]){
continue;
}
for(j=0; j<m0; j++){
if(z0[j].x!=z[i][j].x || z0[j].y!=z[i][j].y){
flag=FALSE;
break;
}
}if(flag){
f[i]=TRUE;
}else{ // 逆方向
flag=TRUE;
if(m0!=m[i]){
continue;
}
for(j=0; j<m0; j++){
if(z0[j].x!=z[i][m0-1-j].x || z0[j].y!=z[i][m0-1-j].y){
flag=FALSE;
break;
}
}if(flag){
f[i]=TRUE;
}
}
}
}
int main(void)
{
int i,j,k,m0,m[50],n;
PT z0[10], z[50][10];
int flag,f[50];
while(1){
scanf("%d", &n);;
if(n==0) break;
for(i=0; i<n; i++){
f[i]=FALSE;
}
// お手本データ読み込み
scanf("%d", &m0);
for(j=0; j<m0; j++){
scanf("%d %d", &z0[j].x, &z0[j].y);
}
// 見本データの重心を取る
jushin1(m0, z0);
// 探索データ読み込み
for(i=0; i<n; i++){
scanf("%d", &m[i]);
for(j=0; j<m[i]; j++){
scanf("%d %d", &z[i][j].x, &z[i][j].y);
}
}
// 探索データの重心をとる(1個目を(0,0)にする)
for(i=0; i<n; i++){
jushin1(m[i], z[i]);
}
// 同じかどうか確認する
kakunin(n,f,m0,z0,m,z);
// 探索データの重心をとる(最後をを(0,0)にする)
for(i=0; i<n; i++){
jushin2(m[i], z[i]);
}
// 同じかどうか確認する
kakunin(n,f,m0,z0,m,z);
// あとは3回90度回転して確認する
for(k=0; k<3; k++){
for(i=0; i<n; i++){
rot(m[i], z[i]);
}
for(i=0; i<n; i++){
jushin1(m[i], z[i]);
}
kakunin(n,f,m0,z0,m,z);
for(i=0; i<n; i++){
jushin2(m[i], z[i]);
}
kakunin(n,f,m0,z0,m,z);
}
//最終結果
for(i=0; i<n; i++){
if(f[i]){
printf("%d\n", i+1);
}
}
puts("+++++");
}
return(0);
}