use std::io::prelude::*;

fn input<T: std::str::FromStr>() -> T {
    let stdin = std::io::stdin();
    let token: String = stdin
        .lock()
        .bytes()
        .map(|c| c.unwrap() as char)
        .skip_while(|c| c.is_whitespace())
        .take_while(|c| !c.is_whitespace())
        .collect();
    token.parse().ok().unwrap()
}

fn main() {
    let l: i64 = input();
    let a: i64 = input();
    let b: i64 = input();
    let m: i64 = input();

    set_mod(m);

    let last = a + b * (l - 1);
    let mut ans = Modulo(0);
    for k in 1..19 {
        let kd = i64::pow(10, k);
        let l = kd / 10;
        let r = kd - 1;
        if last < l || r < a {
            continue;
        }

        let ka = std::cmp::max(a, a + (l - a + b - 1) / b * b);
        let klast = std::cmp::min(last, a + (r - a) / b * b);
        if klast < ka || ka < l || r < ka || klast < l || r < klast {
            continue;
        }

        let kl = (klast - ka) / b + 1;
        ans *= power(kd, kl);
        ans += f(kd, kl) * ka + g(kd, kl) * b;
    }

    println!("{}", ans);
}

fn power(x: i64, p: i64) -> Modulo {
    if p == 0 {
        Modulo(1)
    } else if p % 2 == 1 {
        power(x, p - 1) * x
    } else {
        let t = power(x, p / 2);
        t * t
    }
}

fn f(kd: i64, l: i64) -> Modulo {
    if l == 0 {
        Modulo(0)
    } else if l % 2 == 1 {
        let l = l - 1;
        f(kd, l) * kd + 1
    } else {
        let l = l / 2;
        let t = f(kd, l);
        t * power(kd, l) + t
    }
}

fn g(kd: i64, l: i64) -> Modulo {
    if l == 0 {
        Modulo(0)
    } else if l % 2 == 1 {
        let l = l - 1;
        g(kd, l) * kd + l
    } else {
        let l = l / 2;
        let t = g(kd, l);
        t * power(kd, l) + t + f(kd, l) * l
    }
}

type ModType = i64;
thread_local!(static MOD: std::cell::Cell<ModType> = Default::default());

fn get_mod() -> ModType {
    MOD.with(|m| m.get())
}

fn set_mod(x: ModType) {
    MOD.with(|m| m.set(x))
}

#[derive(Clone, Copy, Debug, Default, Eq, Hash, Ord, PartialEq, PartialOrd)]
struct Modulo(ModType);

impl std::fmt::Display for Modulo {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        self.0.fmt(f)
    }
}

impl std::ops::Add for Modulo {
    type Output = Modulo;
    fn add(self, other: Modulo) -> Modulo {
        let m = get_mod();
        let x = (self.0 % m + other.0 % m) % m;
        Modulo(x)
    }
}

impl<T: Into<ModType>> std::ops::Add<T> for Modulo {
    type Output = Modulo;
    fn add(self, other: T) -> Modulo {
        let m = get_mod();
        let x = (self.0 % m + other.into() % m) % m;
        Modulo(x)
    }
}

impl std::ops::AddAssign for Modulo {
    fn add_assign(&mut self, other: Modulo) {
        let m = get_mod();
        let x = (self.0 % m + other.0 % m) % m;
        self.0 = x;
    }
}

impl<T: Into<ModType>> std::ops::AddAssign<T> for Modulo {
    fn add_assign(&mut self, other: T) {
        let m = get_mod();
        let x = (self.0 % m + other.into() % m) % m;
        self.0 = x;
    }
}

impl std::ops::Mul for Modulo {
    type Output = Modulo;
    fn mul(self, other: Modulo) -> Modulo {
        let m = get_mod();
        let x = self.0 % m * (other.0 % m) % m;
        Modulo(x)
    }
}

impl<T: Into<ModType>> std::ops::Mul<T> for Modulo {
    type Output = Modulo;
    fn mul(self, other: T) -> Modulo {
        let m = get_mod();
        let x = self.0 % m * (other.into() % m) % m;
        Modulo(x)
    }
}

impl std::ops::MulAssign for Modulo {
    fn mul_assign(&mut self, other: Modulo) {
        let m = get_mod();
        let x = self.0 % m * (other.0 % m) % m;
        self.0 = x;
    }
}

impl<T: Into<ModType>> std::ops::MulAssign<T> for Modulo {
    fn mul_assign(&mut self, other: T) {
        let m = get_mod();
        let x = self.0 % m * (other.into() % m) % m;
        self.0 = x;
    }
}

impl std::ops::Sub for Modulo {
    type Output = Modulo;
    fn sub(self, other: Modulo) -> Modulo {
        let m = get_mod();
        let x = (self.0 % m + m - other.0 % m) % m;
        Modulo(x)
    }
}

impl<T: Into<ModType>> std::ops::Sub<T> for Modulo {
    type Output = Modulo;
    fn sub(self, other: T) -> Modulo {
        let m = get_mod();
        let x = (self.0 % m + m - other.into() % m) % m;
        Modulo(x)
    }
}

impl std::ops::SubAssign for Modulo {
    fn sub_assign(&mut self, other: Modulo) {
        let m = get_mod();
        let x = (self.0 % m + m - other.0 % m) % m;
        self.0 = x;
    }
}

impl<T: Into<ModType>> std::ops::SubAssign<T> for Modulo {
    fn sub_assign(&mut self, other: T) {
        let m = get_mod();
        let x = (self.0 % m + m - other.into() % m) % m;
        self.0 = x;
    }
}


Measured memory_bytes: 4352