#include<algorithm>
#include<complex>
#include<cstdio>
#include<iostream>
#include<queue>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)
template<class T> T at(vector<T> v, int i) {return v[i % v.size()];}

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
struct L{P a, b;};
typedef vector<P> Pol;

const D EPS = 1e-8;
const D PI = acos(-1);

// 比較関数
int sig(D a, D b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
bool near(P a, P b) {return !sig(norm(a - b));}
namespace std {
  bool operator<(P a, P b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
  bool operator<(L a, L b) {return !near(a.a, b.a) ? a.a < b.a : a.b < b.b;}
}

// 平方根
D sr(D a) {return sqrt(max(a, (D)0));}

// 内積
D dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
// 外積
D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

// 線分のベクトル
P vec(L a) {return a.b - a.a;}

// 線分abに対する点cの位置
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(P a, P b, P c) {
  if (near(a, c) || near(b, c)) return ON;
  int s = sig(det(b - a, c - a));
  if (s) return s > 0 ? LEFT : RIGHT;
  return (a < b) == (b < c) ? FRONT : (c < a) == (a < b) ? BACK : ON;
}

// 有向角度
D arg(P base, P a, P b) {return arg((b - base) / (a - base));}
L sortBase;
bool lessArg(P a, P b) {
  D ang1 = arg(sortBase.a, sortBase.b, a);
  D ang2 = arg(sortBase.a, sortBase.b, b);
  return sig(ang1, ang2) ? ang1 < ang2 : norm(a) > norm(b);
}

// 射影
P proj(P a, P b) {return a * dot(a, b) / norm(a);}
P perp(L l, P p) {return l.a + proj(vec(l), p - l.a);}
P refl(L l, P p) {return perp(l, p) * (D)2 - p;}

// 交差判定
bool eqL(L a, L b) {return !sig(det(vec(a), vec(b))) && !sig(det(vec(a), b.a - a.a));}
bool iLL(L a, L b) {return sig(det(vec(a), vec(b))) || !sig(det(vec(a), b.a - a.a));}
bool iLLs(L a, L b) {return sig(det(vec(a), vec(b)));}
bool iLS(L a, L b) {return sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) <= 0;}
bool iLSs(L a, L b) {return sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) < 0;}
bool iSS(L a, L b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}
bool iSSs(L a, L b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return (cwa & cwb) == (LEFT | RIGHT);
}

// 交点
P pLL(L a, L b) {return a.a + vec(a) * (det(vec(b), b.a - a.a) / det(vec(b), vec(a)));}

// 距離
D dLP(L l, P p) {return abs(det(vec(l), p - l.a) / vec(l));}
D dSP(L s, P p) {
  if (dot(vec(s), p - s.a) < 0) return abs(p - s.a);
  if (dot(vec(s), p - s.b) > 0) return abs(p - s.b);
  return dLP(s, p);
}
D dLL(L a, L b) {return iLL(a, b) ? 0 : dLP(a, b.a);}
D dLS(L a, L b) {return iLS(a, b) ? 0 : min(dLP(a, b.a), dLP(a, b.b));}
D dSS(L a, L b) {return iSS(a, b) ? 0 : min(min(dSP(a, b.a), dSP(a, b.b)), min(dSP(b, a.a), dSP(b, a.b)));}

// 円
struct C{P c; D r;};

// 2円の位置関係
enum RELATION{SAME = 1, CONTAIN = 2, OVER = 4, NO_CROSS = 8, ONE_CROSS = 16, ONE_CONTAIN_CROSS = 32, ONE_OVER_CROSS = 64, TWO_CROSS = 128};
int cRel(C c1, C c2) {
  D d = abs(c1.c - c2.c);
  if (near(c1.c, c2.c) && !sig(c1.r, c2.r)) return SAME;
  if (sig(d, c1.r - c2.r) < 0) return OVER;
  if (sig(d, c2.r - c1.r) < 0) return CONTAIN;
  if (!sig(d, c1.r - c2.r)) return ONE_OVER_CROSS;
  if (!sig(d, c2.r - c1.r)) return ONE_CONTAIN_CROSS;
  if (!sig(d, c1.r + c2.r)) return ONE_CROSS;
  if (sig(d, c1.r + c2.r) > 0) return NO_CROSS;
  return TWO_CROSS;
}

