#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <unordered_set>
#include <unordered_map>
#include <array>
#include <cassert>
#include <bitset>
using namespace std;
using LL = long long;
using FLOAT = long double;
const FLOAT EPS = 1e-8;
const FLOAT INF = 1e12;
const FLOAT PI = acos(-1);
typedef complex<FLOAT> P;

namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}


struct L : public vector<P> {
	L(const P& a, const P& b) {
		push_back(a); push_back(b);
	}
};
typedef vector<P> G;

FLOAT cross(const P& a, const P& b) {
	return imag(conj(a) * b);
}
FLOAT dot(const P& a, const P& b) {
	return real(conj(a) * b);
}

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

P projection(const L& l, const P& p) {
	FLOAT t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
	return l[0] + t * (l[0] - l[1]);
}

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;
}

FLOAT 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));
}

FLOAT distanceSS(const L & s, const L & t) {
	if (intersectSS(s, t))return 0;
	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])));
}

G convexHull(G ps) {
	int n = ps.size(), k = 0;
	assert(n >= 3);
	sort(ps.begin(), ps.end());
	G ch(2 * n);
	for (int i = 0; i < n; ch[k++] = ps[i++])
		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--])
		while (k >= t && ccw(ch[k - 2], ch[k - 1], ps[i]) <= 0)--k;
	ch.resize(k - 1);
	return ch;
}

struct edge {
	int to;
	FLOAT cost;
	edge(int to, FLOAT cost) :to(to), cost(cost) {}
};
using Pair = pair<FLOAT, int>;
void dijkstra(vector<edge>graph[], FLOAT dist[], int n, int s) {
	priority_queue<Pair, vector<Pair>, greater<Pair>>que;
	que.push({ 0LL,s });
	fill(dist, dist + n, INF);
	dist[s] = 0LL;
	while (!que.empty()) {
		auto q = que.top();
		que.pop();
		FLOAT thd = q.first;
		int thv = q.second;
		if (thd > dist[thv])
			continue;
		for (auto ed : graph[thv]) {
			if (dist[ed.to] > ed.cost + thd) {
				dist[ed.to] = ed.cost + thd;
				que.push({ dist[ed.to] , ed.to });
			}
		}
	}
}

enum { OUT, ON, IN };
int contains(const G & poly, const P & point) {
	bool in = false;
	for (int i = 0; i < poly.size(); ++i) {
		P a = poly[i] - point, b = poly[(i + 1) % poly.size()] - point;
		if (imag(a) > imag(b)) swap(a, b);
		if (imag(a) <= 0 && 0 < imag(b))
			if (cross(a, b) < 0) in = !in;
		if (cross(a, b) == 0 && dot(a, b) <= 0) return ON;
	}
	return in ? IN : OUT;
}

//#define int long long

signed main() {
	int N;
	cout.precision(15);
	cout << fixed;
	while (cin >> N, N) {
		vector<FLOAT>H;
		vector<G>poly;
		vector<edge>graph[123];
		for (int i = 0; i < N; ++i) {
			int NV;
			cin >> NV;
			FLOAT h; cin >> h;
			H.push_back(h);
			poly.push_back(G());
			for (int j = 0; j < NV; ++j) {
				FLOAT x, y;
				cin >> x >> y;
				poly.back().push_back({ x,y });
			}
		}
		FLOAT the, phi;
		cin >> the >> phi;
		the *= (PI / 180);
		phi *= (PI / 180);
		the += PI;
		N += 2;
		FLOAT sx, sy, gx, gy;
		cin >> sx >> sy >> gx >> gy;
		poly.push_back(G(2, P(sx, sy)));
		H.push_back(0);
		poly.push_back(G(2, P(gx, gy)));
		H.push_back(0);
		P kiso(cos(the) / tan(phi), sin(the) / tan(phi));
		for (int i = 0; i < N; ++i) {
			G& g = poly[i], tmp;
			for (auto p : g) {
				tmp.push_back(p + kiso * H[i]);
			}
			for (auto p : tmp) {
				g.push_back(p);
			}
			g = convexHull(g);
		}
		for (int i = 0; i < N; ++i) {
			for (int j = 0; j < i; ++j) {
				FLOAT dist = INF;
				//i-j双方向に辺を張る
				for (int vi = 0; vi < poly[i].size(); vi++) {
					L L1 = { poly[i][vi],poly[i][(vi + 1) % poly[i].size()] };
					for (int vj = 0; vj < poly[j].size(); vj++) {
						L L2 = { poly[j][vj],poly[j][(vj + 1) % poly[j].size()] };
						dist = min(dist, distanceSS(L1, L2));
					}
				}
				if (j == N - 2 || j == N - 1) {
					if (contains(poly[i], poly[j][0])) {
						dist = 0;
					}
				}
				if (i == N - 2 || i == N - 1) {
					if (contains(poly[j], poly[i][0])) {
						dist = 0;
					}
				}
				graph[i].push_back({ j,dist });
				graph[j].push_back({ i,dist });
			}
		}
		FLOAT dist[123];
		dijkstra(graph, dist, N, N - 2);
		cout << dist[N - 1] << endl;
	}

}

