#include <bits/stdc++.h>
using namespace std;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 1e9 + 7;
long long sum[maxn << 2];
struct node {
  int r, h, id;
  long long v;
  bool operator<(const node &a) const { return v < a.v; }
} e[maxn];
long long t[maxn];
int n;
void push_up(int rt) { sum[rt] = max(sum[rt << 1], sum[rt << 1 | 1]); }
void update(int pos, long long val, int l, int r, int rt) {
  if (l == r) {
    sum[rt] = max(val, sum[rt]);
    return;
  }
  int mid = (l + r) / 2;
  if (pos <= mid)
    update(pos, val, l, mid, rt << 1);
  else
    update(pos, val, mid + 1, r, (rt << 1) + 1);
  push_up(rt);
}
long long query(int L, int R, int l, int r, int rt) {
  if (L <= l && R >= r) {
    return sum[rt];
  }
  long long ans = 0;
  int mid = (l + r) / 2;
  if (L <= mid) ans = max(ans, query(L, R, l, mid, rt << 1));
  if (R > mid) ans = max(ans, query(L, R, mid + 1, r, (rt << 1) + 1));
  return ans;
}
long long dp[maxn];
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d%d", &e[i].r, &e[i].h);
    e[i].v = 1LL * e[i].r * e[i].r * e[i].h;
    t[i] = e[i].v;
  }
  sort(t + 1, t + 1 + n);
  long long ans = 0;
  for (int i = 1; i <= n; i++) {
    int pos = lower_bound(t + 1, t + 1 + n, e[i].v) - t;
    if (pos == 1)
      dp[i] = e[i].v;
    else
      dp[i] = query(1, pos - 1, 1, n, 1) + e[i].v;
    update(pos, dp[i], 1, n, 1);
    ans = max(ans, dp[i]);
  }
  printf("%f\n", 1.0 * ans * acos(-1));
  return 0;
}
