#include <bits/stdc++.h>
#include <vector>
#include <queue>
#include <set>
using namespace std;
//#include <boost/multiprecision/cpp_int.hpp>
//using multiInt = boost::multiprecision::cpp_int;

using ll = long long int;
using ld = long double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template<typename Q_temp>
using smaller_queue = priority_queue <Q_temp, vector<Q_temp>, greater<Q_temp> >;

ll MOD = (ll) (1e9 + 7);
const int INF = (int) 1e9;
const ll LINF = (ll) 4e18;
const double PI = acos(-1.0);

#define REP(i,m,n) for(ll i = m; i < (ll)(n); ++i)
#define rep(i,n) REP(i, 0, n)
#define MP make_pair
#define MT make_tuple
#define YES(n) cout << ((n) ? "YES" : "NO") << endl
#define Yes(n) cout << ((n) ? "Yes" : "No") << endl
#define Possible(n) cout << ((n) ? "Possible" : "Impossible") << endl
#define all(v) v.begin(), v.end()
#define NP(v) next_permutation(all(v))
#define dbg(x_) cerr << #x_ << ":" << x_ << endl;
#define dbg2(x_) for(auto a_ : x_) cerr << a_ << " "; cerr << endl;
#define dbg3(x_ , sx_) rep(i, sx_) cerr << x_[i] << " "; cerr << endl;
vector<int> Dx = {0, 0, -1, 1, -1, 1, -1, 1, 0};
vector<int> Dy = {1, -1, 0, 0, -1, -1, 1, 1, 0};

inline ll CEIL(ll a, ll b) {
    return (a + b - 1) / b;
}

void finish() {
    cout << -1 << endl;
    exit(0);
}

//------------------------------------------------------

long long mul_mod(long long a, long long b, const long long MOD) {
    return b ? (mul_mod(a * 2, b / 2, MOD) + (b & 1 ? a : 0)) % MOD : 0;
}

long long bpow_mod(long long a, long long b, const long long MOD) {
    return (b ? bpow_mod(a * a % MOD, b / 2, MOD) * (b & 1 ? a : 1) : 1) % MOD;
}

long long inv_mod(long long a, const long long MOD) {
    return bpow_mod(a, MOD - 2, MOD);
}

vector<long long> MODS = {MOD};

template <int kind = 0, int fast = 0 >
class mint {
public:
    long long v;

    mint() : v(0) {
    }

    mint(long long v)
    : v(fast == 0 ? (v < 0 ? (v % MODS[kind] + MODS[kind]) % MODS[kind]
    : (v >= MODS[kind] ? v % MODS[kind] : v))
    : (v)) {
    }

    long long get_mod() {
        return MODS[kind];
    }

    long long get_val() {
        return v;
    }

    void take_mod() {
        v %= MODS[kind];
    }
};

template <int kind, int fast>
ostream& operator<<(ostream& os, const mint<kind, fast>& x) {
    return os << (x.v % MODS[kind] + MODS[kind]) % MODS[kind];
}

template <int kind, int fast, int fast2>
bool operator==(mint<kind, fast>& a, mint<kind, fast2> b) {
    return a.v == b.v;
}

template <int kind, int fast, int fast2>
mint<kind, fast>& operator+=(mint<kind, fast>& a, mint<kind, fast2> b) {
    return a = a.v + b.v;
}

template <int kind>
mint<kind>& operator-=(mint<kind>& a, mint<kind> b) {
    return a = a.v - b.v;
}

template <int kind>
mint<kind>& operator*=(mint<kind>& a, mint<kind> b) {
    return a = a.v * b.v;
}

template <int kind>
mint<kind>& operator/=(mint<kind>& a, mint<kind> b) {
    return a = a.v * inv_mod(b.v, a.get_mod());
}

template <int kind, int fast, int fast2>
mint<kind, fast> operator+(mint<kind, fast> a, mint<kind, fast2> b) {
    return a += b;
}

template <int kind>
mint<kind> operator-(mint<kind> a, mint<kind> b) {
    return a -= b;
}

template <int kind>
mint<kind> operator*(mint<kind> a, mint<kind> b) {
    return a *= b;
}

template <int kind>
mint<kind> operator/(mint<kind> a, mint<kind> b) {
    return a /= b;
}

template <int kind, int fast>
mint<kind, fast>& operator+=(mint<kind, fast>& a, long long b) {
    return a = a.v + b;
}

template <int kind>
mint<kind>& operator-=(mint<kind>& a, long long b) {
    return a = a.v - b;
}

template <int kind>
mint<kind>& operator*=(mint<kind>& a, long long b) {
    return a = a.v * b;
}

template <int kind>
mint<kind>& operator/=(mint<kind>& a, long long b) {
    return a = a.v * inv_mod(b, a.get_mod());
}

