#include <iostream>
	#include <iomanip>
	#include <string>
	#include <vector>
	#include <algorithm>
	#include <limits>
	#include <cmath>

	namespace lc {
	static const double EPS = 1e-9;
	inline double abs(double x){ return std::abs(x); }
	inline bool tolerant_eq(double a, double b){ return abs(a - b) < EPS; }
	struct Point {
		double x;
		double y;
		explicit Point(const double &x = 0.0, const double &y = 0.0) :
			x(x), y(y)
		{ }
		static Point invalid(){
			double qnan = std::numeric_limits<double>::quiet_NaN();
			return Point(qnan, qnan);
		}
		bool is_valid() const { return !(std::isnan(x) || std::isnan(y)); }
		Point operator+(const Point &p) const { return Point(x + p.x, y + p.y); }
		Point &operator+=(const Point &p){ return *this = *this + p; }
		Point operator-(const Point &p) const { return Point(x - p.x, y - p.y); }
		Point &operator-=(const Point &p){ return *this = *this - p; }
		Point operator*(double s) const { return Point(x * s, y * s); }
		Point &operator*=(double s){ return *this = *this * s; }
		Point operator*(const Point &p) const {
			return Point(x * p.x - y * p.y, x * p.y + y * p.x);
		}
		Point &operator*=(const Point &p){ return *this = *this * p; }
		Point operator/(double s) const { return Point(x / s, y / s); }
		Point &operator/=(double s){ return *this = *this / s; }
		bool operator==(const Point &p) const { return x == p.x && y == p.y; }
		bool operator!=(const Point &p) const { return x != p.x || y != p.y; }
		bool operator<(const Point &p) const {
			return (x == p.x) ? (y < p.y) : (x < p.x);
		}
		double abs() const { return sqrt(x * x + y * y); }
		double norm() const { return x * x + y * y; }
		Point unit() const { return *this / abs(); }
		Point ortho() const { return Point(-y, x); }
		double arg() const { return atan2(y, x); }
	};
	inline Point operator*(double s, const Point &p){ return p * s; }
	inline bool tolerant_eq(const Point &a, const Point &b){
		return tolerant_eq(a.x, b.x) && tolerant_eq(a.y, b.y);
	}
	inline double cross(const Point &a, const Point &b){
		return a.x * b.y - a.y * b.x;
	}
	inline double dot(const Point &a, const Point &b){
		return a.x * b.x + a.y * b.y;
	}
	inline int ccw(const Point &a, const Point &b, const Point &c){
		Point d = b - a, e = c - a;
		if(cross(d, e) > 0.0){ return 1; }
		if(cross(d, e) < 0.0){ return -1; }
		if(dot(d, e) < 0.0){ return 2; }
		if(d.abs() < e.abs()){ return -2; }
		return 0;
	}
	struct Line {
		Point a;
		Point b;
		explicit Line(const Point &a = Point(), const Point &b = Point()) :
			a(a), b(b)
		{ }
		static Line invalid(){
			Point inv = Point::invalid();
			return Line(inv, inv);
		}
		bool is_valid() const { return a.is_valid() && b.is_valid(); }
		bool operator<(const Line &l) const {
			return (a == l.a) ? (b < l.b) : (a < l.a);
		}
		Point projection(const Point &p) const {
			double t = dot(p - a, b - a) / (b - a).norm();
			return a + t * (b - a);
		}
		Point reflection(const Point &p) const {
			return p + 2.0 * (projection(p) - p);
		}
		Point direction() const {
			return (b - a).unit();
		}
	};
	inline bool tolerant_eq(const Line &a, const Line &b){
		const double x = abs(cross(a.b - a.a, b.b - b.a));
		const double y = abs(cross(a.b - a.a, a.b - b.a));
		return x < EPS && y < EPS;
	}
	inline bool directed_tolerant_eq(const Line &a, const Line &b){
		if(!tolerant_eq(a, b)){ return false; }
		return tolerant_eq((a.a - a.b).unit(), (b.a - b.b).unit());
	}
	inline bool is_parallel(const Line &a, const Line &b){
		return abs(cross(a.b - a.a, b.b - b.a)) < EPS;
	}
	inline int ccw(const Line &l, const Point &p){
		return ccw(l.a, l.b, p);
	}
	inline double distance(const Point &a, const Line &b){
		const Point p = b.projection(a);
		return (a - p).abs();
	}
	inline std::vector<Point> convex_hull(const std::vector<Point> &points){
		const int n = points.size();
		std::vector<Point> ps(points);
		std::sort(ps.begin(), ps.end());
		std::vector<Point> ch(2 * n);
		int k = 0;
		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;
	}
	}

	using namespace std;
	const int dx[] = { -1, 0, 1, 0 };
	const int dy[] = { 0, -1, 0, 1 };

	int main(){
		ios_base::sync_with_stdio(false);
		cout << setiosflags(ios::fixed) << setprecision(10);
		int n;
		cin >> n;
		vector<int> x(n), y(n);
		for(int i = 1; i < n; ++i){
			int k, d;
			cin >> k >> d;
			x[i] = x[k] + dx[d];
			y[i] = y[k] + dy[d];
		}
		vector<lc::Point> points;
		points.reserve(n * 4);
		for(int i = 0; i < n; ++i){
			points.emplace_back(x[i] + 0, y[i] + 0);
			points.emplace_back(x[i] + 1, y[i] + 0);
			points.emplace_back(x[i] + 0, y[i] + 1);
			points.emplace_back(x[i] + 1, y[i] + 1);
		}
		const auto conv = convex_hull(points);
		const int m = conv.size();
		double answer = 1e20;
		for(int i = 0; i < m; ++i){
			const lc::Line l(conv[i], conv[(i + 1) % m]);
			double w = 0.0, lo = 0.0, hi = 0.0;
			for(int j = 0; j < m; ++j){
				const auto dot = lc::dot(l.b - l.a, conv[j] - l.a);
				const auto d = (l.a - l.projection(conv[j])).abs() * (dot < 0 ? -1 : 1);
				w = max(w, lc::distance(conv[j], l));
				lo = min(lo, d);
				hi = max(hi, d);
			}
			answer = min(answer, w * (hi - lo));
		}
		cout << answer << endl;
		return 0;
	}

Measured memory_bytes: 28708