//  [swift]
import Foundation

// MARK: READ INPUTS

func readInt() -> Int {
    Int(readLine()!)!
}

func readInts() -> [Int] {
    readLine()!.split(separator: " ").map { Int($0)! }
}

// MARK: DP

struct DP<Argument: Hashable, Element> {
    var dictionary = [Argument: Element]()
    
    var expression: (Argument, (Argument) -> Element) -> Element
    
    init(expression: @escaping (_ argument: Argument, _ note: (Argument) -> Element) -> Element) {
        self.expression = expression
    }
    
    subscript(_ argument: Argument) -> Element {
        mutating _read {
            if let note = dictionary[argument] {
                yield note
            } else {
                let result = expression(argument) { self[$0] }
                dictionary[argument] = result
                yield result
            }
        }
    }
}

// MARK: SOME EXTENSIONS

extension Dictionary {
    init(_ initialize: (inout Self) -> ()) {
        var dictionary = Self()
        initialize(&dictionary)
        self = dictionary
    }
}

extension SignedNumeric where Self: Comparable {
    var abs: Self {
        return self < .zero ? -self : self
    }
}

extension String {
    init(_ text: String, code: Int) {
        self = "\u{1b}[\(code)m" + text + "\u{1b}[0m"
    }
}

extension Collection {
    func tuple() -> (Element, Element) {
        var i = makeIterator()
        return (i.next()!, i.next()!)
    }
    func tuple() -> (Element, Element, Element) {
        var i = makeIterator()
        return (i.next()!, i.next()!, i.next()!)
    }
    func tuple() -> (Element, Element, Element, Element) {
        var i = makeIterator()
        return (i.next()!, i.next()!, i.next()!, i.next()!)
    }
    
    func safe(at index: Index) -> Element? {
        self.indices.contains(index) ? self[index] : nil
    }
}

// MARK: MOD

@propertyWrapper
struct Mod {
    
    let base: Int
    private var store: Int
    
    var value: Int {
        get { return store }
        set {
            store = newValue % base
            if store < 0 { store += base }
        }
    }
    
    static var defaultBaseNumber = 1_000_000_007
    
    init(_ value: Int, base: Int = defaultBaseNumber) {
        self.base = base
        self.store = value % base
        if store < 0 { self.store += base }
    }
    
    private init(unchecked value: Int, base: Int = defaultBaseNumber) {
        self.store = value
        self.base = base
    }
    
    init(wrappedValue: Int, base: Int = defaultBaseNumber) {
        self = .init(wrappedValue, base: base)
    }
    
    var wrappedValue: Int {
        get { return value }
        set { value = newValue }
    }
    
    var projectedValue: Int { base }
}

extension Mod: ExpressibleByIntegerLiteral {
    init(integerLiteral value: Int) {
        self = .init(value)
    }
}

extension Mod: AdditiveArithmetic, SignedNumeric {
    
    private static func assert(_ a: Mod, _ b: Mod) {
        Swift.assert(b.base == b.base, "Base should be same number .")
    }
    
    private static func operate(_ f: @escaping (Int, Int) -> Int) -> (Mod, Mod) -> Mod {
        return { lhs, rhs in
            assert(lhs, rhs)
            let num = f(lhs.value, rhs.value)
            return Mod(num, base: lhs.base)
        }
    }
    
    static func + (lhs: Mod, rhs: Mod) -> Mod { operate(+)(lhs, rhs) }
    static func - (lhs: Mod, rhs: Mod) -> Mod { operate(-)(lhs, rhs) }
    static func * (lhs: Mod, rhs: Mod) -> Mod { operate(*)(lhs, rhs) }
    static func *= (lhs: inout Mod, rhs: Mod) { lhs = lhs * rhs }
    
    init?<T>(exactly source: T) where T : BinaryInteger {
        guard let int = Int(exactly: source) else { return nil }
        self = Mod(int)
    }
    
    var magnitude: Int { value.abs }
}

extension Mod: CustomStringConvertible {
    var description: String {
        let digit = String(base).count
        let string = String(format: "%\(digit)d", value)
        return "Mod(\(string), base: \(base))"
    }
}

