#include<bits/stdc++.h>
 
using namespace std;
 
#define eps 1e-8
 
struct Point
{
  double x, y;
 
  Point(double a = 0, double b = 0) :
    x(a), y(b)
  {
  }
 
  bool operator<(const Point& a) const
  {
    if(fabs(x - a.x) > eps) return x < a.x;
    return y < a.y;
  }
 
  bool operator==(const Point& a) const
  {
    return fabs(x - a.x) < eps && fabs(y - a.y) < eps;
  }
 
  Point operator+(const Point& a) const
  {
    return Point(x + a.x, y + a.y);
  }
 
  Point operator-(const Point& a) const
  {
    return Point(x - a.x, y - a.y);
  }
 
  Point operator/(const double val) const
  {
    return Point(x / val, y / val);
  }
 
  Point operator*(const double val) const
  {
    return Point(x * val, y * val);
  }
};
 
typedef Point Vector;
 
double dist(Point a, Point b)
{
  return hypot(a.x - b.x, a.y - b.y);
}
 
double dot(Point a, Point b)
{
  return a.x * b.x + a.y * b.y;
}
 
double cross2(Point a, Point b)
{
  return a.x * b.y - a.y * b.x;
}
 
double cross(Point o, Point a, Point b)
{
  return (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x);
}
 
int between(Point a, Point b, Point c)
{
  return dot(c - a, b - a) >= 0 && dot(c - b, a - b) >= 0;
}
 
int onSeg(Point a, Point b, Point c)
{
  return between(a, b, c) && fabs(cross(a, b, c)) < eps;
}
 
double distProjection(Point as, Point at, Point s)
{
  double a, b, c;
  a = at.y - as.y;
  b = as.x - at.x;
  c = -(a * as.x + b * as.y);
  return fabs(a * s.x + b * s.y + c) / hypot(a, b);
}
 
struct Seg
{
  Point s, e;
};
 
int calcIntersection(Seg a, Seg b, Point& p)
{
  double a1, b1, c1, a2, b2, c2;
  double d, dx, dy;
  a1 = a.s.y - a.e.y, b1 = -a.s.x + a.e.x;
  a2 = b.s.y - b.e.y, b2 = -b.s.x + b.e.x;
  c1 = a1 * a.s.x + b1 * a.s.y;
  c2 = a2 * b.s.x + b2 * b.s.y;
  d = a1 * b2 - a2 * b1;
  dx = c1 * b2 - c2 * b1;
  dy = a1 * c2 - a2 * c1;
  if(fabs(d) < eps) // NONE or LINE
    return 0;
  p.x = dx / d, p.y = dy / d;
  return onSeg(a.s, a.e, p) && onSeg(b.s, b.e, p);
}
 
int inPolygon(Point p[], int n, Point q)
{
  int i, j, cnt = 0;
  for(i = 0, j = n - 1; i < n; j = i++) {
    if(p[i].y > q.y != p[j].y > q.y &&
       q.x < (p[j].x - p[i].x) * (q.y - p[i].y) / (p[j].y - p[i].y) + p[i].x)
      cnt++;
  }
  return cnt & 1;
}
 
double calcArea(Point p[], int n)
{
  if(n < 3) return 0.0;
  double ret = 0;
  int i;
  p[n] = p[0];
  for(i = 0; i < n; i++)
    ret += p[i].x * p[i + 1].y - p[i].y * p[i + 1].x;
  return fabs(ret) / 2;
}
 
int monotone(int n, Point p[], Point ch[])
{
  sort(p, p + n);
  int i, m = 0, t;
  for(i = 0; i < n; i++) {
    while(m >= 2 && cross(ch[m - 2], ch[m - 1], p[i]) <= 0)
      m--;
    ch[m++] = p[i];
  }
  for(i = n - 1, t = m + 1; i >= 0; i--) {
    while(m >= t && cross(ch[m - 2], ch[m - 1], p[i]) <= 0)
      m--;
    ch[m++] = p[i];
  }
  return m - 1;
}
 
#define INF 1e+30
 
double smallRect(int n, Point ch[])
{
  double lx, ly, rx, ry;
  int up, down, left, right;
  double ret = INF;
  lx = ly = INF;
  rx = ry = -INF;
 
  up = down = left = right = 0;
  for(int i = 0; i < n; i++) {
    if(ch[i].x > rx) rx = ch[i].x, right = i;
    if(ch[i].y > ry) ry = ch[i].y, up = i;
    if(ch[i].x < lx) lx = ch[i].x, left = i;
    if(ch[i].y < ly) ly = ch[i].y, down = i;
  }
 
  int corner[] = {up, down, left, right};
  Point vec[] = {Point(-1, 0), Point(1, 0), Point(0, -1), Point(0, 1)};
 
  ret = (rx - lx) * (ry - ly);
  for(int j = 0; j < 4; j++) {
    while(true) {
      Point a = ch[corner[j]], b = ch[(corner[j] + 1) % n], c = vec[j];
      if(fabs(cross2(b - a, c)) < eps)
        corner[j] = (corner[j] + 1) % n;
      else
        break;
    }
  }
  for(int i = 0; i < n; i++) {
    double mxVal = -INF, cos, sin;
    int mxIdx = 0;
    for(int j = 0; j < 4; j++) {
      Point a = ch[corner[j]], b = ch[(corner[j] + 1) % n], c = vec[j];
      double cosA = dot(b - a, c) / dist(b, a) / dist(c, Point(0, 0));
      if(mxVal < cosA)
        mxVal = cosA, mxIdx = j;
    }
    cos = mxVal, sin = sqrt(1 - cos * cos);
    for(int j = 0; j < 4; j++) {
      double tx, ty;
      tx = vec[j].x * cos - vec[j].y * sin;
      ty = vec[j].x * sin + vec[j].y * cos;
      vec[j] = Point(tx, ty);
    }
    for(int j = 0; j < 4; j++) {
      while(true) {
        Point a = ch[corner[j]], b = ch[(corner[j] + 1) % n], c = vec[j];
        if(fabs(cross2(b - a, c)) < eps)
          corner[j] = (corner[j] + 1) % n;
        else
          break;
      }
    }
    double w = distProjection(ch[corner[0]], ch[corner[0]] + vec[0], ch[corner[1]]);
    double h = distProjection(ch[corner[2]], ch[corner[2]] + vec[2], ch[corner[3]]);
    ret = min(ret, w * h);
  }
  return ret;
}
 
 
int xx[100001], yy[100001];
vector< Point > pp;
Point ch[400007], k[400007];
 
int main()
{
  int N;
  cin >> N;
  int vy[] = {0, 1, 0, -1}, vx[] = {1, 0, -1, 0};
  xx[0] = 0, yy[0] = 0;
  pp.push_back((Point) {0.0, 0.0});
  pp.push_back((Point) {1.0, 0.0});
  pp.push_back((Point) {0.0, 1.0});
  pp.push_back((Point) {1.0, 1.0});
 
  int tail = 0;
  for(int i = 1; i < N; i++) {
    int n, d;
    cin >> n >> d;
    double x = xx[n] + vx[d];
    double y = yy[n] + vy[d];
    xx[i] = x, yy[i] = y;
 
    pp.push_back((Point) {x, y});
    pp.push_back((Point) {x + 1, y});
    pp.push_back((Point) {x, y + 1});
    pp.push_back((Point) {x + 1, y + 1});
  }
  for(int i = 0; i < pp.size(); i++) {
    k[i] = pp[i];
  }
  int m = monotone(pp.size(), k, ch);
  double ret = smallRect(m, ch);
  printf("%.8lf\n", ret);
}

Measured memory_bytes: 24216