#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <time.h>

#define int long long

using namespace std;

long long phim;
long long m, mm;

unsigned long long inq(unsigned long long x, unsigned long long y)
{
    if (y == 0) return 1;
    unsigned long long l = inq(x, y / 2);
    if (y % 2) return l * l * x;
    return l * l;
}

unsigned long long inq(unsigned long long x, unsigned long long y, unsigned long long MOD)
{
    if (y == 0) return 1 % MOD;
    unsigned long long l = inq(x, y / 2, MOD);
    if (y % 2) return l * l % MOD * x % MOD;
    return l * l % MOD;
}

struct Matrix{
    int n, m;
    long long a[3][3];
    Matrix (int n_, int m_)
    {
        n = n_, m = m_;
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < m; j++)
            {
                a[i][j] = 0;
            }
        }
    }
};

Matrix operator * (Matrix A, Matrix B)
{
    if (A.m != B.n)
    {
        exit(0);
    }
    int o = A.m;
    Matrix C(A.n, B.m);
    for (int i = 0; i < A.n; i++)
    {
        for (int j = 0; j < B.m; j++)
        {
            for (int k = 0; k < o; k++)
            {
                C.a[i][j] = (C.a[i][j] + A.a[i][k] * B.a[k][j]) % m;
            }
        }
    }
    return C;
}

Matrix operator ^ (Matrix A, long long c)
{
    if (c == 0)
    {
        Matrix NULLER(A.n, A.m);
        for (int i = 0; i < A.n; i++)
        {
            NULLER.a[i][i] = 1;
        }
        return NULLER;
    }
    if (c == 1) return A;
    Matrix B = A ^ (c / 2);
    if (c % 2) return B * B * A;
    return B * B;
}

long long scalar(long long k, long long b, long long x, long long a, long long n)
{
    if (n == 0)
        return 0;
    k = k % m;
    b = b % m;
    x = x % m;
    a = a % m;
    //n = (mm + n) % m;
    // k + i * b
    // x * (a ^ i)
    //cout << k << " " << b << " " << x << " " << a << " " << n << endl;
    Matrix Sta(1, 3);
    Matrix Exp(3, 3);
    Sta.a[0][0] = k;
    Sta.a[0][1] = (k + b) % m;
    Sta.a[0][2] = b;
    Exp.a[0][0] = a;
    Exp.a[1][0] = 1;
    Exp.a[1][1] = 1;
    Exp.a[2][1] = 1;
    Exp.a[2][2] = 1;
    Exp = Exp ^ (n - 1);
    Sta = Sta * Exp;
    return x * Sta.a[0][0] % m;
}

long long log10(long long x)
{
    if (x < 10)
        return 1;
    return log10(x / 10) + 1;
}

long long solve(long long l, long long a, long long b)
{
    //cout << "Block with l = " << l << endl;
    long long last = a + (l - 1) * b;
    unsigned long long zeroes = 0;
    long long ans = 0;
    for (int i = log10(last); i >= 1 && l > 0; i--)
    {
        //cout << "last = " << last << endl;
        //cout << "zeroes = " << zeroes << endl;
        long long lesser = inq(10, i - 1);
        long long steps = (last - lesser + b - 1) / b;
        if (last - steps * b >= lesser) steps++;
        steps = min(steps, l);
        l = l - steps;
        long long Fi = last - steps * b + b;
        //cout << "Fi and La : " << Fi << " " << last << endl;
        long long value = scalar(Fi, b, 1, inq(10, log10(last), m), steps);
        ans = (ans + inq(10, zeroes, m) % m * value) % m;
        //cout << "and added : " << value << endl;
        //cout << "and zeroes : " << steps * log10(last) << endl;
        zeroes += steps * log10(last);
        last = last - steps * b;
    }
    return ans;
}

long long stupid(long long l, long long a, long long b)
{
    long long summ = 0;
    long long num = a;
    for (int i = 0; i < l; i++)
    {
        summ = (summ * inq(10, log10(num), m) + num) % m;
        num = num + b;
        if (num >= 1000000000000000000)
            return -1;
    }
    return summ;
}

signed main()
{
    srand(time(NULL));
    long long l, a, b;
    cin >> l >> a >> b >> m;
    cout << solve(l, a, b) << " ";
    //cout << stupid(l, a, b) << " ";
}


Measured memory_bytes: 256