#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<ll, ll> ii;
#define REP(i,n) for (ll i = 0; i < n; ++i)
#define REPR(i,n) for (ll i = n-1; i >= 0; --i)
#define FOR(i,m,n) for (ll i = m; i < n; ++i)
#define FORR(i,m,n) for (ll i = n-1; i >= m; --i)
#define FORE(x,xs) for (const auto& x : xs)
#define FORI(i,v) for (auto i = v.begin(); i != v.end(); i++)
#define ALL(v) v.begin(), v.end()
#define CHMIN(x,y) x = min(x, y)
#define CHMAX(x,y) x = max(x, y)
#define YES(b) cout << ((b) ? "YES" : "NO") << endl
#define Yes(b) cout << ((b) ? "Yes" : "No") << endl
#define DOUBLE(d) cout << fixed << setprecision(15) << (d) << endl

template <typename T> struct Matrix {
private:
    typedef vector<T> vt;
    typedef vector<vt> vvt;

    void init(vvt A) {
        N = A.size(), M = A[0].size();
        data = vvt(N, vt(M));
        REP (i,N) copy(A[i].begin(), A[i].end(), data[i].begin());
    }

public:
    int N, M;
    vvt data;

    Matrix (int n, int m) { init(vvt(n, vt(m))); }
    Matrix (vvt A) { init(A); }

    Matrix operator~() { // transverse
        Matrix res(M, N);
        for (int j = 0; j < N; ++j) for (int i = 0; i < M; ++i)
            res.data[i][j] = data[j][i];
        return res;
    }

    Matrix &operator+= (const Matrix& b) {
        REP (i, N) REP (j, M) data[i][j] += b.data[i][j];
        return *this;
    }

    Matrix &operator-= (const Matrix& b) {
        REP (i, N) REP (j, M) data[i][j] -= b.data[i][j];
        return *this;
    }

    Matrix &operator*= (const Matrix& b) {
        int L = b.M;
        Matrix ret(N, L);
        REP (i, N) REP (j, L) {
            REP (k, M) ret.data[i][j] += data[i][k] * b.data[k][j];
        }
        M = L;
        data = ret.data;
        return *this;
    }

    Matrix &operator*= (const T c) {
        REP (i, N) REP (j, M) data[i][j] *= c;
        return *this;
    }

    Matrix operator-() const {
        Matrix ret = Matrix(*this);
        REP (i, N) REP (j, M) ret.data[i][j] = -ret.data[i][j];
        return ret;
    }

    Matrix operator+(const Matrix& b) const { return Matrix(*this) += b; }
    Matrix operator-(const Matrix& b) const { return Matrix(*this) -= b; }
    Matrix operator*(const Matrix& b) const { return Matrix(*this) *= b; }
    Matrix operator*(const T c) const { return Matrix(*this) *= c; }

    Matrix pow(int64_t k) const {
        Matrix ret(N, N);
        REP (i, N) ret.data[i][i] = T(1);
        Matrix tmp(data);
        while (k) {
            if (k&1) ret *= tmp;
            tmp *= tmp;
            k >>= 1;
        }
        return ret;
    }

    friend ostream &operator<<(ostream &os, const Matrix &p) {
        os << "[";
        REP (i, p.N) {
            os << "[";
            REP (j, p.M) os << p.data[i][j] << ((j == p.M-1)?"]":",");
            os << ((i == p.N-1)?"]":",");
        }
        return os;
    }
};

vector<int> MODS = { 11 };
template<int IND = 0> struct RuntimeModInt {
    int64_t x;
    int mod = MODS[IND];

    RuntimeModInt() : x(0) {}
    RuntimeModInt(int64_t y) : x(y % MODS[IND]) { if (y < 0) y += MODS[IND]; }

    RuntimeModInt &operator+=(const RuntimeModInt &a) {
        if ((x += a.x) >= mod) x -= mod;
        return *this;
    }

    RuntimeModInt &operator-=(const RuntimeModInt &a) {
        if ((x += mod - a.x) >= mod) x -= mod;
        return *this;
    }

    RuntimeModInt &operator*=(const RuntimeModInt &a) {
        x = 1LL * x * a.x % mod;
        return *this;
    }

    RuntimeModInt &operator/=(const RuntimeModInt &a) {
        *this *= a.inverse();
        return *this;
    }

    RuntimeModInt operator-() const {
        return RuntimeModInt(-x);
    }

    RuntimeModInt operator+(const RuntimeModInt a) const {
        return RuntimeModInt(*this) += a;
    }

    RuntimeModInt operator-(const RuntimeModInt a) const {
        return RuntimeModInt(*this) -= a;
    }

    RuntimeModInt operator*(const RuntimeModInt a) const {
        return RuntimeModInt(*this) *= a;
    }

    RuntimeModInt operator/(const RuntimeModInt a) const {
        return RuntimeModInt(*this) /= a;
    }

    bool operator==(const RuntimeModInt a) const {
        return x == a.x;
    }

    bool operator!=(const RuntimeModInt a) const {
        return x != a.x;
    }

    RuntimeModInt pow(int64_t k) const {
        RuntimeModInt ret(1), mul(x);
        while (k > 0) {
            if (k & 1) ret *= mul;
            mul *= mul;
            k >>= 1;
        }
        return ret;
    }

    RuntimeModInt inverse() const {
        return pow(mod - 2);
    }

    friend ostream &operator<<(ostream &os, const RuntimeModInt &p) {
        return os << p.x;
    }

    friend istream &operator>>(istream &is, RuntimeModInt &a) {
        int64_t t;
        is >> t;
        a = RuntimeModInt<>(t);
        return (is);
    }
};

ll L, A, B;
int M;

ll solve() {
    using modint = RuntimeModInt<>;
    using matrix = Matrix<modint>;

    ll used = 0;
    ll k10 = 1;
    matrix b(3, 1);
    b.data[0][0] = modint(0);
    b.data[1][0] = modint(A);
    b.data[2][0] = modint(1);

    FOR (k, 1, 19) {
        k10 *= 10;
        ll ng = -1, ok = L;
        while (ok - ng > 1) {
            ll mid = (ok + ng) / 2;
            if (A + B*mid >= k10) ok = mid;
            else ng = mid;
        }

        ll l = ok - used;

        matrix a(3, 3);
        a.data[0][0] = modint(k10);
        a.data[1][2] = modint(B);
        a.data[0][1] = a.data[1][1] = a.data[2][2] = modint(1);

        b = a.pow(l)*b;
        used += l;
    }

    return b.data[0][0].x;
}

int main() {
    cin >> L >> A >> B >> MODS[0];
    cout << solve() << endl;
}

Measured memory_bytes: 256