#include<iostream>
#include<vector>
#include<algorithm>
#include<cmath>
#include<cstdio>
using namespace std;

// ---------- lib ----------
class Point {
public:
	long double px, py;
	Point() : px(0), py(0) {};
	Point(long double px_, long double py_) : px(px_), py(py_) {};
	bool operator==(const Point& p) const { return px == p.px && py == p.py; }
	bool operator!=(const Point& p) const { return px != p.px || py != p.py; }
	bool operator<(const Point& p) const { return px < p.px ? true : (px == p.px && py < p.py); }
	bool operator>(const Point& p) const { return px > p.px ? true : (px == p.px && py > p.py); }
	bool operator<=(const Point& p) const { return !(Point(px, py) > p); }
	bool operator>=(const Point& p) const { return !(Point(px, py) < p); }
	Point operator+(const Point& p) const { return Point(px + p.px, py + p.py); }
	Point operator-(const Point& p) const { return Point(px - p.px, py - p.py); }
	Point operator/(long double d) const { return Point(px / d, py / d); }
	friend Point operator*(const Point p, long double d) { return Point(p.px * d, p.py * d); }
	friend Point operator*(long double d, const Point& p) { return p * d; }
	Point& operator+=(const Point& p1) { px += p1.px, py += p1.py; return *this; }
	Point& operator-=(const Point& p1) { px -= p1.px, py -= p1.py; return *this; }
	Point& operator*=(long double d) { px *= d, py *= d; return *this; }
	Point& operator/=(long double d) { px /= d, py /= d; return *this; }
};
struct Line { Point p1, p2; };

long double norm(const Point& a) { return a.px * a.px + a.py * a.py; }
long double dot(const Point& a, const Point& b) { return a.px * b.px + a.py * b.py; }
long double abs(const Point& a) { return sqrtl(norm(a)); }
long double crs(const Point& a, const Point& b) { return a.px * b.py - a.py * b.px; }
int ccw(const Point& p0, const Point& p1, const Point& p2) {
	Point a = p1 - p0, b = p2 - p0;
	if (crs(a, b) > 1e-10) return 1;
	if (crs(a, b) < -1e-10) return -1;
	if (dot(a, b) < -1e-10) return 2;
	if (norm(a) < norm(b)) return -2;
	return 0;
}
vector<Point> convex_hull(vector<Point> v) {
	if (v.size() < 3) return v;
	sort(v.begin(), v.end());
	vector<Point> u = { v[0], v[1] }, l = { v[v.size() - 1], v[v.size() - 2] };
	for (int i = 2; i < v.size(); i++) {
		for (int n = u.size(); n >= 2 && ccw(u[n - 2], u[n - 1], v[i]) >= 0; n--) u.pop_back();
		u.push_back(v[i]);
	}
	for (int i = v.size() - 3; i >= 0; i--) {
		for (int n = l.size(); n >= 2 && ccw(l[n - 2], l[n - 1], v[i]) >= 0; n--) l.pop_back();
		l.push_back(v[i]);
	}
	reverse(l.begin(), l.end());
	for (int i = u.size() - 2; i >= 1; i--) l.push_back(u[i]);
	return l;
}
long double dst(const Point& a, const Point& b) { return abs(b - a); }
Point prj(const Line& a, const Point& b) { return a.p1 + (a.p2 - a.p1) * dot(b - a.p1, a.p2 - a.p1) / norm(a.p2 - a.p1); }
long double dst(const Line& a, const Point& b) { return abs(crs(a.p2 - a.p1, b - a.p1) / abs(a.p2 - a.p1)); }
// ---------- end ----------

int n, X[100000], Y[100000]; Point G[400000];
int dy[4] = { -1,0,1,0 }, dx[4] = { 0,1,0,-1 };
vector<Point>T, U;

int main() {
	cin >> n; X[0] = 0; Y[0] = 0;
	for (int i = 1; i < n; i++) {
		int a, b; cin >> a >> b; X[i] = X[a] + dx[b]; Y[i] = Y[a] + dy[b];
	}
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < 2; j++)for (int k = 0; k < 2; k++) {
			G[i * 4 + j * 2 + k] = Point(X[i] + j,Y[i] + k);
		}
	}
	sort(G, G + n * 4); T.push_back(G[0]);
	for (int i = 1; i < n * 4; i++) {
		if (G[i] != G[i - 1])T.push_back(G[i]);
	}
	U = convex_hull(T);
	long double maxn = 1e12;
	//---shakutorization---
	int pos1 = 0, pos2 = 0, pos3 = 0;
	for (int i = 0; i < U.size(); i++) {
		Line W = Line{ U[i],U[(i + 1) % U.size()] };
		long double maxy = 0, minx = 1e12, maxx = -1e12;
		if (i == 0) {
			for (int j = 0; j < U.size(); j++) {
				long double DST = dst(W, U[j]);
				if (maxy < DST) { maxy = DST; pos1 = j; }
				Point PP = prj(W, U[j]);
				long double DST2 = dst(U[i], PP);
				if ((PP < U[i]) == (W.p1 < W.p2))DST2 *= -1;
				if (maxx < DST2) { maxx = DST2; pos2 = j; }
				if (minx > DST2) { minx = DST2; pos3 = j; }
			}
		}
		else {
			while (true) {
				long double DST = dst(W, U[pos1]);
				if (maxy > DST) { pos1 = (pos1 + U.size() - 1) % U.size(); break; } 
				maxy = DST; pos1 = (pos1 + 1) % U.size();
			}
			while (true) {
				Point PP = prj(W, U[pos2]);
				long double DST = dst(U[i], PP);
				if ((PP < U[i]) == (W.p1 < W.p2))DST *= -1;
				if (maxx > DST) { pos2 = (pos2 + U.size() - 1) % U.size(); break; }
				maxx = DST; pos2 = (pos2 + 1) % U.size();
			}
			while (true) {
				Point PP = prj(W, U[pos3]);
				long double DST = dst(U[i], PP);
				if ((PP < U[i]) == (W.p1 < W.p2))DST *= -1;
				if (minx < DST) { pos3 = (pos3 + U.size() - 1) % U.size(); break; }
				minx = DST; pos3 = (pos3 + 1) % U.size();
			}
		}
		maxn = min(maxn, maxy*(maxx - minx));
	}
	printf("%.20Lf\n", maxn);
	return 0;
}

Measured memory_bytes: 46080