// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <string>
#include <cstring>
#include <deque>
#include <list>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <algorithm>
#include <map>
#include <set>
#include <complex>
#include <cmath>
#include <limits>
#include <cfloat>
#include <climits>
#include <ctime>
#include <cassert>
#include <numeric>
#include <fstream>
#include <functional>
#include <bitset>
using namespace std;

#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int
 
template<typename T> void chmax(T &a, T b) {a = max(a, b);}
template<typename T> void chmin(T &a, T b) {a = min(a, b);}
template<typename T> void chadd(T &a, T b) {a = a + b;}
 
typedef pair<int, int> pii;
typedef long long ll;
 
int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

int L, A, B, M;
const int D = 18;

// 行列ライブラリ
// Verified: TopCoder SRM 704 Div.2 (ModEquationEasy)
// 行列の積 と 累乗(繰り返し二乗法)

// Matrix Library Begin (C++11)

template <typename T>
using Matrix = vector< vector<T> >;

template <typename T>
void init_mat(Matrix<T> &A, int h, int w) {
    A.resize(h, vector<T>(w, 0));
}

template <typename T>
Matrix<T> calc_mat(Matrix<T> A, Matrix<T> B, int enable_mod = true) {
    Matrix<T> C(A.size(), vector<T>(B[0].size()));
    for(int i=0; i<A.size(); i++) {
        for(int k=0; k<B.size(); k++) {
            for(int j=0; j<B[0].size(); j++) {
                if(!enable_mod) C[i][j] += A[i][k] * B[k][j]; // modなし
                else C[i][j] = (C[i][j] + A[i][k] * B[k][j]) % M; // modあり
            }
        }
    }
    return C;
}

template <typename T>
Matrix<T> mat_pow(Matrix<T> A, ll n, int enable_mod = true) {
    if(n < 0) return A;
    Matrix<T> B(A.size(), vector<T>(A.size()));
    for(int i=0; i<A.size(); i++) B[i][i] = 1;
    while(n > 0) {
        if(n & 1) B = calc_mat(B, A, enable_mod);
        A = calc_mat(A, A, enable_mod);
        n >>= 1;
    }
    return B;
}

// N * M 行列のランクを求める
// 整数行列でも基本変形時に分数になるので double 型に限定しています
// 位数 2 の有限体では (演算を xor とかに直した形で) 確認済み、他は未 Verify なのでもしかしたらやばいかもしれない
int mat_rank(Matrix<double> A) {
    int N = A.size(), M = A[0].size();

    int res = 0;
    for(int i=0; i<M; i++) {
        // 絶対値が最も大きいものを探す
        double max_elem = 0; int piv = -1;
        for(int j=res; j<N; j++) {
            if(abs(A[j][i]) > max_elem) {
                max_elem = abs(A[j][i]);
                piv = j;
            }
        }

        // res 行目を piv 行目に変えて、行基本変形
        if(piv < 0) continue;
        swap(A[res], A[piv]);

        // res 行目を正規化
        // F_2 の場合はここは不要
        {
            double div = A[res][i];
            for(int k=0; k<M; k++) {
                A[res][k] = 1.0 * A[res][k] / div;
            }
        }
        
        for(int j=0; j<N; j++) {
            if(j == res) continue;
            assert(A[res][i] != 0);
            double mul = A[j][i];
            for(int k=0; k<M; k++) {
                // 場合に応じて xor に変えるなりする
                A[j][k] = A[j][k] - mul * A[res][k];
            }
        }
        res++;
    }
    return res;
}

// Matrix Library End

int digits(int N) {
    int res = 0;
    while(N > 0) res++, N /= 10;
    return res;
}

int mod_pow(int x, unsigned long long k) {
    int res = 1;
    for(; k>0; k>>=1) {
        if(k & 1) (res *= x) %= M;
        (x *= x) %= M;
    }
    return res;
}

int solve(int lim, int d) {
    if(lim < 0) return 0;
    
    Matrix<int> mat;
    init_mat(mat, 4, 4);
    
    // s_{i+1} = s_i * 10^d + a_i
    int ten = 1;
    for(int i=0; i<d; i++) (ten *= 10) %= M;
    
    mat[0] = {ten, 1, 0, B%M};
    mat[1] = {  0, 1, 0, B%M};
    mat[2] = {  0, 1, 0, 0};
    mat[3] = {  0, 0, 0, 1};

    Matrix<int> vec;
    init_mat(vec, 4, 1);
    vec[0][0] = A%M;
    vec[1][0] = A%M;
    vec[2][0] = 0;
    vec[3][0] = 1;

    return calc_mat(mat_pow(mat, lim), vec)[0][0];
}

signed main() {
    cin >> L >> A >> B >> M;
    fprintf(stderr, "digit: A = %lld, B = %lld\n", digits(A), digits(B));
    using MatAType = __int128;
    
    Matrix<MatAType> mat_a;
    init_mat(mat_a, 3, 3);
    // s_{i+1}, s_i, 1
    
    // s_{i+1} = s_i + B
    mat_a[0] = {1, 0, B};
    mat_a[1] = {1, 0, 0};
    mat_a[2] = {0, 0, 1};

    Matrix<MatAType> vec_a;
    init_mat(vec_a, 3, 1);
    vec_a[0][0] = A;
    vec_a[1][0] = 0;
    vec_a[2][0] = 1;

    // d 桁はどこからどこまで？
    vector<int> lims(D + 1);
    for(int d=1; d<=D; d++) {
        int ub = L, lb = -1;
        while(ub - lb > 1) {
            int mid = (ub + lb) / 2;
            MatAType res_a = calc_mat(mat_pow(mat_a, mid, false), vec_a, false)[0][0];

            int dig = 0;
            while(res_a > 0) dig++, res_a /= 10;

            if(dig >= d) ub = mid;
            else lb = mid;
        }
        lims[d] = ub;
        // fprintf(stderr, "lims[%lld] = %lld\n", d, lims[d]);
    }

    int ans = 0;
    for(int d=1; d<=D; d++) {
        // (lb, ub]
        int lb = 0, ub = 0;
        {
            MatAType res_a = calc_mat(mat_pow(mat_a, lims[d], false), vec_a, false)[0][0];

            int dig = 0;
            while(res_a > MatAType(0)) dig++, res_a /= 10;

            if(dig != d) continue;
            else lb = lims[d] - 1;
        }
        {
            if(d == D) ub = L-1;
            else {
                /*
                int res_a = calc_mat(mat_pow(mat_a, lims[d+1], false), vec_a, false)[0][0];

                int dig = 0;
                while(res_a > 0) dig++, res_a /= 10;
                */

                ub = lims[d+1] - 1;
            }
        }

        // 今までのやつをシフト
        unsigned long long shift = (ub - lb) * d;
        // fprintf(stderr, "shift = %lld\n", shift);
        (ans *= mod_pow(10, shift)) %= M;

        int resL = solve(lb, d) * mod_pow(10, shift) % M;
        int resR = solve(ub, d);
        int res = (resR - resL + M) % M;

        // fprintf(stderr, "(%lld, %lld]\n", lb, ub);
        // fprintf(stderr, "d = %lld, res = %lld\n", d, res);
        // fprintf(stderr, "resL = %lld, resR = %lld\n", resL, resR);
        (ans += res) %= M;
    }
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 256