use std::io::{stdin, Read};
use std::str::FromStr;
use std::{cmp, mem, process};
use std::collections::{HashSet, BTreeMap, BTreeSet};


fn main() {
    let n = read::<usize>();
    let mut q = vec![(0, 0); n];

    let mut s = BTreeMap::<usize, BTreeSet<usize>>::new();
    let mut max_element = 0;
    let mut min_element = 10000000000;
    for i in 0..n {
        let mut x = read::<usize>();
        let mut y = read::<usize>();
        if x > y {
            mem::swap(&mut x, &mut y);
        }
        q[i] = (x, y);
        for j in &[x, y] {
            if max_element < *j || min_element > *j {
                let hoge = s.entry(*j).or_insert(BTreeSet::<usize>::new());
                hoge.insert(i);
            }
            max_element = cmp::max(max_element, *j);
            min_element = cmp::min(min_element, *j);
        }
        //println!("{:?}", &s);
    }
    q.sort();
    if s.get(&max_element).unwrap().len() == 1 && s.get(&min_element).unwrap().len() == 1 {
        if s.get(&max_element).unwrap() == s.get(&min_element).unwrap() {
            // 別々のみ
            let mut r_min = max_element;
            let mut b_max = min_element;
            for i in &q {
                let (l, r) = *i;
                r_min = cmp::min(r, r_min);
                b_max = cmp::max(l, b_max);
            }
            //println!("{}", (max_element - r_min) * (b_max - min_element));
            process::exit(0);
        }
    }
    let mut r_min = max_element;
    let mut b_max = min_element;
    for i in &q {
        let (l, r) = *i;
        r_min = cmp::min(r, r_min);
        b_max = cmp::max(l, b_max);
    }
    let mut ans = (max_element - r_min) * (b_max - min_element);
    let temp = max_element - min_element;
    max_element = q[n - 1].0;
    min_element = q[0].0;
    ans = cmp::min(temp * (max_element - min_element), ans);

    let mut sets1 = BTreeSet::new();
    let mut sets2 = BTreeSet::new();

    for i in 0..n {
        sets1.insert((q[i].0, i));
        sets2.insert((-(q[i].0 as i64), i));

    }
    q.push((10000000, 0));
    for i in 0..n {
        sets1.remove(&(q[i].0, i));
        sets1.insert((q[i].1, i));

        sets2.remove(&(-(q[i].0 as i64), i));
        sets2.insert((-(q[i].1 as i64), i));

        min_element = (*sets1.iter().next().unwrap()).0;
        max_element = -(*sets2.iter().next().unwrap()).0 as usize;
        ans = cmp::min(temp * (max_element - min_element), ans);
        //println!("{}", ans);
    }
    println!("{}", ans);
}


#[allow(dead_code)]
fn read_vec<T: FromStr>(n: usize) -> Vec<T> {
    let mut v = vec![];
    for i in 0..n {
        let a = read::<T>();
        v.push(a);
    }
    v
}
#[allow(dead_code)]
fn read_str() -> Vec<char> {
    let s: String = read();
    s.chars().collect::<Vec<char>>()
}
#[allow(dead_code)]
fn read<T: FromStr>() -> T {
    let stdin = stdin();
    let stdin = stdin.lock();
    let s = stdin
        .bytes()
        .map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect::<String>();
    s.parse::<T>().unwrap_or_else(
        |_| panic!("Faild to parse {}", s),
    )
}


Measured memory_bytes: 28924