use std::io;
use std::str::FromStr;
use std::str::Chars;
use std::i32;
use std::u8;
use std::ascii::AsciiExt;
use std::collections::HashMap;
use std::collections::HashSet;
use std::collections::BTreeMap;
use std::collections::BTreeSet;
use std::collections::VecDeque;
use std::io::prelude::*;
use std::time::Duration;
use std::cmp;

macro_rules! println_stderr(
    ($($arg:tt)*) => { {
        let r = writeln!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

macro_rules! print_stderr(
    ($($arg:tt)*) => { {
        let r = write!(&mut ::std::io::stderr(), $($arg)*);
        r.expect("failed printing to stderr");
    } }
);

fn main() {
    let v = next_ints();
    let (a,b,c,d) = (v[0],v[1],v[2],v[3]);
    println!("{}",(a%d)*(b%d)%d*(c%d)%d);
}

#[allow(dead_code)]
fn next_string() -> String {
    let mut input = String::new();
    io::stdin().read_line(&mut input).unwrap();
    input
}

#[allow(dead_code)]
fn next_strings() -> Vec<String> {
    let input = next_string();
    input.split_whitespace().map(|x| x.parse().unwrap()).collect()
}

#[allow(dead_code)]
fn next_int() -> i64 {
    let input = next_string();
    i64::from_str(input.trim()).unwrap()
}

#[allow(dead_code)]
fn next_ints() -> Vec<i64> {
    let input = next_string();
    input.split_whitespace().map(|x| x.parse().unwrap()).collect()
}