#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cassert>
#include <vector>
#include <cstring>
#include <set>
#include <map>
#include <cmath>
#include <queue>
#include <complex>
using namespace std;
#define REP(i,n) for (int i=0; i<(int)n; ++i)
#define FOR(i,c) for (__typeof((c).begin())i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(),(c).end()

#define double long double
const double EPS = 1e-8;
const double INF = 1e9;
const double PI = acos(-1);

typedef complex<double> P;
P pIN() { double x,y; cin >> x >> y; return P(x,y); }
namespace std {
  bool operator<(const P &a, const P &b) {
    return real(a) != real(b) ? real(a) < real(b): imag(a) < imag(b);
  }
}
double cross(const P &a, const P &b) {
  return imag(conj(a)*b);
}
double dot(const P &a, const P &b) {
  return real(conj(a)*b);
}
struct L : vector<P> {
  L(const P &a, const P &b) {
    push_back(a); push_back(b);
  }
  L(){}
  P v() const { return (*this)[1]- (*this)[0]; }
};
typedef vector<P> G;
inline L gline(const G &g, int i) { return L(g[i],g[(i+1)<g.size()?i+1:0]); }

int ccw(L l, P p) {
  P b = l.v(), c = p-l[0];
  if (cross(b,c) > EPS) return 1;
  if (cross(b,c) < -EPS) return -1;
  if (dot(b,c) < -EPS) return 2;
  if (EPS<norm(b) && norm(b) < norm(c)-EPS) return -2;
}
int ccw(L l, L m) { return ccw(l,l[0]+m.v());}
int ccw2(L l, P p) { return abs(ccw(l,p)) == 1? ccw(l,p) : 0; }
int ccw2(L l, L m) { return ccw2(l,l[0]+m.v()); }
bool online(L l, P p) { return !ccw2(l,p); }
bool onseg2(L s, P p) { return ccw(L(s[0],p),s[1]) == -2; }
bool onseg(L s, P p) { return !ccw(s,p); }
bool sameline(L l, L m) { return !ccw2(l,m[0]) && !ccw2(l,m[1]); }
bool parallel(L l, L m) { return !ccw2(l,m); }
bool different(L l, L s) { return ccw2(l,s[0])*ccw2(l,s[1]) <= 0; }
bool different2(L l, L s) { return ccw(l,s[0])*ccw(l,s[1]) == -1; }
P projection(L l, P p) { return l[0] + dot(p-l[0],l.v()) / norm(l.v()) * l.v(); }
P reflection(L l, P p) { return p + P(2,0)* (projection(l,p)-p); }
bool intersectSS(L s, L t) { return different(s,t) && different(t,s); }
bool intersectSS2(L s, L t) { 
  return different2(s,t) && different2(t,s);
  // if (sameline(s,t)) return onseg2(s,t[0]) || onseg2(s,t[1]);
  // else return different2(s,t) && different2(t,s);
}
P crosspoint(const L &l, const L &m) {
  double A = cross(l.v(), m.v());
  double B = cross(l.v(), l[1]-m[0]);
  if (abs(A) < EPS && abs(B) < EPS) return m[0];
  if (abs(A) < EPS) assert(false);
  return m[0] + B/A*m.v();
}
// #define curr(g, i) g[i]
// #define next(g, i) g[(i+1)%g.size()]
#define curr(P, i) P[i]
#define next(P, i) P[(i+1)%P.size()]

int contains(const G &g, const P &p) {
  bool in = 0;
  REP(i,g.size()) {
    P a = g[i] - p;
    P b = next(g,i) - p;
    if (imag(a) > imag(b)) swap(a,b);
    if (imag(a) <= 0 && 0 < imag(b))
      if (cross(a,b) < 0) in = !in;
    if (abs(cross(a,b))< EPS && dot(a,b) <= EPS) return 0;
  }
  return in?1:-1;
}

// bool contain2(const G &g, const L &seg) {
//   if (contains(g,seg[0]) == -1) return 0;
//   if (contains(g,seg[1]) == -1) return 0;
//   P pp = seg[0];
//   int N = 100;
//   REP(i,N) {
//     if (contains(g,pp) == -1) return 0;
//     pp += (seg[1]-seg[0]) * P(1.0/N,0);
//   }
//   REP(i,g.size()) {
//     L l(g[i],g[(i+1)%g.size()]);
//     if (intersectSS2(l,seg)) return 0;
//   }
//   return 1;
// }

