#include <bits/stdc++.h>
 
using namespace std;
 
#define EPS 1e-8
#define equal(a,b) (fabs(a-b) < EPS)
#define lt(a,b) (a-b < -EPS)
#define MAX_N 100
#define MAX_P 500
#define INF 1e9
 
struct Point{
    double x,y;
 
    Point(){}
    Point(double x,double y) : x(x),y(y) {}
 
    Point operator + (const Point &p)const{ return Point(x+p.x,y+p.y); }
    Point operator - (const Point &p)const{ return Point(x-p.x,y-p.y); }
    Point operator * (const double &k)const{ return Point(x*k,y*k); }
    Point operator / (const double &k)const{ return Point(x/k,y/k); }
    bool operator < (const Point &p)const{
	if(!equal(x,p.x)){
	    return lt(x,p.x);
	}else{
	    return lt(y,p.y);
	}
    }
    bool operator == (Point &p)const{
	if(equal(x,p.x) && equal(y,p.y)){
	    return true;
	}
	return false;
    }
};
 
double dot(const Point &a,const Point &b){ return a.x*b.x+a.y*b.y; }
double cross(const Point &a,const Point &b){ return a.x*b.y - b.x*a.y; }
double norm(const Point &p){ return dot(p,p); }
double abs(const Point &p){ return sqrt(norm(p)); }
double dist(const Point &a,const Point &b){
    return sqrt(pow(a.x-b.x,2) + pow(a.y-b.y,2));
}
 
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
typedef Point Vector;
 
int ccw(const Point &p0,const Point &p1,const Point &p2){
    Vector a = p1 - p0;
    Vector b = p2 - p0;
    if(cross(a,b) > EPS) return COUNTER_CLOCKWISE;
    if(cross(a,b) < -EPS) return CLOCKWISE;
    if(dot(a,b) < -EPS) return ONLINE_BACK;
    if(norm(a) < norm(b)) return ONLINE_FRONT;
    return ON_SEGMENT;
}
 
typedef Point Vector;
 
struct Segment{
    Point s,t;
    Segment(){}
    Segment(Point s,Point t) : s(s),t(t) {}
    bool operator == (Segment &seg)const{
	if(s == seg.s && t == seg.t){
	    return true;
	}
	if(t == seg.s && s == seg.t){
	    return true;
	}
	return false;
    }
};
 
bool isIntersectSS(const Segment &a,const Segment &b){
    Point s[2] = {a.s,a.t}, t[2] = {b.s,b.t};
    return (ccw(s[0],s[1],t[0])*ccw(s[0],s[1],t[1]) <= 0
	    && ccw(t[0],t[1],s[0])*ccw(t[0],t[1],s[1]) <= 0);
}
 
Point crosspointSS(const Segment &a,const Segment &b){
    Vector va = a.t-a.s, vb = b.t-b.s;
    double d = cross(vb,va);
    return a.s+va*cross(vb,b.t-a.s)*(1.0/d);
}
 
struct Line{
    Point s,t;
    Line(){}
    Line(Point s,Point t) : s(s),t(t) {}
};
 
Point projection(const Line &l,const Point &p){
    Vector b = l.t-l.s;
    double t = dot(p-l.s,b)/norm(b);
    return l.s+b*t;
}
 
Point reflection(const Line &l,const Point &p){
    return p+(projection(l,p)-p)*2.0;
}
 
#define curr(G,i) (G[i%G.size()])
#define next(G,i) (G[(i+1)%G.size()])
typedef vector<Point> Polygon;
 
int containPP(const Polygon &pg,const Point &p){
    int N = pg.size();
    bool in = false;
    for(int i = 0 ; i < N ; i++){
	Point a = curr(pg,i)-p, b = next(pg,i)-p;
	if(a.y > b.y){ swap(a,b); }
	if(a.y <= 0 && 0 < b.y && cross(a,b) < 0){ in = !in; }
	if(cross(a,b) == 0 && dot(a,b) <= 0){ return 1; }
    }
    return (in ? 2 : 0);
}
 
struct Data{
    Point p;
    double d;
    Data(Point p,double d) : p(p),d(d) {}
    bool operator < (const Data &data)const{
	if(!equal(d,data.d)){
	    return lt(d,data.d);
	}else{
	    return p < data.p;
	}
    }
};
 
