//
//  main.cpp
//
// https://atcoder.jp/contests/abc129/tasks/abc129_f

#include <algorithm>
#include <array>
#include <assert.h>
#include <functional>
#include <iostream>
#include <limits>
#include <math.h>
#include <memory>
#include <queue>
#include <random>
#include <set>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <vector>

using namespace std;

using ll = long long;
using ull = unsigned long long;

static ll BASE;

ull max_two_power_contained(ull x) {
    for (int i = 63; i >= 0; i--) {
        if (x & ((ull)1 << i)) {
            return (ull)1 << i;
        }
    }
    assert(false);
}

ll good_mod(ll x) {
    return (x % BASE + BASE) % BASE;
}

ll power(ll a, ull b, unordered_map<ull, ll>& cache) {
    auto cache_iter = cache.find(b);
    if (cache_iter != cache.end()) {
        return cache_iter->second;
    } else if (b == 0) {
        return 1;
    } else if (b == 1) {
        return a;
    } else {
        ull h = max_two_power_contained(b);
        if (h == b) {
            h = b / 2;
        }
        cache[h] = power(a, h, cache);
        return good_mod(cache[h] * power(a, b-h, cache));
    }
}

// r^0 + r^1 + ... + r^(n-1) mod BASE
ll Sn(ll r, ull n, unordered_map<ull, ll>& cache, unordered_map<ull, ll>& pow_cache) {
    auto cache_iter = cache.find(n);
    if (cache_iter != cache.end()) {
        return cache_iter->second;
    } else if (n == 0) {
        return 0;
    } else if (n == 1) {
        return 1;
    } else {
        ull h = max_two_power_contained(n);
        if (h == n) {
            h = n / 2;
        }
        cache[h] = Sn(r, h, cache, pow_cache);
        return good_mod(cache[h] + good_mod(power(r, h, pow_cache) * Sn(r, n-h, cache, pow_cache)));
    }
}

// 0r^0 + 1r^1 + ... + (n-1)r^(n-1) mod BASE
ll Tn(ll r, ull n, unordered_map<ull, ll>& cache, unordered_map<ull, ll>& sn_cache, unordered_map<ull, ll>& pow_cache) {
    auto cache_iter = cache.find(n);
    if (cache_iter != cache.end()) {
        return cache_iter->second;
    } else if (n == 0) {
        return 0;
    } else if (n == 1) {
        return 0;
    } else {
        ull h = max_two_power_contained(n);
        if (h == n) {
            h = n / 2;
        }
        cache[h] = Tn(r, h, cache, sn_cache, pow_cache);
        ll ans = good_mod(good_mod(h) * Sn(r, n-h, sn_cache, pow_cache));
        ans = good_mod(ans + Tn(r, n-h, cache, sn_cache, pow_cache));
        ans = good_mod(ans * power(r, h, pow_cache));
        ans = good_mod(cache[h] + ans);
        return ans;
    }
}

int main(int argc, char* argv[]) {
    ll L, A, B, M;
    cin >> L >> A >> B >> M;
    BASE = M;
    vector<ll> exceed_index(19); // exceed_is[n] = s_iの桁が初めてn桁以上になるようなi
    auto si = [A,B](ll i) -> ll {
        return A + B * i;
    };
    auto si_len = [&si](ll i) -> ll {
        string si_str = to_string(si(i));
        return si_str.size();
    };
    for (ll n = 0; n <= 18; n++) {
        if (si_len(0) >= n) {
            exceed_index[n] = 0;
            continue;
        }
        ll lower_bound = 0;
        ll upper_bound = 1;
        while (true) {
            if (si_len(upper_bound) >= n) {
                break;
            }
            upper_bound *= 2;
        }
        while (true) {
            if (upper_bound - lower_bound == 1) {
                exceed_index[n] = upper_bound;
                break;
            }
            ll intermediate = lower_bound + (upper_bound - lower_bound) / 2;
            if (si_len(intermediate) >= n) {
                upper_bound = intermediate;
            } else {
                lower_bound = intermediate;
            }
        }
    }
    ll ans = 0;
    ll len = 0;
    ll last_i = L-1;
    while (last_i >= 0) {
        ll term_len = si_len(last_i);
        ll first_i = exceed_index[term_len];
        ll num_of_terms = last_i - first_i + 1;
        ll sub_sum = 0;
        ll A_plus_B_last_i = good_mod(A + good_mod(B * last_i));
        unordered_map<ull, ll> pow_cache_0;
        ll ten_pow_term_len = power(10, term_len, pow_cache_0);
        unordered_map<ull, ll> pow_cache;
        unordered_map<ull, ll> sn_cache;
        unordered_map<ull, ll> tn_cache;
        ll sn = Sn(ten_pow_term_len, num_of_terms, sn_cache, pow_cache);
        ll tn = Tn(ten_pow_term_len, num_of_terms, tn_cache, sn_cache, pow_cache);
        sub_sum += good_mod(A_plus_B_last_i * sn);
        sub_sum = good_mod(sub_sum - good_mod(good_mod(B) * tn));
        unordered_map<ull, ll> pow_cache_1;
        sub_sum = good_mod(power(10, len, pow_cache_1) * sub_sum);
        ans = good_mod(ans + sub_sum);
        len += term_len * num_of_terms;
        last_i = first_i - 1;
    }
    cout << ans << endl;
}


Measured memory_bytes: 256