// 交差判定
bool iCP(C c, P p) {return sig(abs(p - c.c), c.r) <= 0;}
bool iCL(C c, L l) {return sig(c.r, dLP(l, c.c)) >= 0;}
bool iCS(C c, L s) {return sig(c.r, dSP(s, c.c)) >= 0;}
bool iCSc(C c, L s) {return iCS(c, s) && sig(c.r, max(abs(s.a - c.c), abs(s.b - c.c))) >= 0;}
bool iCC(C a, C b) {return sig(abs(a.c - b.c), a.r + b.r) <= 0;}
bool iCCc(C a, C b) {return iCC(a, b) && sig(abs(a.c - b.c), abs(a.r - b.r)) >= 0;}

// 交点
pair<P, P> pCC(C a, C b) {
  D x = (norm(a.c - b.c) + a.r * a.r - b.r * b.r) / (2 * abs(a.c - b.c));
  P e = (b.c - a.c) / abs(b.c - a.c);
  P y = e * P(0, sr(a.r * a.r - x * x));
  return make_pair(a.c + e * x - y, a.c + e * x + y);
}
pair<P, P> pCL(C c, L l) {
  P x = perp(l, c.c);
  P y = vec(l) / abs(vec(l)) * sr(c.r * c.r - norm(x - c.c));
  return make_pair(x - y, x + y);
}

// 角の内外判定 角abの内部にあれば正、辺上は0、外部は負
int sAP(P a, P b, P c) {return sig(det(a, c)) - sig(det(b, c)) - sig(det(a, b));}

// 多角形の面積
D aPol(Pol vp) {
  D ret = 0;
  rep (i, vp.size()) ret += det(vp[i], at(vp, i + 1));
  return ret / 2;
}

// 多角形の内外判定 内部:1、周上:0、外部:-1
int sGP(Pol pol, P p) {
  int side = -1;
  rep (i, pol.size()) {
    P p0 = pol[i] - p, p1 = at(pol, i + 1) - p;
    if (ccw(p0, p1, 0) == ON) return 0;
    if (p0.Y > p1.Y) swap(p0, p1);
    if (sig(p0.Y) <= 0 && 0 < sig(p1.Y) && sig(det(p0, p1)) > 0) side *= -1;
  }
  return side;
}

// 凸包
Pol convexHull(Pol p) {
  int m = -1, n = p.size();
  if (n < 3) return p;
  vector<P> q(n * 2);
  sort(p.begin(), p.end());
  for (int i = 0; i < n; q[++m] = p[i++])
    for (; m > 0 && ccw(q[m - 1], q[m], p[i]) != LEFT; --m);
  for (int i = n - 2, r = m; i >= 0; q[++m] = p[i--])
    for (; m > r && ccw(q[m - 1], q[m], p[i]) != LEFT; --m);
  q.resize(m);
  return q;
}

// 凸包カット
Pol convexCut(Pol p, L l) {
  vector<P> q;
  rep (i, p.size()) {
    if (ccw(l.a, l.b, p[i]) != RIGHT) q.push_back(p[i]);
    L s = {p[i], at(p, i + 1)};
    if (iLSs(l, s)) q.push_back(pLL(l, s));
  }
  return q;
}

// 線分をマージする
vector<L> merge(vector<L> s) {
  rep (i, s.size()) if (s[i].b < s[i].a) swap(s[i].a, s[i].b);
  sort(s.begin(), s.end());
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j]) && !iLLs(s[i], s[j])) {
    s[j].b = max(s[i].b, s[j].b);
    s.erase(s.begin() + i--);
    break;
  }
  return s;
}

// 線分アレンジメント 隣の点への辺のみを持つ
vector<vector<int> > sArr(vector<L> s, vector<P> &vp) {
  s = merge(s);
  rep (i, s.size()) {
    vp.push_back(s[i].a);
    vp.push_back(s[i].b);
  }
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j])) vp.push_back(pLL(s[i], s[j]));
  sort(vp.begin(), vp.end());
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<int> > g(vp.size());
  rep (i, s.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (ccw(s[i].a, s[i].b, vp[j]) == ON) {
      v.push_back(make_pair(norm(vp[j] - s[i].a), j));
    }
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(v[j].second);
      g[v[j].second].push_back(v[j + 1].second);
    }
  }
  return g;
}

