#include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
#ifndef __FASTPOW_INCLUDED_
#define __FASTPOW_INCLUDED_
template <typename T> T fpow_eq(T& x, long long y, T identity = 1) {
    for(; y > 0; x *= x, y >>= 1) if(y & 1) identity *= x;
    return x = identity;
}
template <typename T> T fpow(T x, long long y, T identity = 1) { return fpow_eq(x, y, identity); }
#endif
int M;
struct modint {
    int val;
    modint() : val(0) {}
    modint(int x) : val(x % M) { val += val < 0 ? M : 0; }
    modint(long long x) : modint(int(x % M)) {}
    explicit operator int() const { return val; }
    bool operator==(const modint& y) const { return val == y.val; }
    bool operator!=(const modint& y) const { return val != y.val; }
    modint& operator+=(const modint& y) { val += y.val; val -= val >= M ? M : 0; return *this; }
    modint& operator-=(const modint& y) { val -= y.val; val += val <  0 ? M : 0; return *this; }
    modint& operator*=(const modint& y) { val = ll(val) * y.val % M; return *this; }
    modint& operator^=(ll y) { fpow_eq(*this, y); return *this; }
    modint operator+(const modint& y) const { return modint(*this) += y; }
    modint operator-(const modint& y) const { return modint(*this) -= y; }
    modint operator*(const modint& y) const { return modint(*this) *= y; }
    modint operator^(ll y) const { return modint(*this) ^= y; }
    modint operator-() const { return modint(0) -= *this; }
    modint& operator++() { val = val == M - 1 ? 0 : val + 1; return *this; }
    modint& operator--() { val = val == 0 ? M - 1 : val - 1; return *this; }
    modint operator++(int) { modint m = *this; ++(*this); return m; }
    modint operator--(int) { modint m = *this; --(*this); return m; }
    friend modint operator+(long long x, const modint& y) { return modint(x) + y; }
    friend modint operator*(long long x, const modint& y) { return modint(x) * y; }
    friend modint operator-(long long x, const modint& y) { return modint(x) - y; }
    friend ostream& operator<<(ostream& os, const modint& m) { return os << m.val; }
    friend istream& operator>>(istream& is, modint& m) { ll val; is >> val; m = modint(val); return is; }
};
modint operator""_m(unsigned long long int x) { return modint(ll(x)); }
template <typename T, typename Can> T bsearch(T L, T R, const Can& can, bool left_feasible = true) {
    static_assert(is_convertible<decltype(can), function<bool(T)>>::value, "can must be bool(T)");
    T& feasible = left_feasible ? L : R;
    T& infeasible = left_feasible ? R : L;
    while(R - L > 1) {
        T M = L + (R - L) / 2;
        (can(M) ? feasible : infeasible) = M;
    }
    return feasible;
}
#ifndef __FASTPOW_INCLUDED_
#define __FASTPOW_INCLUDED_
template <typename T> T fpow_eq(T& x, long long y, T identity = 1) {
    for(; y > 0; x *= x, y >>= 1) if(y & 1) identity *= x;
    return x = identity;
}
template <typename T> T fpow(T x, long long y, T identity = 1) { return fpow_eq(x, y, identity); }
#endif
using szt = size_t; // required for operator overload template argument deduction
template <typename T, szt N, szt M> using mat = array<array<T, M>, N>;
template <typename T, szt N> using sqmat = mat<T, N, N>;
template <typename T, szt N> sqmat<T, N> I() {
    sqmat<T, N> I = {}; // required to initialize to 0
    for(szt i = 0; i < N; i++) {
        I[i][i] = 1;
    }
    return I;
}
template <typename T, szt P, szt Q> mat<T, P, Q>& operator+=(mat<T, P, Q>& A, const mat<T, P, Q>& B) {
    for(szt i = 0; i < P; i++) {
        for(szt j = 0; j < Q; j++) {
            A[i][j] += B[i][j];
        }
    }
    return A;
}
template <typename T, szt P, szt Q> mat<T, P, Q> operator+(mat<T, P, Q> A, const mat<T, P, Q>& B) { return A += B; }
template <typename T, szt P, szt Q> mat<T, P, Q>& operator-=(mat<T, P, Q>& A, const mat<T, P, Q>& B) {
    for(szt i = 0; i < P; i++) {
        for(szt j = 0; j < Q; j++) {
            A[i][j] -= B[i][j];
        }
    }
    return A;
}
template <typename T, szt P, szt Q> mat<T, P, Q> operator-(mat<T, P, Q> A, const mat<T, P, Q>& B) { return A -= B; }
template <typename T, szt P, szt Q> mat<T, P, Q>& operator*=(mat<T, P, Q>& A, const T& c) {
    for(szt i = 0; i < P; i++) {
        for(szt j = 0; j < Q; j++) {
            A[i][j] *= c;
        }
    }
    return A;
}
template <typename T, szt P, szt Q> mat<T, P, Q> operator*(mat<T, P, Q> A, const T& c) { return A *= c; }
template <typename T, szt P, szt Q> mat<T, P, Q>& operator*=(const T& c, mat<T, P, Q>& A) { return A *= c; }
template <typename T, szt P, szt Q> mat<T, P, Q> operator*(const T& c, mat<T, P, Q> A) { return A *= c; }
template <typename T, szt P, szt Q> mat<T, P, Q> operator-(mat<T, P, Q> A) { return A *= -1; }
template <typename T, szt P, szt Q, szt R> mat<T, P, R> operator*(const mat<T, P, Q>& A, const mat<T, Q, R>& B) {
    mat<T, P, R> C = {};
    for(szt i = 0; i < P; i++) {
        for(szt k = 0; k < Q; k++) {
            for(szt j = 0; j < R; j++) {
                C[i][j] += A[i][k] * B[k][j];
            }
        }
    }
    return C;
}
template <typename T, szt N> sqmat<T, N> operator*=(sqmat<T, N>& A, sqmat<T, N>& B) { return A = A * B; }
template <typename T, szt N> sqmat<T, N> operator^=(sqmat<T, N>& x, long long y) {
    return fpow_eq(x, y, I<T, N>());
}
template <typename T, szt N> sqmat<T, N> operator^(sqmat<T, N> x, long long y) { return x ^= y; }
template <typename T, szt N> T operator|(const array<T, N>& u, const array<T, N>& v) {
    T ans = 0;
    for(int i = 0; i < N; i++) {
        ans += u[i] * v[i];
    }
    return ans;
}
template <typename T, szt N> array<T, N> operator|(const sqmat<T, N>& A, const array<T, N>& x) {
    array<T, N> ans;
    for(int i = 0; i < N; i++) {
        ans[i] = A[i] | x;
    }
    return ans;
}
// NOTE: outer braces required for initialization
// example: matrix<int, 2, 2> m = { {{1, 0}, {0, 1}} };
template <typename T> T ceildiv(T x, T y) {
    return (x + y - 1) / y;
}
int ndig(ll n) {
    int ans = 0;
    while(n > 0) {
        n /= 10;
        ans++;
    }
    return ans;
}
modint solve(int digits, ll A, ll B, ll L, ll term) {
    sqmat<modint, 3> m = {{
        {10_m ^ digits, 1, 1},
        {0, 1, 1},
        {0, 0, 1}
    }};
    return ((m ^ term) | array<modint, 3>{A + B * L, A + B * L, B})[0];
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    ll n, A, B;
    cin >> n >> A >> B >> M;
    modint ans = 0, offset = 1;
    for(int digits = ndig(A + B * (n - 1)); digits >= ndig(A); digits--) {
        ll L = bsearch<ll>(-1, n - 1, [&](ll k) { return ndig(A + B * k) >= digits; }, false);
        ll R = bsearch<ll>(0, n, [&](ll k) { return ndig(A + B * k) <= digits; });
        if(L <= R) {
            ll nterms = R - L + 1;
            ans += solve(digits, A, B, L, nterms - 1) * offset;
            offset *= 10_m ^ digits ^ nterms;
        }
    }
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 3628