define_runtime_modint!(MInt; Modulus with MOD: i32);

use num::One;

fn main() {
	let mut s = String::new();
	use std::io::Read;
	std::io::stdin().read_to_string(&mut s).unwrap();
	let mut s = s.split_whitespace();
	let l: i64 = s.next().unwrap().parse().unwrap();
	let a: i64 = s.next().unwrap().parse().unwrap();
	let b: i64 = s.next().unwrap().parse().unwrap();
	let m: i32 = s.next().unwrap().parse().unwrap();
	let ans = Modulus::with(m, || {
		let mut matrix = SquareMatrix::identity(3);
		let mut l = l;
		let mut cur = a;
		while l > 0 {
			let tenp = next_power_of_ten(cur);
			let cnt = (tenp - 1 - cur) / b + 1;
			let exp = std::cmp::min(l, cnt);
			cur += cnt * b;
			let mut mat = SquareMatrix::new(3);
			mat[(0, 0)] = MInt::from(tenp);
			mat[(0, 1)] = MInt::one();
			mat[(1, 1)] = MInt::one();
			mat[(1, 2)] = MInt::from(b);
			mat[(2, 2)] = MInt::one();
			matrix = SquareMatrix::pow(mat, exp as u64) * matrix;
			l -= cnt;
		}
		matrix[(0, 1)] * MInt::from(a) + matrix[(0, 2)]
	});
	println!("{}", ans);
}

pub fn prev_power_of_ten(n: i64) -> i64 {
	let mut r = 1;
	let mut n = n;
	while {
		n /= 10;
		n > 0
	} {
		r *= 10;
	}
	r
}

pub fn next_power_of_ten(n: i64) -> i64 {
	prev_power_of_ten(n) * 10
}

#[derive(Clone)]
pub struct SquareMatrix<T> {
	elem: Vec<T>,
	size: usize,
}

impl<T> SquareMatrix<T>
where
	T: Clone,
{
	pub fn new(size: usize) -> Self
	where
		T: Default,
	{
		Self {
			size,
			elem: vec![T::default(); size * size],
		}
	}

	pub fn size(&self) -> usize {
		self.size
	}

	pub fn zeros(size: usize) -> Self
	where
		T: num::Zero,
	{
		Self {
			size,
			elem: vec![T::zero(); size * size],
		}
	}

	pub fn identity(size: usize) -> Self
	where
		T: num::Zero + num::One,
	{
		let mut elem = vec![T::zero(); size * size];
		for i in (0..size * size).step_by(size + 1) {
			elem[i] = T::one();
		}
		Self { size, elem }
	}

	pub fn get(&self, i: usize, j: usize) -> Option<&T> {
		if i < self.size && j < self.size() {
			unsafe { Some(self.elem.get_unchecked(i * self.size() + j)) }
		} else {
			None
		}
	}

	pub fn get_mut(&mut self, i: usize, j: usize) -> Option<&mut T> {
		if i < self.size && j < self.size() {
			unsafe {
				let size = self.size();
				Some(self.elem.get_unchecked_mut(i * size + j))
			}
		} else {
			None
		}
	}

	pub unsafe fn get_unchecked(&self, i: usize, j: usize) -> &T {
		self.elem.get_unchecked(i * self.size() + j)
	}

	pub unsafe fn get_unchecked_mut(&mut self, i: usize, j: usize) -> &mut T {
		let size = self.size();
		self.elem.get_unchecked_mut(i * size + j)
	}

	pub fn pow<U>(matrix: Self, exp: U) -> Self
	where
		T: num::Zero + num::One + std::ops::Add<Output = T> + std::ops::Mul<Output = T>,
		U: num::Unsigned + num::Integer,
	{
		let mut mat = matrix;
		let mut n = exp;
		let mut r = Self::identity(mat.size());
		while n > U::zero() {
			if n.is_odd() {
				r = r * &mat;
			}
			mat = &mat * &mat;
			n = n / (U::one() + U::one());
		}
		r
	}
}

impl<T> std::ops::Index<(usize, usize)> for SquareMatrix<T> {
	type Output = T;
	fn index(&self, index: (usize, usize)) -> &Self::Output {
		assert!(index.0 < self.size && index.1 < self.size);
		unsafe { self.elem.get_unchecked(index.0 * self.size + index.1) }
	}
}

impl<T> std::ops::IndexMut<(usize, usize)> for SquareMatrix<T> {
	fn index_mut(&mut self, index: (usize, usize)) -> &mut Self::Output {
		assert!(index.0 < self.size && index.1 < self.size);
		unsafe { self.elem.get_unchecked_mut(index.0 * self.size + index.1) }
	}
}