// 多角形と線分の交差判定
bool iGS(Pol pol, L s) {
  int n = pol.size();
  vector<int> sa(n + 1), sb(n + 1), sab(n + 1);
  pol.push_back(pol[0]);
  pol.push_back(pol[1]);
  rep (i, n + 1) {
    sa[i] = sig(det(pol[i + 1] - pol[i], s.a - pol[i]));
    sb[i] = sig(det(pol[i + 1] - pol[i], s.b - pol[i]));
    sab[i] = sig(det(s.b - s.a, pol[i] - s.a));
  }
  rep (i, n) if (sa[i] * sb[i] < 0 && sab[i] * sab[i + 1] < 0) return true;
  rep (i, n) {
    if (sa[i] == 0 && sb[i] > 0 && sig(dot(s.a - pol[i], s.a - pol[i + 1])) < 0) return true;
    if (sb[i] == 0 && sa[i] > 0 && sig(dot(s.b - pol[i], s.b - pol[i + 1])) < 0) return true;
  }
  rep (i, n) if (sab[i + 1] == 0 && sig(dot(pol[i + 1] - s.a, pol[i + 1] - s.b)) <= 0) {
    if (!near(pol[i + 1], s.a) && sAP(pol[i + 2] - pol[i + 1], pol[i] - pol[i + 1], s.a - pol[i + 1]) > 0) return true;
    if (!near(pol[i + 1], s.b) && sAP(pol[i + 2] - pol[i + 1], pol[i] - pol[i + 1], s.b - pol[i + 1]) > 0) return true;
  }
  return false;
}

const string IMP = "impossible";

int main() {
  while (true) {
    int n;
    cin >> n;
    if (n == 0) break;
    vector<Pol> vpol(n);
    rep (i, n) {
      int m;
      cin >> m;
      rep (j, m) {
	P p;
	cin >> p.X >> p.Y;
	vpol[i].push_back(p);
      }
    }
    P s, g, ss, gg;
    L l;
    cin >> s.X >> s.Y >> g.X >> g.Y >> l.a.X >> l.a.Y >> l.b.X >> l.b.Y;
    ss = refl(l, s); gg = refl(l, g);
    int pi1 = -1, pi2 = -1;
    rep (i, vpol.size()) if (sGP(vpol[i], s) >= 0) pi1 = i;
    rep (i, vpol.size()) if (sGP(vpol[i], ss) >= 0) pi2 = i;
    if (pi1 == -1 || pi2 == -1 || sGP(vpol[pi1], g) < 0 || sGP(vpol[pi2], gg) < 0) {
      puts(IMP.c_str());
      continue;
    }
    Pol pol1, pol2;
    pol1 = vpol[pi1];
    pol2 = vpol[pi2];
    rep (i, pol2.size()) pol2[i] = refl(l, pol2[i]);
    reverse(pol1.begin(), pol1.end());
    vector<P> vp;
    vp.push_back(s);
    vp.push_back(g);
    rep (i, pol1.size()) vp.push_back(pol1[i]);
    rep (i, pol2.size()) vp.push_back(pol2[i]);
    D dis[vp.size()];
    rep (i, vp.size()) dis[i] = 1e100;
    priority_queue<pair<D, int>, vector<pair<D, int> >, greater<pair<D, int> > > que;
    que.push(make_pair(0, 0));
    while (!que.empty()) {
      pair<D, int> now = que.top();
      que.pop();
      if (sig(dis[now.second], now.first) <= 0) continue;
      dis[now.second] = now.first;
      rep (i, vp.size()) {
	L s = (L){vp[now.second], vp[i]};
	if (iGS(pol1, s)) continue;
	if (iGS(pol2, s)) continue;
	que.push(make_pair(now.first + abs(vec(s)), i));
      }
    }
    if (dis[1] == 1e100) puts(IMP.c_str());
    else printf("%.12Lf\n", dis[1]);
  }
  return 0;
}

Measured memory_bytes: 1384