bool contain2(const G &g, const L &seg) {
  if (contains(g,seg[0]) == -1) return 0;
  if (contains(g,seg[1]) == -1) return 0;

  vector<P> v;
  v.push_back(seg[0]);
  v.push_back(seg[1]);
  REP(i,g.size())
    if (intersectSS(gline(g,i), seg)) {
      if (intersectSS2(gline(g,i),seg)) return 0;
      v.push_back(crosspoint(gline(g,i),seg));
    }
  sort(ALL(v));
  v.erase(unique(ALL(v)),v.end());
  REP(i, v.size()-1) {
    P p = (v[i]+v[i+1])*P(0.5,0);
    if (contains(g,p) == -1) return 0;
  }
  return 1;
}

typedef double Weight;
struct Edge {
  int src, dst;
  Weight weight;
  Edge(int src, int dst, Weight weight) :
    src(src), dst(dst), weight(weight) {}
};
bool operator<(const Edge &e, const Edge &f) {
  return e.weight > f.weight;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
Weight dijkstra(const Graph &g, int s, int t) {
  vector<Weight> dist(g.size(), INF);
  dist[s] = 0;
  priority_queue<Edge> Q;
  for (Q.push(Edge(-2,s,0)); !Q.empty();)  {
    Edge e = Q.top(); Q.pop();
    if (dist[e.dst] < e.weight) continue;
    if (e.dst == t) return dist[t];
    FOR(f,g[e.dst]) {
      if (dist[f->dst] > e.weight +f->weight) {
        dist[f->dst] = e.weight + f->weight;
        Q.push(Edge(f->src, f->dst, e.weight+f->weight));
      }
    }
  }
  return -1;
}
int main() {
  int n;
  while(cin >> n,n) {
    vector<G> vg;
    REP(i,n) {
      G g;
      int m;
      cin  >> m;
      REP(j,m) {
        g.push_back(pIN());
      }
      vg.push_back(g);
    }
    P s(pIN());
    P t(pIN());
    P ss(pIN());
    P tt(pIN());
    L mirror(ss,tt);
    bool hanten[n];
    vector<G> vg2(vg);
    REP(i,n) {
      int c = ccw2(mirror,vg[i][0]);
      assert(c != 0);
      if (c == ccw2(mirror,s)) {        
        hanten[i] = 0;
      }else {
        FOR(it, vg2[i]) {
          *it = reflection(mirror,*it);
        }
        reverse(ALL(vg2[i]));
        hanten[i] = 1;
      }
    }
    P s2 = reflection(mirror,s);
    P t2 = reflection(mirror,t);
    int sid = -1;
    int tid = -1;
    // cout << s << " " << t << endl;
    // REP(i,n) {
    //   FOR(it, vg[i]) {
    //     cout << *it << " ";
    //   }
    //   cout << endl;
    // }
    REP(i,n) {
      // cout << i << " " << contains(vg[i], s) << endl;
      if (contains(vg[i], s) >= 0) sid = i;
      if (contains(vg[i], t) >= 0) tid = i;
    }
    assert(sid == tid && sid != -1);
    int sid2 = -1;
    int tid2 = -1;
    REP(i,n) {
      if (contains(vg[i], s2) >= 0) sid2 = i;
      if (contains(vg[i], t2) >= 0) tid2 = i;
    }
    if (sid2 == -1 || tid2 == -1 || sid2 != tid2) {
      puts("impossible");
      continue;
    }
    vector<P> ps;
    FOR(jt, vg2[sid2]) {
      ps.push_back(*jt);
    }
    REP(i, vg[sid].size()) {
      L l1(vg[sid][i], next(vg[sid],i));
      REP(j,vg2[sid2].size()) {
        L l2(vg2[sid2][i], next(vg2[sid2],i));
        if (intersectSS(l1,l2)) {
          ps.push_back(crosspoint(l1,l2));
        }
      }
      ps.push_back(vg[sid][i]);
    }
    sort(ALL(ps));
    ps.erase(unique(ALL(ps)), ps.end());
    int start = ps.size();
    ps.push_back(s);
    int dst = ps.size();
    ps.push_back(t);

    Graph g(ps.size());
    // cout << sid2 << endl;
    // FOR(it, vg2[sid2]) {
    //   cout << *it << " ";
    // }
    // cout << endl;
    // cout << contain(L(vg2[sid2][3],vg2[sid2][4]), L(s,t)) << endl;
    REP(i,ps.size()) {
      REP(j,i) {
        L seg(ps[i],ps[j]);
        if (contain2(vg[sid], seg) && contain2(vg2[sid2],seg)) {
          // cout << ps[i] << " " << ps[j] << endl;
          g[i].push_back(Edge(i,j,abs(seg.v())));
          g[j].push_back(Edge(j,i,abs(seg.v())));
        }
      }
    }
    double ans = dijkstra(g, start, dst);
    if (ans < EPS) {
      puts("impossible");
    } else {
      printf("%.10Lf\n", ans);
    }
  }
}

Measured memory_bytes: 1376