macro_rules !read_value {($iter :expr ,($($t :tt ) ,*) ) =>{($(read_value !($iter ,$t ) ) ,*) } ;($iter :expr ,[$t :tt ;$len :expr ] ) =>{(0 ..$len ) .map (|_ |read_value !($iter ,$t ) ) .collect ::<Vec <_ >>() } ;($iter :expr ,{chars :$base :expr } ) =>{read_value !($iter ,String ) .chars () .map (|c |(c as u8 -$base as u8 ) as usize ) .collect ::<Vec <usize >>() } ;($iter :expr ,{char :$base :expr } ) =>{read_value !($iter ,{chars :$base } ) [0 ] } ;($iter :expr ,chars ) =>{read_value !($iter ,String ) .chars () .collect ::<Vec <char >>() } ;($iter :expr ,char ) =>{read_value !($iter ,chars ) [0 ] } ;($iter :expr ,usize1 ) =>{read_value !($iter ,usize ) -1 } ;($iter :expr ,$t :ty ) =>{$iter .next () .unwrap () .parse ::<$t >() .unwrap () } ;}
macro_rules !input_inner {($iter :expr ) =>{} ;($iter :expr ,) =>{} ;($iter :expr ,mut $var :ident :$t :tt $($r :tt ) *) =>{let mut $var =read_value !($iter ,$t ) ;input_inner !{$iter $($r ) *} } ;($iter :expr ,mut $var :ident $($r :tt ) *) =>{input_inner !{$iter ,mut $var :usize $($r ) *} } ;($iter :expr ,$var :ident :$t :tt $($r :tt ) *) =>{let $var =read_value !($iter ,$t ) ;input_inner !{$iter $($r ) *} } ;($iter :expr ,$var :ident $($r :tt ) *) =>{input_inner !{$iter ,$var :usize $($r ) *} } ;}
macro_rules !input {(source =$s :expr ,$($r :tt ) *) =>{let mut iter =$s .split_whitespace () ;input_inner !{iter ,$($r ) *} } ;(iter =$iter :ident ,$($r :tt ) *) =>{let s ={use std ::io ::Read ;let mut s =String ::new () ;std ::io ::stdin () .read_to_string (&mut s ) .unwrap () ;s } ;let mut $iter =s .split_whitespace () ;input_inner !{$iter ,$($r ) *} } ;($($r :tt ) *) =>{let s ={use std ::io ::Read ;let mut s =String ::new () ;std ::io ::stdin () .read_to_string (&mut s ) .unwrap () ;s } ;let mut iter =s .split_whitespace () ;input_inner !{iter ,$($r ) *} } ;}
pub trait Magma {
    type T: Clone + PartialEq;
    fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T;
}
pub trait Associative {}
pub trait SemiGroup: Magma + Associative {}
pub trait Unital: Magma {
    fn unit(&self) -> Self::T;
}
pub trait Monoid: SemiGroup + Unital {
    fn power(&self, x: Self::T, n: usize) -> Self::T {
        let mut n = n;
        let mut res = self.unit();
        let mut base = x;
        while n > 0 {
            if n & 1 == 1 {
                res = self.operate(&res, &base);
            }
            base = self.operate(&base, &base);
            n = n >> 1;
        }
        res
    }
}
pub trait Invertible: Magma {
    fn inverse(&self, x: &Self::T) -> Self::T;
}
pub trait Group: Monoid + Invertible {}
pub trait Commutative {}
pub trait AbelianMonoid: Monoid + Commutative {}
pub trait AbelianGroup: Group + Commutative {}
pub trait Idempotent {}
pub trait IdempotentMonoid: Monoid + Idempotent {}
#[derive(Clone, Debug)]
pub struct MinOperation<T: Clone + Ord> {
    maximum: T,
}
pub mod min_operation_impl {
    use super::*;
    impl<T: Clone + Ord> MinOperation<T> {
        pub fn new(maximum: T) -> Self {
            MinOperation { maximum: maximum }
        }
    }
    impl<T: Clone + Ord> Magma for MinOperation<T> {
        type T = T;
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            std::cmp::min(x, y).clone()
        }
    }
    impl<T: Clone + Ord> Unital for MinOperation<T> {
        #[inline]
        fn unit(&self) -> Self::T {
            self.maximum.clone()
        }
    }
    impl<T: Clone + Ord> Associative for MinOperation<T> {}
    impl<T: Clone + Ord> SemiGroup for MinOperation<T> {}
    impl<T: Clone + Ord> Monoid for MinOperation<T> {}
    impl<T: Clone + Ord> Commutative for MinOperation<T> {}
    impl<T: Clone + Ord> AbelianMonoid for MinOperation<T> {}
    impl<T: Clone + Ord> Idempotent for MinOperation<T> {}
    impl<T: Clone + Ord> IdempotentMonoid for MinOperation<T> {}
}
#[derive(Clone, Debug)]
pub struct MaxOperation<T: Clone + Ord> {
    minimum: T,
}
pub mod max_operation_impl {
    use super::*;
    impl<T: Clone + Ord> MaxOperation<T> {
        pub fn new(minimum: T) -> Self {
            MaxOperation { minimum: minimum }
        }
    }
    impl<T: Clone + Ord> Magma for MaxOperation<T> {
        type T = T;
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            std::cmp::max(x, y).clone()
        }
    }
    impl<T: Clone + Ord> Unital for MaxOperation<T> {
        #[inline]
        fn unit(&self) -> Self::T {
            self.minimum.clone()
        }
    }
    impl<T: Clone + Ord> Associative for MaxOperation<T> {}
    impl<T: Clone + Ord> SemiGroup for MaxOperation<T> {}
    impl<T: Clone + Ord> Monoid for MaxOperation<T> {}
    impl<T: Clone + Ord> Commutative for MaxOperation<T> {}
    impl<T: Clone + Ord> AbelianMonoid for MaxOperation<T> {}
    impl<T: Clone + Ord> Idempotent for MaxOperation<T> {}
    impl<T: Clone + Ord> IdempotentMonoid for MaxOperation<T> {}
}
#[derive(Clone, Debug)]
pub struct CartesianOperation<M1, M2> {
    m1: M1,
    m2: M2,
}
pub mod cartesian_operation_impl {
    use super::*;
    impl<M1, M2> CartesianOperation<M1, M2> {
        pub fn new(m1: M1, m2: M2) -> Self {
            CartesianOperation { m1: m1, m2: m2 }
        }
    }
    impl<M1: Magma, M2: Magma> Magma for CartesianOperation<M1, M2> {
        type T = (M1::T, M2::T);
        #[inline]
        fn operate(&self, x: &Self::T, y: &Self::T) -> Self::T {
            (self.m1.operate(&x.0, &y.0), self.m2.operate(&x.1, &y.1))
        }
    }
    impl<M1: Unital, M2: Unital> Unital for CartesianOperation<M1, M2> {
        #[inline]
        fn unit(&self) -> Self::T {
            (self.m1.unit(), self.m2.unit())
        }
    }
    impl<M1: Associative, M2: Associative> Associative for CartesianOperation<M1, M2> {}
    impl<M1: SemiGroup, M2: SemiGroup> SemiGroup for CartesianOperation<M1, M2> {}
    impl<M1: Monoid, M2: Monoid> Monoid for CartesianOperation<M1, M2> {}
    impl<M1: Commutative, M2: Commutative> Commutative for CartesianOperation<M1, M2> {}
    impl<M1: AbelianMonoid, M2: AbelianMonoid> AbelianMonoid for CartesianOperation<M1, M2> {}
    impl<M1: Invertible, M2: Invertible> Invertible for CartesianOperation<M1, M2> {
        #[inline]
        fn inverse(&self, x: &Self::T) -> Self::T {
            (self.m1.inverse(&x.0), self.m2.inverse(&x.1))
        }
    }
    impl<M1: Group, M2: Group> Group for CartesianOperation<M1, M2> {}
    impl<M1: AbelianGroup, M2: AbelianGroup> AbelianGroup for CartesianOperation<M1, M2> {}
}
#[derive(Clone, Debug)]
pub struct QueueAggregation<M: Monoid> {
    front_stack: Vec<(M::T, M::T)>,
    back_stack: Vec<(M::T, M::T)>,
    monoid: M,
}
impl<M: Monoid> QueueAggregation<M> {
    pub fn new(monoid: M) -> Self {
        QueueAggregation {
            front_stack: Vec::new(),
            back_stack: Vec::new(),
            monoid: monoid,
        }
    }
    #[inline]
    pub fn len(&self) -> usize {
        self.front_stack.len() + self.back_stack.len()
    }
    #[inline]
    pub fn is_empty(&self) -> bool {
        self.front_stack.is_empty() && self.back_stack.is_empty()
    }
    #[inline]
    pub fn fold_all(&self) -> M::T {
        self.monoid.operate(
            self.front_stack
                .last()
                .map(|t| &t.0)
                .unwrap_or(&self.monoid.unit()),
            self.back_stack
                .last()
                .map(|t| &t.0)
                .unwrap_or(&self.monoid.unit()),
        )
    }
    #[inline]
    pub fn last(&self) -> Option<&M::T> {
        self.back_stack
            .last()
            .or(self.front_stack.first())
            .map(|t| &t.1)
    }
    #[inline]
    pub fn push(&mut self, value: M::T) {
        let x = self.monoid.operate(
            self.back_stack
                .last()
                .map(|t| &t.0)
                .unwrap_or(&self.monoid.unit()),
            &value,
        );
        self.back_stack.push((x, value));
    }
    #[inline]
    fn push_front(&mut self, value: M::T) {
        let x = self.monoid.operate(
            &value,
            self.front_stack
                .last()
                .map(|t| &t.0)
                .unwrap_or(&self.monoid.unit()),
        );
        self.front_stack.push((x, value));
    }
    #[inline]
    pub fn pop(&mut self) -> Option<M::T> {
        if self.front_stack.is_empty() {
            let v = self
                .back_stack
                .drain(..)
                .map(|t| t.1)
                .rev()
                .collect::<Vec<_>>();
            for x in v.into_iter() {
                self.push_front(x)
            }
        }
        self.front_stack.pop().map(|t| t.1)
    }
}
use std::cmp::{max, min};
fn main() {
    input! { n, xy: [(i64, i64); n] };
    let mut ans = 0i64;
    let ab = xy
        .iter()
        .map(|&(x, y)| (min(x, y), max(x, y)))
        .collect::<Vec<_>>();
    if n > 1 {
        ans = std::i64::MAX;
        let (mut mx, mut mn) = ((0, 0), (1_000_000_001, n));
        for i in 0..n {
            mx = max(mx, (ab[i].1, i));
            mn = min(mn, (ab[i].0, i));
        }
        if mx.1 != mn.1 {
            let mut seg = (min(ab[mx.1].0, ab[mn.1].1), max(ab[mx.1].0, ab[mn.1].1));
            let mut idx = (0..n)
                .filter(|&i| i != mx.1 && i != mn.1)
                .collect::<Vec<_>>();
            idx.sort_by_key(|&i| ab[i].0);
            let mut que = QueueAggregation::new(CartesianOperation::new(
                MinOperation::new(1_000_000_001),
                MaxOperation::new(0),
            ));
            if idx.len() > 0 {
                for &i in idx.iter() {
                    que.push((ab[i].0, ab[i].0));
                }
                for &i in idx.iter() {
                    let (mi, ma) = que.fold_all();
                    ans = min(ans, (max(seg.1, ma) - min(seg.0, mi)) * (mx.0 - mn.0));
                    que.pop();
                    seg.0 = min(seg.0, ab[i].1);
                    seg.1 = max(seg.1, ab[i].1);
                }
            }
            ans = min(ans, (seg.1 - seg.0) * (mx.0 - mn.0));
        }
        let mut seg = (ab[mx.1].0, ab[mn.1].1);
        for i in 0..n {
            seg.0 = max(seg.0, ab[i].0);
            seg.1 = min(seg.1, ab[i].1);
        }
        ans = min(ans, (mx.0 - seg.1) * (seg.0 - mn.0));
    }
    println!("{}", ans);
}


Measured memory_bytes: 42728