extension Mod: Equatable, Comparable {
    static func == (lhs: Mod, rhs: Mod) -> Bool {
        assert(lhs, rhs)
        return lhs.value == rhs.value
    }
    
    static func < (lhs: Mod, rhs: Mod) -> Bool {
        assert(lhs, rhs)
        return lhs.value < rhs.value
    }
}

extension Mod: Hashable {
    func hash(into hasher: inout Hasher) {
        hasher.combine(base)
        hasher.combine(value)
    }
}

extension Mod: Strideable {
    typealias Stride = Int
    
    func distance(to other: Mod) -> Int {
        return (other - self).value
    }
    
    func advanced(by n: Int) -> Mod {
        return self + Mod(n, base: base)
    }
}

// MARK: UNION FIND

struct UnionFind {
    var par: [Int]
    init(n: Int) {
        self.par = Array(0...n)
    }
    
    mutating func root(_ x: Int) -> Int {
        if par[x] == x { return x }
        par[x] = root(par[x])
        return par[x]
    }
    
    mutating func unite(_ x: Int, _ y: Int) {
        let rx = root(x), ry = root(y)
        if rx == ry { return }
        par[rx] = ry
    }
    
    mutating func same(_ x: Int, _ y: Int) -> Bool {
        let rx = root(x), ry = root(y)
        return rx == ry
    }
    
    mutating func size() -> Int {
        var dic = [Int: Int]()
        for i in par {
            dic[root(i), default: 0] += 1
        }
        return dic.values.max() ?? 0
    }
}

extension UnionFind: CustomStringConvertible {
    var description: String { "UnionFind(\(par))" }
}

// MARK: EUCLID
func euclid(_ x: Int, _ y: Int) -> Int {
    var x = x, y = y
    while y != 0 {
        (x, y) = (y, x%y)
    }
    return x
}

/// - Note: O(n)
func euclid(_ x: Int, _ y: Int, _ others: Int...) -> Int {
    var result = euclid(x, y)
    for i in others {
        result = euclid(result, i)
        if result == 1 { break }
    }
    return result
}

/// - Note: O(n)
func euclid(array: [Int]) -> Int {
    guard let first = array.first else { return 1 }
    var result = first
    for i in array {
        result = euclid(result, i)
        if result == 1 { break }
    }
    return result
}

// MARK: SIEVE of ERATOSTHENES
extension Int {
    /// - NOTE: O(n^2)
    func primeFactors() -> Set<Int> {
        guard self > 1 else { return [] }
        var x = self
        let primes = PrimeStore[x]
        
        // self.isPrime
        if primes.last ?? 0 == x { return [x] }
        
        var result = Set<Int>()
        for prime in primes {
            while x.isMultiple(of: prime) {
                result.insert(prime)
                x /= prime
            }
            if x == 1 { break }
        }
        return result
    }
    
    func isPrime() -> Bool {
        PrimeStore[self].last ?? 0 == self
    }
}

// MARK: PRIME
struct PrimeStore {
    private static var primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
    private static var searched = 100
    
    /// - NOTE: O(n^2)
    static subscript(_ x: Int) -> [Int] {
        if x <= searched {
            return primes.prefix(while: { $0 <= x })
        }
        
        var array = Array(searched...x)
        for prime in primes {
            array.removeAll(where: { $0.isMultiple(of: prime) })
        }
        while let prime = array.first {
            primes.append(prime)
            for i in array.indices where array[i].isMultiple(of: prime) {
                array.remove(at: i)
            }
            array.removeAll(where: { $0.isMultiple(of: prime) })
        }
        return primes
    }
}

// MARK: -- MAIN

func main() {
    let (a, b, c, d) = readInts().tuple()
    print(max(a*c, a*d, b*c, b*d))
}

func test(_ n: Int = 10) {
    func judge<T: Equatable>(_ answer: T, expected: T) {
        let success = "SUCCESS: \(answer)"
        let failed  = "FAILED:  \(answer) (expected \(expected))"
        print(answer == expected ? success : String(failed, code: 31))
    }
    
    
    print("\nborder ====================")
    
    
    print("\nrandom ====================")
    for _ in 0..<n {
//        let ans = problem_c(an)
//        let hev = heavy_problem_c(an)
//        printResult(ans, expected: hev)
    }
}

main()