bool containPS(const Polygon &pg,Segment &s){
    vector<Data> v;
    v.push_back(Data(s.s,0));
    v.push_back(Data(s.t,dist(s.s,s.t)));
    set<Point> st;
    for(int i = 0 ; i < (int)pg.size() ; i++){
	Segment seg(curr(pg,i),next(pg,i));
	if(seg == s) return true;
	if(ccw(seg.s,seg.t,s.s) == 0 && ccw(seg.s,seg.t,s.t) == 0){
	    return true;
	}
 
	if(isIntersectSS(s,seg)){
	    Point cp = crosspointSS(s,seg);
	    double d = dist(cp,s.s);
	    if(st.find(cp) != st.end()){
		continue;
	    }
	    st.insert(cp);
	    v.push_back(Data(cp,d));
	}
    }
    sort(v.begin(),v.end());
    for(int i = 0 ; i < (int)v.size()-1 ; i++){
	Point cp = (v[i].p + v[i+1].p) / 2.0;
	if(containPP(pg,cp) == 0){
	    return false;
	}
    }
    return true;
}
 
struct Edge{
    int to;
    double cost;
    Edge(int to,double cost) : to(to),cost(cost) {}
};
 
struct State{
    int v;
    double d;
    State(int v,double d) : v(v),d(d) {}
    bool operator < (const State &s)const{
	return d > s.d;
    }
};
 
Polygon L,R;
vector<Edge> G[MAX_P];
 
double dijkstra(int s,int t){
    double dist[MAX_P];
    fill(dist,dist+MAX_P,INF);
    dist[s] = 0;
    priority_queue<State> Q;
    Q.push(State(s,0));
    while(!Q.empty()){
	State st = Q.top(); Q.pop();
	int v = st.v;
	if(lt(dist[v],st.d)){
	    continue;
	}
	if(v == t) return dist[t];
	for(int i = 0 ; i < (int)G[v].size() ; i++){
	    Edge e = G[v][i];
	    if(lt(dist[v]+e.cost,dist[e.to])){
		dist[e.to] = dist[v] + e.cost;
		Q.push(State(e.to,dist[e.to]));
	    }
	}
    }
    return INF;
}
 
void init(){
    for(int i = 0 ; i < MAX_P ; i++){
	G[i].clear();
    }
}
 
int main(){
    int N;
    while(cin >> N, N){
	init();
	Polygon b[MAX_N];
	for(int i = 0 ; i < N ; i++){
	    int M;
	    cin >> M; b[i].resize(M);
	    for(int j = 0 ; j < M ; j++){
		cin >> b[i][j].x >> b[i][j].y;
	    }
	}
	Point s,t;
	Line l;
	cin >> s.x >> s.y >> t.x >> t.y;
	cin >> l.s.x >> l.s.y >> l.t.x >> l.t.y;
	int n = -1;
	for(int i = 0 ; i < N ; i++){
	    if(containPP(b[i],s) != 0){
		n = i;
		L = b[n];
		break;
	    }
	}
	int rn = -1;
	Point rs = reflection(l,s);
	for(int i = 0 ; i < N ; i++){
	    if(containPP(b[i],rs) != 0){
		rn = i;
		R = b[rn];
		break;
	    }
	}
	Point rt = reflection(l,t);
	if(n == -1 || rn == -1 ||
	   containPP(R,rt) == 0){
	    cout << "impossible" << endl;
	    continue;
	}
 
	int size = L.size();
	int rsize = R.size();
	int src,dst;
	for(int i = 0 ; i < size ; i++){
	    L[i] = reflection(l,L[i]);
	}
	set<Point> st;
	for(int i = 0 ; i < size ; i++){
	    if(st.find(L[i]) == st.end()){
		st.insert(L[i]);
	    }
	}
 
	for(int i = 0 ; i < rsize ; i++){
	    if(st.find(R[i]) == st.end()){
		st.insert(R[i]);
	    }
	}
	s = reflection(l,s);
	t = reflection(l,t);
	if(st.find(s) == st.end()) st.insert(s);
	if(st.find(t) == st.end()) st.insert(t);
	vector<Point> vec;
	for(auto it = st.begin() ; it != st.end() ; ++it){
	    vec.push_back(*it);
	}
	size = vec.size();
	for(int i = 0 ; i < size ; i++){
	    for(int j = i+1 ; j < size ; j++){
		Segment seg(vec[i],vec[j]);
		if(containPS(L,seg) && containPS(R,seg)){
		    double d = dist(vec[i],vec[j]);
		    G[i].push_back(Edge(j,d));
		    G[j].push_back(Edge(i,d));
		}
	    }
	    if(s == vec[i]) src = i;
	    if(t == vec[i]) dst = i;
	}
	double res = dijkstra(src,dst);
	if(res == INF){
	    cout << "impossible" << endl;
	}else{
	    printf("%.10f\n",res);
	}
    }
    return 0;
}

Measured memory_bytes: 3348