template <int kind, int fast>
mint<kind, fast> operator+(mint<kind, fast> a, long long b) {
    return a += b;
}

template <int kind>
mint<kind> operator-(mint<kind> a, long long b) {
    return a -= b;
}

template <int kind>
mint<kind> operator*(mint<kind> a, long long b) {
    return a *= b;
}

template <int kind>
mint<kind> operator/(mint<kind> a, long long b) {
    return a /= b;
}

const int MAX_N = 210, MAX_M = 210;

template<typename T> class Matrix {
public:
    size_t N, M; //N*M行列
    T data[MAX_N][MAX_M];

    Matrix(size_t init_N, size_t init_M) : N(init_N), M(init_M) {

    }

    Matrix operator+(const Matrix& A) {
        assert(A.N == N && A.M == M);
        Matrix res(N, M);
        rep(i, N) rep(j, M) res.data[i][j] = data[i][j] + A.data[i][j];
        return res;
    }

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

    Matrix operator-(const Matrix& A) {
        assert(A.N == N && A.M == M);
        Matrix<T> res(N, M);
        rep(i, N) rep(j, M) res.data[i][j] = data[i][j] - A.data[i][j];
        return res;
    }

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

    Matrix operator*(const Matrix& A) {
        assert(M == A.N);
        Matrix res(N, A.M);

        rep(i, N) rep(j, A.M) {
            rep(k, M) res.data[i][j] += data[i][k] * A.data[k][j];
        }
        return res;
    }

    Matrix& operator*=(const Matrix<T>& A) {
        return *this = *this * A;
    }

    Matrix operator*(T a) {
        Matrix res(N, M);
        rep(i, N) rep(j, M) res.data[i][j] = data[i][j] * a;
        return res;
    }

    Matrix& operator*=(ll a) {
        rep(i, N) rep(j, M) data[i][j] *= a;
        return *this;
    }

    bool operator==(Matrix& A) {
        if (N != A.N || M != A.M) return false;

        rep(i, N) rep(j, M) {
            if (data[i][j] != A.data[i][j]) return false;
        }
        return true;
    }

    bool operator!=(Matrix& A) {
        return !(*this == A);
    }

    Matrix transpose() {
        Matrix res(M, N);
        rep(i, N) rep(j, M) res.data[j][i] = data[i][j];
        return res;
    }

    ll trace() {
        assert(N == M);
        ll res = 0;
        rep(i, N) res += data[i][i];
        return res;
    }

    void display() {

        rep(i, N) {
            rep(j, M) cerr << data[i][j] << " ";
            cerr << endl;
        }
    }

    Matrix E(const ll n) {
        Matrix res(n, n);
        rep(i, n) rep(j, n) res.data[i][j] = (i == j);
        return res;
    }

    Matrix pow(const ll n) {
        assert(N == M);
        bitset<60> bs(n);
        int pow_cnt = 0;
        rep(i, 60) if (bs[i]) pow_cnt = i + 1;
        Matrix P = *this;
        Matrix res = E(N);

        rep(i, pow_cnt) {
            if (bs[i]) res *= P;
            P *= P;
        }
        return res;
    }

};

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << setprecision(20) << setiosflags(ios::fixed);

    ll l, a, b, m;
    cin >> l >> a >> b >> m;
    MODS[0] = m;

    ll min_d[20]; //d桁以下の要素の個数
    ll d[20]; //d桁の要素の個数

    for (ll i = 1; i <= 18; ++i) {
        ll sup = (ll) pow(10, i) - 1;
        if (sup - a < 0) {
            min_d[i] = 0;
            continue;
        }
        ll max_i = (sup - a) / b;
        min_d[i] = min(l, max_i + 1);
    }

    min_d[0] = 0;
    for (ll i = 1; i <= 18; ++i) d[i] = (min_d[i] - min_d[i - 1]);

    Matrix<mint<> > ans(1, 3);
    ans.data[0][0] = 0;
    ans.data[0][1] = a;
    ans.data[0][2] = 1;
    for (ll i = 1; i <= 18; ++i) {
        Matrix<mint<> > M_pow(3, 3);
        mint<> pow10 = (ll) pow(10, i) % m;
        M_pow.data[0][0] = pow10;
        M_pow.data[0][1] = 0;
        M_pow.data[0][2] = 0;
        M_pow.data[1][0] = 1;
        M_pow.data[1][1] = 1;
        M_pow.data[1][2] = 0;
        M_pow.data[2][0] = 0;
        M_pow.data[2][1] = b;
        M_pow.data[2][2] = 1;
        ans *= M_pow.pow(d[i]);
    }
    cout << ans.data[0][0] << endl;

    return 0;
}



Measured memory_bytes: 2688