macro_rules! impl_ {
	($trait:ident:$fn:ident for $type:ty) => {
		impl_!($type; $trait:$fn);
		impl_!($type; $trait<&>:$fn);
		impl_!($type; <&> $trait:$fn);
		impl_!($type; <&> $trait<&>:$fn);
	};

	($type:ty; $(<$ref_self:tt>)? Mul$(<$($ref_rhs:tt)?>)?:$fn:ident) => {
		impl<T> std::ops::Mul<$($($ref_rhs)?)?$type> for $($ref_self)? $type
		where
			T: Clone + num::Zero + std::ops::Add<Output = T> + std::ops::Mul<Output = T>,
		{
			type Output = $type;
			fn $fn(self, rhs: $($($ref_rhs)?)?$type) -> Self::Output {
				assert_eq!(self.size(), rhs.size());

				let mut r = <$type>::zeros(self.size());

				for i in 0..self.size() {
					for k in 0..rhs.size() {
						for j in 0..rhs.size() {
							unsafe {
								*r.get_unchecked_mut(i, j) = r.get_unchecked(i, j).clone() + self.get_unchecked(i, k).clone() * rhs.get_unchecked(k, j).clone();
							}
						}
					}
				}
				r
			}
		}
	};
}

impl_!(Mul:mul for SquareMatrix<T>);

pub mod traits {
	pub mod consts {
		pub trait Constant: super::marker::Unsafe {
			type Type;
			fn value() -> Self::Type;
		}
	}
	pub mod marker {
		pub unsafe trait Unsafe {}
	}

	pub mod integer {
		pub trait SizeOrder<T> {
			type LargerType;
			type SmallerType;
		}

		pub trait IntoLarger {
			type LargerType;
		}

		macro_rules! impl_ {
			($i0:ty:$u0:ty, $($is:ty:$us:ty),+) => {
				impl_![imp $i0:$u0];
				impl_![imp $i0];
				impl_![imp $u0];
				$(impl_![imp $i0:$u0, $is:$us];)+
				impl_![$($is:$us),+];
			};

			($i:ty:$u:ty) => {
				impl_![imp $i:$u];
				impl_![imp $i];
				impl_![imp $u];
			};

			(imp $t:ty) => {
				impl_![imp $t | $t, $t:$t];
			};

			(imp $i:ty:$u:ty) => {
				impl_![imp $u | $i, $u:$i];
				impl_![imp $i | $u, $u:$i];
			};

			(imp $i0:ty:$u0:ty, $i1:ty:$u1:ty) => {
				impl_![imp $i1 | $i0, $i1:$i0];
				impl_![imp $u1 | $u0, $u1:$u0];
				impl_![imp $i1 | $u0, $i1:$u0];
				impl_![imp $u1 | $i0, $u1:$i0];
				impl_![imp $i0 | $i1, $i1:$i0];
				impl_![imp $u0 | $u1, $u1:$u0];
				impl_![imp $u0 | $i1, $i1:$u0];
				impl_![imp $i0 | $u1, $u1:$i0];
			};

			(imp $target:ty | $self:ty, $large:ty:$small:ty) => {
				impl SizeOrder<$target> for $self {
					type LargerType = $large;
					type SmallerType = $small;
				}
			};

			(lt ptr; $($is:ty:$us:ty),+) => {
				$(impl_![imp $is:$us, isize:usize];)+
			};
			(eq ptr; $($is:ty:$us:ty),+) => {
				impl_![isize:usize];
				$(
					impl_![imp $is | isize, $is:isize];
					impl_![imp $us | isize, $us:isize];
					impl_![imp $is | usize, usize:$is];
					impl_![imp $us | usize, $us:usize];
					impl_![imp isize | $is, $is:isize];
					impl_![imp isize | $us, $us:isize];
					impl_![imp usize | $is, usize:$is];
					impl_![imp usize | $us, $us:usize];
				)+
			};
			(gt ptr; $($is:ty:$us:ty),+) => {
				$(impl_![imp isize:usize, $is:$us];)+
			};
		}

		impl_![i8: u8, i16: u16, i32: u32, i64: u64, i128: u128];
		#[cfg(target_pointer_width = "32")]
		mod size_order_for_ptr {
			use super::SizeOrder;
			impl_![lt ptr; i8: u8, i16: u16];
			impl_![eq ptr; i32: u32];
			impl_![gt ptr; i64: u64, i128: u128];
		}

		#[cfg(target_pointer_width = "64")]
		mod size_order_for_ptr {
			use super::SizeOrder;
			impl_![lt ptr; i8: u8, i16: u16, i32: u32];
			impl_![eq ptr; i64: u64];
			impl_![gt ptr; i128: u128];
		}

