#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
const double eps = 1e-6;
void add(long long &x, long long y) { x += y, x %= MOD; }
struct Tree {
  int l, r;
  double Max;
};
Tree tree[MAXN << 2];
void PushUp(int o) {
  tree[o].Max = max(tree[o << 1].Max, tree[o << 1 | 1].Max);
}
void Build(int o, int l, int r) {
  tree[o].l = l;
  tree[o].r = r;
  tree[o].Max = 0;
  if (l == r) return;
  int mid = (l + r) >> 1;
  Build(o << 1, l, mid);
  Build(o << 1 | 1, mid + 1, r);
}
void Update(int o, int pos, double val) {
  if (tree[o].l == tree[o].r) {
    tree[o].Max = val;
    return;
  }
  int mid = (tree[o].l + tree[o].r) >> 1;
  if (pos <= mid)
    Update(o << 1, pos, val);
  else
    Update(o << 1 | 1, pos, val);
  PushUp(o);
}
double Query(int o, int L, int R) {
  if (tree[o].l == L && R == tree[o].r) return tree[o].Max;
  int mid = (tree[o].l + tree[o].r) >> 1;
  if (R <= mid)
    return Query(o << 1, L, R);
  else if (L > mid)
    return Query(o << 1 | 1, L, R);
  else
    return max(Query(o << 1, L, mid), Query(o << 1 | 1, mid + 1, R));
}
double val[MAXN], rec[MAXN];
int main() {
  int n;
  cin >> n;
  for (int i = 0; i < n; i++) {
    double r, h;
    cin >> r >> h;
    val[i] = rec[i + 1] = acos(-1.0) * r * r * h;
  }
  sort(rec + 1, rec + n + 1);
  int top = unique(rec + 1, rec + n + 1) - rec;
  double ans = 0;
  Build(1, 0, n);
  for (int i = 0; i < n; i++) {
    int pos = lower_bound(rec, rec + top, val[i]) - rec;
    double res = Query(1, 0, pos - 1) + val[i];
    Update(1, pos, res);
    ans = max(ans, res);
  }
  printf("%.12lf\n", ans);
  return 0;
}
