#include <algorithm>
#include <array>
#include <cassert>
#include <cstddef>
#include <initializer_list>

template <class T, std::size_t N, std::size_t M>
class array_matrix : public std::array<std::array<T, M>, N> {
public:
  array_matrix() {
    std::for_each(this->begin(), this->end(), [](auto &row) {
      std::fill(row.begin(), row.end(), static_cast<T>(0));
    });
  }
  array_matrix(std::initializer_list<std::initializer_list<T>> il) {
    assert(il.size() == N);
    auto ar_itr = this->begin();
    const auto ar_end = this->end();
    auto il_itr = il.begin();
    while (ar_itr != ar_end) {
      assert(il_itr->size() == M);
      std::copy(il_itr->begin(), il_itr->end(), ar_itr->begin());
      ++ar_itr;
      ++il_itr;
    }
  }
};

template <class T, std::size_t N, std::size_t M, std::size_t L>
array_matrix<T, N, L> operator*(const array_matrix<T, N, M> &lhs,
                                const array_matrix<T, M, L> &rhs) {
  array_matrix<T, N, L> ret = {};
  for (std::size_t i = static_cast<std::size_t>(0); i != N; ++i) {
    for (std::size_t j = static_cast<std::size_t>(0); j != M; ++j) {
      for (std::size_t k = static_cast<std::size_t>(0); k != L; ++k) {
        ret[i][k] += lhs[i][j] * rhs[j][k];
      }
    }
  }
  return ret;
}

template <class T, std::size_t N> array_matrix<T, N, N> identity() {
  array_matrix<T, N, N> ret;
  for (std::size_t i = static_cast<std::size_t>(0); i != N; ++i) {
    ret[i][i] = static_cast<T>(1);
  }
  return ret;
}

#include <cstdint>

class runtime_modint {
  using u64 = std::uint_fast64_t;

  static u64 &mod() noexcept {
    static u64 mod_ = static_cast<u64>(0);
    return mod_;
  }

  u64 a;

  runtime_modint &negate() noexcept {
    if (a != static_cast<u64>(0)) {
      a = get_mod() - a;
    }
    return *this;
  }

public:
  runtime_modint(const u64 x = static_cast<u64>(0)) : a(x % get_mod()) {}
  u64 &value() noexcept { return a; }
  u64 value() const noexcept { return a; }
  runtime_modint operator+() const noexcept { return runtime_modint(*this); }
  runtime_modint operator-() const noexcept {
    return runtime_modint(*this).negate();
  }
  runtime_modint operator+(const runtime_modint rhs) const noexcept {
    return runtime_modint(*this) += rhs;
  }
  runtime_modint operator-(const runtime_modint rhs) const noexcept {
    return runtime_modint(*this) -= rhs;
  }
  runtime_modint operator*(const runtime_modint rhs) const noexcept {
    return runtime_modint(*this) *= rhs;
  }
  runtime_modint operator/(const runtime_modint rhs) const noexcept {
    return runtime_modint(*this) /= rhs;
  }
  runtime_modint &operator+=(const runtime_modint rhs) noexcept {
    a += rhs.a;
    if (a >= mod()) {
      a -= mod();
    }
    return *this;
  }
  runtime_modint &operator-=(const runtime_modint rhs) noexcept {
    if (a < rhs.a) {
      a += mod();
    }
    a -= rhs.a;
    return *this;
  }
  runtime_modint &operator*=(const runtime_modint rhs) noexcept {
    a = a * rhs.a % mod();
    return *this;
  }
  runtime_modint &operator/=(runtime_modint rhs) noexcept {
    u64 exp = mod() - 2;
    while (exp) {
      if (exp % static_cast<u64>(2) != static_cast<u64>(0)) {
        *this *= rhs;
      }
      rhs *= rhs;
      exp /= static_cast<u64>(2);
    }
    return *this;
  }
  bool operator==(const runtime_modint rhs) const noexcept {
    return a == rhs.a;
  }
  bool operator!=(const runtime_modint rhs) const noexcept {
    return a != rhs.a;
  }

  static void set_mod(const u64 x) noexcept { mod() = x; }
  static u64 get_mod() noexcept { return mod(); }
};

#include <functional>
#include <utility>

template <class T, class U, class Operate = std::multiplies<T>>
constexpr T power(T base, U exp, const Operate &oper = Operate(),
                  T iden = static_cast<T>(1)) {
  while (exp != static_cast<U>(0)) {
    if (exp % static_cast<U>(2) != static_cast<U>(0)) {
      iden = oper(iden, base);
    }
    exp /= static_cast<U>(2);
    base = oper(base, base);
  }
  return iden;
}

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iostream>

int main() {
  using u64 = std::uint_fast64_t;
  using mint = runtime_modint;
  using vec_type = array_matrix<mint, static_cast<std::size_t>(1),
                                static_cast<std::size_t>(3)>;
  using trans_type = array_matrix<mint, static_cast<std::size_t>(3),
                                  static_cast<std::size_t>(3)>;

  u64 l, a, b, m;
  std::cin >> l >> a >> b >> m;
  mint::set_mod(m);

  vec_type vec(
      {{static_cast<mint>(0), static_cast<mint>(a), static_cast<mint>(1)}});
  trans_type trans(
      {{static_cast<mint>(0), static_cast<mint>(0), static_cast<mint>(0)},
       {static_cast<mint>(1), static_cast<mint>(1), static_cast<mint>(0)},
       {static_cast<mint>(0), static_cast<mint>(b), static_cast<mint>(1)}});
  u64 next = static_cast<u64>(1);

  while (l != static_cast<u64>(0)) {
    while (next <= a) {
      next *= static_cast<u64>(10);
    }
    trans[static_cast<std::size_t>(0)][static_cast<std::size_t>(0)] =
        static_cast<mint>(next);
    u64 step =
        std::min(l, (next - a - static_cast<u64>(1)) / b + static_cast<u64>(1));
    vec = vec * power(trans, step, std::multiplies<trans_type>(),
                      identity<mint, 3>());
    a += b * step;
    l -= step;
  }

  std::cout
      << vec[static_cast<std::size_t>(0)][static_cast<std::size_t>(0)].value()
      << std::endl;

  return 0;
}


Measured memory_bytes: 384