		macro_rules! impl_ {
			($t0:ty, $t1:ty, $($ts:ty),+) => {
				impl_![imp $t0, $t1];
				impl_![$t1, $($ts),+];
			};

			($t0:ty, $t1:ty) => {
				impl_![imp $t0, $t1];
			};

			(imp $t0:ty, $t1:ty) => {
				impl IntoLarger for $t0 {
					type LargerType = $t1;
				}
			};
		}

		impl_![i8, i16, i32, i64, i128];
		impl_![u8, u16, u32, u64, u128];
	}
}

pub mod math {
	pub mod number {
		pub mod modint {
			use crate::traits::consts::Constant;
			use crate::traits::integer::{IntoLarger, SizeOrder};
			use num::traits::{AsPrimitive, One, Zero};
			use std::ops::{Add, Div, Mul, Sub};

			pub struct ModInt<M>
			where
				M: Constant,
			{
				value: M::Type,
			}

			impl<T, U, M> From<T> for ModInt<M>
			where
				M: Constant,
				M::Type: num::Integer + num::Signed + SizeOrder<T, LargerType = U> + AsPrimitive<U>,
				T: num::Integer + SizeOrder<M::Type, LargerType = U> + AsPrimitive<U>,
				U: num::Integer + AsPrimitive<M::Type>,
			{
				fn from(src: T) -> Self {
					debug_assert!(M::value() >= M::Type::zero());
					let src: U = src.as_();
					let modulus: U = M::value().as_();
					let value = num::integer::mod_floor(src, modulus).as_();
					Self { value }
				}
			}

			impl<M> std::fmt::Display for ModInt<M>
			where
				M: Constant,
				M::Type: std::fmt::Display,
			{
				fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
					write!(f, "{}", self.value)
				}
			}

			impl<M> std::fmt::Debug for ModInt<M>
			where
				M: Constant,
				M::Type: std::fmt::Debug,
			{
				fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
					f.debug_tuple("ModInt").field(&self.value).finish()
				}
			}

			impl<M> Clone for ModInt<M>
			where
				M: Constant,
				M::Type: Clone,
			{
				fn clone(&self) -> Self {
					Self {
						value: self.value.clone(),
					}
				}
			}

			impl<M> Copy for ModInt<M>
			where
				M: Constant,
				M::Type: Copy,
			{
			}

			impl<M> Default for ModInt<M>
			where
				M: Constant,
				M::Type: Default,
			{
				fn default() -> Self {
					Self {
						value: M::Type::default(),
					}
				}
			}

