#include <bits/stdc++.h>
using namespace std;

const double EPS = 1e-8;
const double INF = 1e12;
typedef complex<double> P;
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 : public vector<P> {
    L(const P &a, const P &b) {
        push_back(a); push_back(b);
    }
};

typedef vector<P> G;

struct C {
    P p; double r;
    C(const P &p, double r) : p(p), r(r) { }
};

int ccw(P a, P b, P c) {
    b -= a; c -= a;
    if (cross(b, c) > 0)   return +1;       // counter clockwise
    if (cross(b, c) < 0)   return -1;       // clockwise
    if (dot(b, c) < 0)     return +2;       // c--a--b on line
    if (norm(b) < norm(c)) return -2;       // a--b--c on line
    return 0;
}

typedef P point;

vector<point> convex_hull(vector<point> ps) {
    int n = ps.size(), k = 0;
    sort(ps.begin(), ps.end());
    vector<point> ch(2*n);
    for (int i = 0; i < n; ch[k++] = ps[i++]) // lower-hull
        while (k >= 2 && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
    for (int i = n-2, t = k+1; i >= 0; ch[k++] = ps[i--]) // upper-hull
        while (k >= t && ccw(ch[k-2], ch[k-1], ps[i]) <= 0) --k;
    ch.resize(k-1);
    return ch;
}

typedef vector<point> polygon;

enum { OUT, ON, IN };
int convex_contains(const polygon &P, const point &p) {
    const int n = P.size();
    point g = (P[0] + P[n/3] + P[2*n/3]) / 3.0; // inner-point
    int a = 0, b = n;
    while (a+1 < b) { // invariant: c is in fan g-P[a]-P[b]
        int c = (a + b) / 2;
        if (cross(P[a]-g, P[c]-g) > 0) { // angle < 180 deg
            if (cross(P[a]-g, p-g) > 0 && cross(P[c]-g, p-g) < 0) b = c;
            else                                                  a = c;
        } else {
            if (cross(P[a]-g, p-g) < 0 && cross(P[c]-g, p-g) > 0) a = c;
            else                                                  b = c;
        }
    }
    b %= n;
    if (cross(P[a] - p, P[b] - p) < 0) return 0;
    if (cross(P[a] - p, P[b] - p) > 0) return 2;
    return 1;
}

class Dijkstra {
    int n;
    vector<vector<pair<int, double>>> adj;
    vector<double> d;

public:
    Dijkstra(int n) : n(n), adj(n), d(n, numeric_limits<double>::infinity()) {}

    void add_edge(int a, int b, double w) {
        assert(0 <= a && a < n && 0 <= b && b < n);
        // cerr << "add edge (" << a << ", " << b << ", " << w << ")" << endl;
        adj[a].emplace_back(b, w);
        adj[b].emplace_back(a, w);
    }

    void add_arc(int a, int b, double w) {
        assert(0 <= a && a < n && 0 <= b && b < n);
        adj[a].emplace_back(b, w);
    }

    void run(int a) {
        d[a] = 0;
        priority_queue<pair<double, int>, vector<pair<double, int>>, greater<pair<double, int>>> que;
        que.emplace(0, a);

        while (que.size()) {
            auto top = que.top();
            que.pop();
            int u = top.second;

            for (auto& p : adj[u]) {
                int v = p.first;
                double w = p.second;
                if (d[u] + w < d[v]) {
                    d[v] = d[u] + w;
                    que.emplace(d[v], v);
                }
            }
        }
    }

    double dist(int a) {
        return d[a];
    }
};

bool EQ(double a, double b) {
    return abs(a - b) < EPS;
}

bool GE(double a, double b) {
    return a - b > -EPS;
}

double LE(double a, double b) {
    return a - b < EPS;
}

bool intersect_1pt(const point& a, const point& b,
                   const point& c, const point& d, point &r) {
    double D =  cross(b - a, d - c);
    if (EQ(D, 0)) return false;
    double t =  cross(c - a, d - c) / D;
    double s = -cross(a - c, b - a) / D;
    r = a + t * (b - a);
    return GE(t, 0) && LE(t, 1) && GE(s, 0) && LE(s, 1);
}
polygon convex_intersect(const polygon &P, const polygon &Q) {
    const int n = P.size(), m = Q.size();
    int a = 0, b = 0, aa = 0, ba = 0;
    enum { Pin, Qin, Unknown } in = Unknown;
    polygon R;
    do {
        int a1 = (a+n-1) % n, b1 = (b+m-1) % m;
        double C = cross(P[a] - P[a1], Q[b] - Q[b1]);
        double A = cross(P[a1] - Q[b], P[a] - Q[b]);
        double B = cross(Q[b1] - P[a], Q[b] - P[a]);
        point r;
        if (intersect_1pt(P[a1], P[a], Q[b1], Q[b], r)) {
            if (in == Unknown) aa = ba = 0;
            R.push_back( r );
            in = B > 0 ? Pin : A > 0 ? Qin : in;
        }
        if (C == 0 && B == 0 && A == 0) {
            if (in == Pin) { b = (b + 1) % m; ++ba; }
            else           { a = (a + 1) % m; ++aa; }
        } else if (C >= 0) {
            if (A > 0) { if (in == Pin) R.push_back(P[a]); a = (a+1)%n; ++aa; }
            else       { if (in == Qin) R.push_back(Q[b]); b = (b+1)%m; ++ba; }
        } else {
            if (B > 0) { if (in == Qin) R.push_back(Q[b]); b = (b+1)%m; ++ba; }
            else       { if (in == Pin) R.push_back(P[a]); a = (a+1)%n; ++aa; }
        }
    } while ( (aa < n || ba < m) && aa < 2*n && ba < 2*m );
    if (in == Unknown) {
        if (convex_contains(Q, P[0])) return P;
        if (convex_contains(P, Q[0])) return Q;
    }
    return R;
}

bool intersectLL(const L &l, const L &m) {
    return abs(cross(l[1]-l[0], m[1]-m[0])) > EPS || // non-parallel
           abs(cross(l[1]-l[0], m[0]-l[0])) < EPS;   // same line
}
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
}
bool intersectLP(const L &l, const P &p) {
    return abs(cross(l[1]-p, l[0]-p)) < EPS;
}
bool intersectSS(const L &s, const L &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;
}
bool intersectSP(const L &s, const P &p) {
    return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < EPS; // triangle inequality
}

