#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]); }

inline int ccw(const L &l, const 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;
  return 0;
}
inline int ccw(const L &l, const L &m) { return ccw(l,l[0]+m.v());}
inline int ccw2(const L &l, const P &p) { return abs(ccw(l,p)) == 1? ccw(l,p) : 0; }
inline int ccw2(const L &l, const L &m) { return ccw2(l,l[0]+m.v()); }
inline bool online(const L &l,const P &p) { return !ccw2(l,p); }
inline bool onseg2(const L &s,const P &p) { return ccw(L(s[0],p),s[1]) == -2; }
inline bool onseg(const L &s, const P &p) {
  return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}
inline bool sameline(const L &l, const L &m) { return !ccw2(l,m[0]) && !ccw2(l,m[1]); }
inline bool different(const L &l, const L &s) { return ccw2(l,s[0])*ccw2(l,s[1]) <= 0; }
inline bool different2(const L &l, const L &s) { return ccw(l,s[0])*ccw(l,s[1]) == -1; }
P projection(const L &l, const P &p) { return l[0] + dot(p-l[0],l.v()) / norm(l.v()) * l.v(); }
P reflection(const L &l, const P &p) { return p + P(2,0)* (projection(l,p)-p); }
inline bool intersectSS(const L &s, const L &t) { return different(s,t) && different(t,s); }
inline bool intersectSS2(const L &s, const 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);
}
// inline bool intersectLS(const L &l, const L &s) { return different(l,s); }
inline bool intersectLS(const L &l, const L &s) {
  return cross(l[1]-l[0], s[0]-l[0])*       // s[0] is left of l
         cross(l[1]-l[0], s[1]-l[0]) < EPS; // s[1] is right of l
}

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) {
    if (onseg(l,m[0])) return m[0];
    double r = -1;
    if (onseg(m,l[0])) r = abs(m[0]-l[0]);
    if (onseg(m,l[1])) {
      double rr = abs(m[0]-l[1]);
      if (r < -EPS || r > rr) {
        rr = r;
      }
    }
    if (r < EPS) return m[1];
    return m[0] + P(r/abs(m[1]-m[0]),0) * (m[1]-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(g, i) g[i]
#define next(g, i) g[i+1<g.size()?i+1:0]
#define prev(g, i) g[i?i-1:g.size()-1]

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 contain4(const G &g, const L &seg) {
  if (contains(g,seg[0]) == -1) return 0;
  if (contains(g,seg[1]) == -1) return 0;
  double len = abs(seg[0]-seg[1]);
  // if (len < EPS) return 1;
  typedef pair<double,int> pdi;
  vector<pdi> t;
  t.push_back(pdi(0,-1));
  t.push_back(pdi(1,-1));
  bool in = 0;
  REP(i,g.size()) {
    const L gl = gline(g,i);
    if (intersectLS(seg,gl)) {
      P cp = crosspoint(gl,seg);
      if (dot(seg[1]-seg[0], cp-seg[0]) < -EPS) {
        if (ccw(seg,gl[0]) == -1 || ccw(seg,gl[1]) == -1) {
          // cout << gl[0] << " " << gl[1] << endl;
          in = !in;
        }
      }
      if (intersectSS(gl, seg)) {
        if (intersectSS2(gl,seg)) return 0;
        t.push_back(pdi(abs(cp-seg[0])/len, i));
      }
    }
  }

  // sort(ALL(v));
  sort(ALL(t));
  // v.erase(unique(ALL(v)),v.end());

  // cout << in << endl;
  // FOR(it, t) cout << it->first << " " << it->second << endl;
  int id = 0;
  REP(i, t.size()-1) {
    P p = seg[0] + (t[i].first+t[i+1].first)/2*(seg[1]-seg[0]);
    double r = (t[i].first+t[i+1].first)/2;
    bool ok = 0;
    if (abs(t[i].first-t[i+1].first)<EPS) continue;
//    cout << "r = " << r << endl;
    while(id<t.size() && t[id].first < r + EPS) {
      int k = t[id].second;
      if (k == -1) {
        id++;
        continue;
      }
      // cout << k << " " << ccw2(seg,g[k]) << " " << ccw2(seg,next(g,k)) << endl;
      // cout << g[k] << "," << g[(k+1)%g.size()] << " " << r << " ; " << p << " " << cross(g[(k+1)%g.size()]-g[k], p-g[k]) << " " << ccw2(seg,next(g,k)) << " " << onseg(gline(g,k),p) << endl;
      
      if (ccw(seg,g[k]) == -1 || ccw(seg,next(g,k)) == -1) {
        in = !in;
      }
      if (onseg(gline(g,k),p)) {
        // cout << g[k] << " " << next(g,k) << " " << p << endl;
        ok = 1;
      }
      id++;
    }
    // cout << p << " " << id << " " << in << " " << ok << endl;
    if (!in && !ok) return 0;
  }
  return 1;
}

bool contain5(const G &g, const L &seg) {
  if (contains(g,seg[0]) == -1) return 0;
  if (contains(g,seg[1]) == -1) return 0;
  double len = abs(seg[0]-seg[1]);
  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;
      P cp = crosspoint(gline(g,i),seg);
      v.push_back(cp);
    }
  sort(ALL(v));
  // v.erase(unique(ALL(v)),v.end());
  
  int id = 0;
  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;
    int cnt = 0;
    REP(i,ps.size()) {
      REP(j,i) {
        L seg(ps[i],ps[j]);
        // cout << seg[0]-P(1,1) << " , " << seg[1]-P(1,1) << endl;
        if (contain4(vg[sid], seg) && contain4(vg2[sid2],seg)) {
          // cout << ps[i]-P(1,1) << " " << ps[j]-P(1,1) << endl;
          g[i].push_back(Edge(i,j,abs(seg.v())));
          g[j].push_back(Edge(j,i,abs(seg.v())));
          cnt++;
        }
      }
    }
    // cout << cnt << endl;
    double ans = dijkstra(g, start, dst);
    if (ans < EPS) {
      puts("impossible");
    } else {
      printf("%.10Lf\n", ans);
    }
  }
}

Measured memory_bytes: 1372