#include <bits/stdc++.h>
using namespace std;
const long double PI = acos(-1);
const long long INF = 1e18;
long double vol(long double r, long double h) { return PI * r * r * h; }
struct node {
  long long mx;
  int l, r;
  node *left, *right;
  node(int l, int r) : l(l), r(r) {
    mx = -INF;
    if (l < r) {
      int m = (l + r) / 2;
      left = new node(l, m);
      right = new node(m + 1, r);
    }
  }
  void upd(int pos, long double val) {
    if (r < pos || pos < l) return;
    if (l == r) {
      mx = val;
      return;
    }
    left->upd(pos, val);
    right->upd(pos, val);
    mx = max(left->mx, right->mx);
  }
  long long qry(int rl, int rr) {
    if (r < rl || rr < l) return -INF;
    if (rl <= l && r <= rr) return mx;
    return max(left->qry(rl, rr), right->qry(rl, rr));
  }
};
map<long long, int> wt;
const int MAXN = 1e5 + 5;
long long dp[MAXN];
int main() {
  int n;
  cin >> n;
  vector<long long> v(n);
  vector<pair<long long, int>> o;
  for (int i = 0; i < n; i++) {
    long long r, h;
    cin >> r >> h;
    v[i] = r * r * h;
    o.emplace_back(v[i], i);
  }
  node tree(1, n);
  sort(o.begin(), o.end());
  int pt = 1;
  for (int i = 0; i < n; i++) {
    if (i > 0 && o[i].first != o[i - 1].first) pt++;
    wt[o[i].second] = pt;
  }
  for (int i = 0; i < n; i++) {
    int w = wt[i];
    dp[i] = v[i];
    if (i > 0) dp[i] = max(dp[i], v[i] + tree.qry(1, w - 1));
    tree.upd(w, dp[i]);
  }
  long long ans = 0;
  for (int i = 0; i < n; i++) ans = max(ans, dp[i]);
  cout << fixed << setprecision(15) << PI * (long double)ans << endl;
}
