#include <bits/stdc++.h>
using namespace std;
long long query(vector<long long> &tree, int l, int r, int start, int end,
                int node) {
  if (l > end || r < start) return 0;
  if (start >= l && end <= r) return tree[node];
  int mid = (start + end) / 2;
  return max(query(tree, l, r, start, mid, 2 * node),
             query(tree, l, r, mid + 1, end, 2 * node + 1));
}
void update(vector<long long> &tree, long long val, int idx, int start, int end,
            int node) {
  if (start == end) {
    tree[node] = val;
    return;
  }
  int mid = (start + end) / 2;
  if (idx >= start && idx <= mid)
    update(tree, val, idx, start, mid, 2 * node);
  else
    update(tree, val, idx, mid + 1, end, 2 * node + 1);
  tree[node] = max(tree[2 * node], tree[2 * node + 1]);
}
bool cmp(pair<long long, int> p1, pair<long long, int> p2) {
  if (p1.first < p2.first) return true;
  if (p1.first == p2.first && p1.second > p2.second) return true;
  return false;
}
int main() {
  int n, i;
  long long r, h, q, val;
  cin >> n;
  vector<pair<long long, int> > v(n);
  vector<int> idx(n);
  for (i = 0; i < n; i++) {
    cin >> r >> h;
    v[i] = make_pair(r * r * h, i);
  }
  sort(v.begin(), v.end(), cmp);
  for (i = 0; i < n; i++) idx[v[i].second] = i;
  vector<long long> tree(4 * n);
  update(tree, v[idx[n - 1]].first, idx[n - 1] + 1, 1, n, 1);
  for (i = n - 2; i >= 0; i--) {
    q = query(tree, idx[i] + 2, n, 1, n, 1);
    val = q + v[idx[i]].first;
    update(tree, val, idx[i] + 1, 1, n, 1);
  }
  printf("%.15lf", (double)tree[1] * acos(-1));
}
