Consider a house plan. 

Let the house be represented by an infinite horizontal strip defined by the inequality  - h ≤ y ≤ h. Strictly outside the house there are two light sources at the points (0, f) and (0, - f). Windows are located in the walls, the windows are represented by segments on the lines y = h and y = - h. Also, the windows are arranged symmetrically about the line y = 0.

Your task is to find the area of the floor at the home, which will be lighted by the sources of light. 

<image>

Input

The first line of the input file contains three integers n, h and f (1 ≤ n ≤ 500, 1 ≤ h ≤ 10, h < f ≤ 1000). Next, n lines contain two integers each li, ri ( - 5000 ≤ li < ri ≤ 5000), each entry indicates two segments. Endpoints of the first segment are (li, h)-(ri, h), and endpoints of the second segment are (li, - h)-(ri, - h). These segments describe location of windows. Numbers in the lines are space-separated. It is guaranteed that no two distinct segments have common points. 

Output

Print the single real number — the area of the illuminated part of the floor with an absolute or relative error of no more than 10 - 4.

Examples

Input

1 1 2
-1 1


Output

10.0000000000


Input

2 2 4
-1 0
1 2


Output

23.3333333333

Note

The second sample test is shown on the figure. Green area is the desired area of the illuminated part of the floor. Violet segments indicate windows.
#include <bits/stdc++.h>
using namespace std;
int n, h, f;
double DEG_to_RAD(double d) { return d * acos(-1.0) / 180.0; }
double RAD_to_DEG(double r) { return r * 180.0 / acos(-1.0); }
struct point {
  double x, y;
  point() { x = y = 0.0; }
  point(double _x, double _y) : x(_x), y(_y) {}
  bool operator<(point other) const {
    if (fabs(x - other.x) > 1e-9) return x < other.x;
    return y < other.y;
  }
  bool operator==(point other) const {
    return (fabs(x - other.x) < 1e-9 && (fabs(y - other.y) < 1e-9));
  }
};
struct vec {
  double x, y;
  vec(double _x, double _y) : x(_x), y(_y) {}
};
vec toVec(point a, point b) { return vec(b.x - a.x, b.y - a.y); }
double dist(point p1, point p2) { return hypot(p1.x - p2.x, p1.y - p2.y); }
double area(const vector<point> &P) {
  double result = 0.0, x1, y1, x2, y2;
  for (int i = 0; i < (int)P.size() - 1; i++) {
    x1 = P[i].x;
    x2 = P[i + 1].x;
    y1 = P[i].y;
    y2 = P[i + 1].y;
    result += (x1 * y2 - x2 * y1);
  }
  return fabs(result) / 2.0;
}
double dot(vec a, vec b) { return (a.x * b.x + a.y * b.y); }
double norm_sq(vec v) { return v.x * v.x + v.y * v.y; }
double angle(point a, point o, point b) {
  vec oa = toVec(o, a), ob = toVec(o, b);
  return acos(dot(oa, ob) / sqrt(norm_sq(oa) * norm_sq(ob)));
}
double cross(vec a, vec b) { return a.x * b.y - a.y * b.x; }
bool ccw(point p, point q, point r) {
  return cross(toVec(p, q), toVec(p, r)) > 0;
}
bool collinear(point p, point q, point r) {
  return fabs(cross(toVec(p, q), toVec(p, r))) < 1e-9;
}
bool isConvex(const vector<point> &P) {
  int sz = (int)P.size();
  if (sz <= 3) return false;
  bool isLeft = ccw(P[0], P[1], P[2]);
  for (int i = 1; i < sz - 1; i++)
    if (ccw(P[i], P[i + 1], P[(i + 2) == sz ? 1 : i + 2]) != isLeft)
      return false;
  return true;
}
bool inPolygon(point pt, const vector<point> &P) {
  if ((int)P.size() == 0) return false;
  double sum = 0;
  for (int i = 0; i < (int)P.size() - 1; i++) {
    if (ccw(pt, P[i], P[i + 1]))
      sum += angle(P[i], pt, P[i + 1]);
    else
      sum -= angle(P[i], pt, P[i + 1]);
  }
  return fabs(fabs(sum) - 2 * acos(-1.0)) < 1e-9;
}
point lineIntersectSeg(point p, point q, point A, point B) {
  double a = B.y - A.y;
  double b = A.x - B.x;
  double c = B.x * A.y - A.x * B.y;
  double u = fabs(a * p.x + b * p.y + c);
  double v = fabs(a * q.x + b * q.y + c);
  return point((p.x * v + q.x * u) / (u + v), (p.y * v + q.y * u) / (u + v));
}
vector<point> cutPolygon(point a, point b, const vector<point> &Q) {
  vector<point> P;
  for (int i = 0; i < (int)Q.size(); i++) {
    double left1 = cross(toVec(a, b), toVec(a, Q[i])), left2 = 0;
    if (i != (int)Q.size() - 1) left2 = cross(toVec(a, b), toVec(a, Q[i + 1]));
    if (left1 > -1e-9) P.push_back(Q[i]);
    if (left1 * left2 < -1e-9)
      P.push_back(lineIntersectSeg(Q[i], Q[i + 1], a, b));
  }
  if (!P.empty() && !(P.back() == P.front())) P.push_back(P.front());
  return P;
}
int x[] = {-1000000007, 1000000007};
point temp;
int main() {
  cin >> n >> h >> f;
  vector<point> ventanas;
  for (int i = 0; i < n; i++) {
    cin >> temp.x >> temp.y;
    if (temp.x < 0 && temp.y > 0) {
      ventanas.push_back(point(temp.x, 0));
      ventanas.push_back(point(0, temp.y));
    } else {
      ventanas.push_back(temp);
    }
  }
  vector<point> p_g;
  p_g.push_back(point(x[0], h));
  p_g.push_back(point(x[1], h));
  p_g.push_back(point(x[1], 0));
  p_g.push_back(point(x[0], 0));
  p_g.push_back(point(x[0], h));
  point a, b;
  vector<point> temp1;
  vector<point> temp2;
  vector<point> temp3;
  double areaTotal = 0;
  bool flag1 = false;
  bool flag2 = false;
  sort(ventanas.begin(), ventanas.end());
  bool rango = false;
  if (n > 2000) {
    while (true)
      ;
  }
  for (int i = 0; i < ventanas.size(); i++) {
    for (int j = 0; j < i; j++) {
      if (ventanas[j].x < ventanas[i].x && ventanas[j].y > ventanas[i].y)
        rango = true;
    }
    if (!rango) {
      if (ventanas[i].y <= 0) {
        temp1 = cutPolygon(point(0, f), point(ventanas[i].x, h), p_g);
        temp2 = cutPolygon(point(ventanas[i].y, h), point(0, f), temp1);
        temp1 = cutPolygon(point(ventanas[i].y, -h), point(0, -f), temp2);
        areaTotal += area(temp1);
        temp1 = cutPolygon(point(0, -f), point(ventanas[i].x, -h), temp2);
        areaTotal += area(temp1);
        temp1 = cutPolygon(point(ventanas[i].x, -h), point(0, -f), p_g);
        temp2 = cutPolygon(point(0, -f), point(ventanas[i].y, -h), temp1);
        if (i > 0) {
          for (int j = 0; j < i; j++) {
            if (j > 0) {
              temp1 =
                  cutPolygon(point(0, f), point(ventanas[j - 1].y, h), temp2);
              temp1 = cutPolygon(point(ventanas[j].x, h), point(0, f), temp1);
            } else {
              temp1 = cutPolygon(point(ventanas[j].x, h), point(0, f), temp2);
            }
            areaTotal += area(temp1);
          }
        }
        if (i > 0) {
          temp2 = cutPolygon(point(0, f), point(ventanas[i - 1].y, h), temp2);
        }
        temp1 = cutPolygon(point(ventanas[i].x, h), point(0, f), temp2);
        areaTotal += area(temp1);
        temp1 = cutPolygon(point(0, f), point(ventanas[i].x, h), temp2);
        areaTotal += area(temp1);
      } else {
        temp1 = cutPolygon(point(0, f), point(ventanas[i].x, h), p_g);
        temp2 = cutPolygon(point(ventanas[i].y, h), point(0, f), temp1);
        if (i > 0) {
          for (int j = i - 1; j >= 0; j--) {
            if (true) {
              temp3 =
                  cutPolygon(point(0, -f), point(ventanas[j + 1].x, -h), temp2);
              temp3 = cutPolygon(point(ventanas[j].y, -h), point(0, -f), temp3);
              if (j == 0) {
                temp1 =
                    cutPolygon(point(0, -f), point(ventanas[j].x, -h), temp2);
                areaTotal += area(temp1);
              }
            } else {
              ;
              temp3 = cutPolygon(point(0, -f), point(ventanas[j].x, -h), temp2);
            }
            areaTotal += area(temp3);
          }
        }
        if (i > 0) {
          temp2 = cutPolygon(point(ventanas[i - 1].y, -h), point(0, -f), temp2);
        } else {
          temp1 = cutPolygon(point(0, -f), point(ventanas[i].x, -h), temp2);
          areaTotal += area(temp1);
        }
        temp1 = cutPolygon(point(ventanas[i].x, -h), point(0, -f), temp2);
        areaTotal += area(temp1);
        temp1 = cutPolygon(point(ventanas[i].x, -h), point(0, -f), p_g);
        temp2 = cutPolygon(point(0, -f), point(ventanas[i].y, -h), temp1);
        temp1 = cutPolygon(point(0, f), point(ventanas[i].y, h), temp2);
        areaTotal += area(temp1);
        if (i > 0) {
          temp2 = cutPolygon(point(0, f), point(ventanas[i - 1].y, h), temp2);
        }
        temp1 = cutPolygon(point(ventanas[i].x, h), point(0, f), temp2);
        areaTotal += area(temp1);
      }
    }
    rango = false;
  }
  cout << fixed << setprecision(6) << (areaTotal * 2.0000) << endl;
  return 0;
}