			macro_rules! impl_std_ops {
				($trait:ident:$fn:ident for $type:ty) => {
					impl_std_ops!($type; $trait:$fn);
					impl_std_ops!($type; $trait:$fn<'a, &>);
					impl_std_ops!($type; <'a, &> $trait:$fn);
					impl_std_ops!($type; <'a, &> $trait:$fn<'b, &>);
				};

				($type:ty; $(<$lt_self:lifetime, $ref_self:tt>)? Add:$fn:ident $(<$lt_rhs:lifetime, $ref_rhs:tt>)?) => {
					impl<$($lt_self,)? $($lt_rhs, )?M> Add<$($ref_rhs$lt_rhs)?$type> for $($ref_self$lt_self)? $type
					where
						M: Constant,
						M::Type: Copy + num::Integer,
					{
						type Output = $type;
						fn $fn(self, rhs: $($ref_rhs$lt_rhs)?$type) -> Self::Output {
							let value = self.value.$fn(rhs.value);
							ModInt { value: if value >= M::value() { value - M::value() } else { value } }
						}
					}
				};

				($type:ty; $(<$lt_self:lifetime, $ref_self:tt>)? Sub:$fn:ident $(<$lt_rhs:lifetime, $ref_rhs:tt>)?) => {
					impl<$($lt_self,)? $($lt_rhs, )?M> Sub<$($ref_rhs$lt_rhs)?$type> for $($ref_self$lt_self)? $type
					where
						M: Constant,
						M::Type: Copy + num::Integer + num::Signed,
					{
						type Output = $type;
						fn $fn(self, rhs: $($ref_rhs$lt_rhs)?$type) -> Self::Output {
							let value = self.value.$fn(rhs.value);
							ModInt { value: if value < M::Type::zero() { value + M::value() } else { value } }
						}
					}
				};

				($type:ty; $(<$lt_self:lifetime, $ref_self:tt>)? Mul:$fn:ident $(<$lt_rhs:lifetime, $ref_rhs:tt>)?) => {
					impl<$($lt_self,)? $($lt_rhs, )?M> Mul<$($ref_rhs$lt_rhs)?$type> for $($ref_self$lt_self)? $type
					where
						M: Constant,
						M::Type: num::Integer + IntoLarger + AsPrimitive<<M::Type as IntoLarger>::LargerType>,
						<M::Type as IntoLarger>::LargerType: num::Integer + AsPrimitive<M::Type>,
					{
						type Output = $type;
						fn $fn(self, rhs: $($ref_rhs$lt_rhs)?$type) -> Self::Output {
							let modulus: <M::Type as IntoLarger>::LargerType = M::value().as_();
							let lhs: <M::Type as IntoLarger>::LargerType = self.value.as_();
							let rhs: <M::Type as IntoLarger>::LargerType = rhs.value.as_();
							let value: M::Type = num::integer::mod_floor(lhs.$fn(rhs), modulus).as_();
							ModInt { value }
						}
					}
				};

				($type:ty; $(<$lt_self:lifetime, $ref_self:tt>)? Div:$fn:ident $(<$lt_rhs:lifetime, $ref_rhs:tt>)?) => {
					impl<$($lt_self,)? $($lt_rhs, )?M> Div<$($ref_rhs$lt_rhs)?$type> for $($ref_self$lt_self)? $type
					where
						M: Constant,
						M::Type: Copy + num::Integer + num::Signed,
						$($ref_self$lt_self)?$type : Mul<$type, Output = $type>
					{
						type Output = $type;
						fn $fn(self, rhs: $($ref_rhs$lt_rhs)?$type) -> Self::Output {
							self * rhs.inverse()
						}
					}
				};
			}

			impl_std_ops!(Add:add for ModInt<M>);
			impl_std_ops!(Sub:sub for ModInt<M>);
			impl_std_ops!(Mul:mul for ModInt<M>);
			impl_std_ops!(Div:div for ModInt<M>);

			impl<M> std::ops::Neg for ModInt<M>
			where
				M: Constant,
				M::Type: num::Integer + num::Signed,
			{
				type Output = Self;
				fn neg(self) -> Self::Output {
					Self {
						value: if self.value == M::Type::zero() {
							M::Type::zero()
						} else {
							M::value() - self.value
						},
					}
				}
			}

			impl<M> Zero for ModInt<M>
			where
				M: Constant,
				M::Type: num::Zero + num::Integer,
				Self: Add<Output = Self>,
			{
				fn zero() -> Self {
					Self {
						value: M::Type::zero(),
					}
				}

				fn is_zero(&self) -> bool {
					self.value == M::Type::zero()
				}
			}

			impl<M, U> num::traits::Pow<U> for ModInt<M>
			where
				M: Constant,
				Self: Copy + One,
				U: num::Integer + num::Unsigned,
			{
				type Output = Self;
				fn pow(self, rhs: U) -> Self {
					let mut r = Self::one();
					let mut b = rhs;
					let mut a = self;
					while b > U::zero() {
						if b.is_odd() {
							r = r * a;
						}
						a = a * a;
						b = b / (U::one() + U::one());
					}
					r
				}
			}

			impl<M> One for ModInt<M>
			where
				M: Constant,
				M::Type: num::Integer,
				Self: Mul<Output = Self>,
			{
				fn one() -> Self {
					Self {
						value: M::Type::one(),
					}
				}
			}

			impl<M> ModInt<M>
			where
				M: Constant,
			{
				pub fn value(&self) -> &M::Type {
					&self.value
				}
			}

			impl<M> ModInt<M>
			where
				M: Constant,
				M::Type: Copy + num::Integer + num::Signed,
			{
				pub fn inverse(self) -> Self {
					let mut r = (M::value(), self.value);
					let mut s = (M::Type::zero(), M::Type::one());
					while r.1 != M::Type::zero() {
						let q = r.0 / r.1;
						let nr = r.0 - q * r.1;
						r = (r.1, nr);
						let ns = s.0 - q * s.1;
						s = (s.1, ns);
					}
					if r.0 > M::Type::one() {
						panic!();
					}
					Self {
						value: if s.0 < M::Type::zero() {
							s.0 + M::value()
						} else {
							s.0
						},
					}
				}
			}

			#[macro_export]
			macro_rules! define_runtime_modint {
				($mint:ident; $modulus:ident with $mod:ident: $type:ty) => {
					type $mint = $crate::math::number::modint::ModInt<$modulus>;
					thread_local! { static $mod: std::cell::RefCell<$type> = std::cell::RefCell::new(0); }
					struct $modulus;
					impl $modulus {
						pub fn with<T, F: FnOnce() -> T>(modulus: $type, f: F) -> T {
							$mod.with(|m| {
								*m.borrow_mut() = modulus;
								let _m = m.borrow();
								f()
							})
						}
					}
					unsafe impl traits::marker::Unsafe for $modulus {}
					impl traits::consts::Constant for $modulus {
						type Type = $type;
						fn value() -> Self::Type {
							$mod.with(|m| *m.borrow())
						}
					}
				};
			}
		}
	}
}


Measured memory_bytes: 2188