P projection(const L &l, const P &p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
P reflection(const L &l, const P &p) {
    return p + 2.0 * (projection(l, p) - p);
}
double distanceLP(const L &l, const P &p) {
    return abs(p - projection(l, p));
}
double distanceLL(const L &l, const L &m) {
    return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
double distanceLS(const L &l, const L &s) {
    if (intersectLS(l, s)) return 0;
    return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
double distanceSP(const L &s, const P &p) {
    const P r = projection(s, p);
    if (intersectSP(s, r)) return abs(r - p);
    return min(abs(s[0] - p), abs(s[1] - p));
}
double distanceSS(const L &s, const L &t) {
    if (intersectSS(s, t)) return 0;
    return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
               min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
P crosspoint(const L &l, const L &m) {
    double A = cross(l[1] - l[0], m[1] - m[0]);
    double B = cross(l[1] - l[0], l[1] - m[0]);
    if (abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
    if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
    return m[0] + B / A * (m[1] - m[0]);
}

double distance(const polygon &P, const polygon &Q) {
    polygon isec = convex_intersect(P, Q);
    if (isec.size()) return 0;
    double ret = 1e9;
    for (int i = 0; i < P.size(); i++) {
        for (int j = 0; j < Q.size(); j++) {
            L lp = {P[i], P[(i + 1) % P.size()]};
            L lq = {Q[j], Q[(j + 1) % Q.size()]};
            ret = min(ret, distanceSS(lp, lq));
        }
    }
    return ret;
}

double distance(const polygon &P, const point &p) {
    int k = convex_contains(P, p);
    if (k == IN || k == ON) return 0;
    double ret = 1e9;
    for (int i = 0; i < P.size(); i++) {
        L l = {P[i], P[(i + 1) % P.size()]};
        ret = min(ret, distanceSP(l, p));
    }
    return ret;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    int cnt = 0;
    while (cin >> n) {
        if (n == 0) break;
        // cerr << "Case #" << ++cnt << endl;
        vector<polygon> polygons;
        vector<vector<point>> points;
        vector<int> ks(n), hs(n);
        for (int i = 0; i < n; i++) {
            cin >> ks[i] >> hs[i];
            // cerr << "fuga " << ks[i] << ' ' << hs[i] << endl;
            vector<point> ps;
            for (int j = 0; j < ks[i]; j++) {
                double a, b;
                cin >> a >> b;
                ps.push_back(point(a, b));
            }
            points.emplace_back(ps);
        }
        double theta, phi;
        cin >> theta >> phi;
        phi = phi / 180 * acos(-1);
        theta = theta / 180 * acos(-1);
        // cerr << "tan(phi) = " << tan(phi) << endl;
        for (int j = 0; j < n; j++) {
            double dx = hs[j] / tan(phi) * cos(theta), dy = hs[j] / tan(phi) * sin(theta);
            // cerr << "dx : " << dx << ", dy : " << dy << endl;
            for (int i = 0; i < ks[j]; i++) {
                double a = points[j][i].real(), b = points[j][i].imag();
                points[j].push_back(point(a - dx, b - dy));
            }
            polygon poly = convex_hull(points[j]);
            // cerr << "polygon " << j << ": ";
            for (int i = 0; i < poly.size(); i++) {
                // cerr << "(" << poly[i].real() << ", " << poly[i].imag() << "), ";
            }
            // cerr << endl;
            polygons.emplace_back(poly);
        }
        // cerr << "read polygon" << endl;
        double sx, sy, tx, ty;
        cin >> sx >> sy >> tx >> ty;
        // cerr << "hoge" << sx << ' ' << sy << ' ' << tx << ' ' << ty << endl;
        Dijkstra g(n + 2);
        g.add_edge(n, n + 1, hypot(sx - tx, sy - ty));
        for (int i = 0; i < n; i++) {
            g.add_edge(i, n, distance(polygons[i], point(sx, sy)));
            g.add_edge(i, n + 1, distance(polygons[i], point(tx, ty)));
        }
        // cerr << "piyo" << endl;
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                g.add_edge(i, j, distance(polygons[i], polygons[j]));
            }
        }
        // cerr << "added edge" << endl;
        g.run(n);
        printf("%.10f\n", g.dist(n + 1));
    }
}



Measured memory_bytes: 3964