#include <bits/stdc++.h>
#define WHOLE(v) (v).begin(), (v).end()
#define REV_WHOLE(v) (v).rbegin(), (v).rend()
using i64 = int64_t;
using namespace std;
template <size_t I, class H, class... T> struct TupleReaderWriter{static tuple<H,T...> r(istream&i){H v;i>>v;return tuple_cat(tuple<H>(v),TupleReaderWriter<sizeof...(T)-1,T...>::r(i));}static void w(ostream&o,tuple<H,T...>&t,string d){TupleReaderWriter<I-1,H,T...>::w(o,t,d);o<<d<<get<I>(t);}};
template <class H, class... T> struct TupleReaderWriter<0,H,T...>{static tuple<H,T...> r(istream&i){H v;i>>v;return tuple<H>(v);}static void w(ostream&o,tuple<H,T...>&t,string d){o<<get<0>(t);}};
template<class T>istream&operator>>(istream&i,vector<T>&v){for(auto&x:v)i>>x;return i;}
template<class T>ostream&operator<<(ostream&o,vector<T>&v){string delim="";for(auto&x:v)o<<delim<<x,delim=" ";return o;}
template <class... T> istream& operator>>(istream&i,tuple<T...>& t) { t = TupleReaderWriter<sizeof...(T), T...>::r(i); return i; }
template <class... T> ostream& operator<<(ostream& o, tuple<T...>& t) { string delim = " "; TupleReaderWriter<sizeof...(T) - 1, T...>::w(o, t, delim); return o; }
template<typename T> using rev_priority_queue = priority_queue<T, vector<T>, greater<T>>;
template<typename T> using vector2d = vector<vector<T>>;
void R_YESNO(bool p) { cout << (p ? "YES" : "NO") << endl; }
void R_YesNo(bool p) { cout << (p ? "Yes" : "No") << endl; }

struct int_m {
    static int64_t m;
    int64_t v;
    int_m() {}
    int_m(int64_t x) {v = x % m;}
    int_m operator+(const int_m& y) { return (v + y.v) % m; }
    int_m operator-(const int_m& y) { return (v - y.v + m) % m; }
    int_m operator*(const int_m& y) { return (v * y.v) % m; }
    /* int_m operator/(const int_m &y) { return (v * invmod(y.v)) % m; } */
    void operator+=(const int_m& y) { *this = *this + y; }
    void operator-=(const int_m& y) { *this = *this - y; }
    void operator*=(const int_m& y) { *this = *this * y; }
    /* void operator/=(const int_m &y) { *this = *this / y; } */
    friend istream& operator>>(istream& ist, int_m& m) { return ist >> m.v; }
    friend ostream& operator<<(ostream& ost, int_m& m) { return ost << m.v; }
};

int64_t int_m::m;

int64_t divceil(int64_t a, int64_t b) {
    return a / b + (a > 0 && a % b ? 1 : 0);
}

template <typename T>
struct Matrix {
    int r, c;
    using Container = vector2d<T>;
    Container m;
    int row() const { return r; }
    int column() const { return c; }
    Matrix() {}
    // O(RC)
    Matrix(int row, int column = -1, T val = 0) {
        if (row <= 0) row = 0;
        if (column < 0) column = row;
        c = column, r = row;
        m.resize(r);
        for (int i = 0; i < m.size(); i++) {
            m[i].resize(c, val);
        }
    }

    // O(RC)
    Matrix(const Matrix<T>& rhs) {
        m = rhs.m;
        r = rhs.row();
        c = rhs.column();
    }

    ~Matrix() {}

    vector<T>& operator[](int i) {
        return m[i];
    }

    // O(ABC) AxB 型と BxC型 の積の場合
    Matrix<T> operator*(const Matrix<T>& x) {
        if (c != x.r) return I(0);
        Matrix<T> retval = Matrix<T>(r, x.c);
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < x.c; j++) {
                T tmp = 0;
                for (int k = 0; k < c; k++) {
                    tmp += m[i][k] * x.m[k][j];
                }
                retval[i][j] = tmp;
            }
        }
        return retval;
    }

    Matrix<T> operator*(const T& x) {
        if (c != x.r) return I(0);
        Matrix<T> retval = Matrix<T>(r, x.c);
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < x.c; j++) {
                retval[i][j] *= x;
            }
        }
        return retval;
    }

    Matrix<T> operator+(const Matrix<T>& mat) {
        if (mat.r != mat || mat.c != c) return I(0);
        Matrix<T> retval = Matrix<T>(*this);
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                retval[i][j] += mat[i][j];
            }
        }
        return retval;
    }

    Matrix<T> operator-(const Matrix<T>& mat) {
        return (*this) + (mat * -1);
    }

    // O(N^3)
    T det() {
        int n = min(r, c);
        T retval = 1, buf;
        Matrix<T> a = Matrix<T>(this);
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i < j) {
                    buf = a[i][j] / a[i][i];
                    for (int k = 0; k < n; k++) {
                        a[j][k] -= a[i][k] * buf;
                    }
                }
            }
        }
        for (int i = 0; i < n; i++) {
            retval *= a[i][i];
        }
        return retval;
    }

    void power(int64_t p) {
        if(r != c) return;
        auto mul = *this;
        *this = I(r);
        for (; p > 0; p >>= 1, mul = mul * mul) {
            if (p & 1) {
                *this = mul * (*this);
            }
        }
    }

    static Matrix<T> I(int n) {
        Matrix<T> a(n, n, 0);
        for (int i = 0; i < n; i++) {
            a[i][i] = 1;
        }
        return a;
    }
};

int main() {
    i64 L, A, B, M;
    cin >> L >> A >> B >> M;
    int_m::m = M;
    const int D = 18;

    vector<i64> N(D);
    Matrix<int_m> mat[D];
    for(i64 d = 0, tmp = 10; d < D; d++, tmp *= 10) {
        N[d] = max(i64(0), min(L, divceil(tmp - A, B)));
        mat[d] = Matrix<int_m>(3, 3, 0);
        mat[d][0] = {tmp, 1, 0};
        mat[d][1] = {  0, 1, B};
        mat[d][2] = {  0, 0, 1};
        i64 p = N[d] - (d ? N[d - 1] : 0);
        mat[d].power(p);
    }
    Matrix<int_m> vec(3, 1, 0);
    vec[0][0] = 0;
    vec[1][0] = A;
    vec[2][0] = 1;

    for(int d = 0; d < D; d++) {
        vec = mat[d] * vec;
    }
    cout << vec[0][0] << endl;
    return 0;
}

Measured memory_bytes: 256