//#define TEST

using System;
using static System.Math;

class Program
{
    static long l;
    static long a;
    static long b;
    static long m;

    static void Main()
    {
        /* 入力の受け取り */
        string[] input = Console.ReadLine().Split();
        l = long.Parse(input[0]);
        a = long.Parse(input[1]);
        b = long.Parse(input[2]);
        m = long.Parse(input[3]);

        Matrix<long>.SetMod(m); //余りを設定

        /* k(=1,2,...,18)について、k桁のものを並べてできる数をmで割った余りを求める */
        long[] mod = new long[19];
        long[] l_k = new long[19]; //siがk桁になる最小のk
        long[] r_k = new long[19]; //siがk桁になる最大のk
        for (int k = 1; k <= 18; k++)
        {
            if (a.ToString().Length > k)
            {
                l_k[k] = -1;
                r_k[k] = -1;
                continue;
            }
            r_k[k] = kDig(k);
            l_k[k] = kDig(k - 1) + 1;
        }
#if TEST
        for (int k = 1; k <= 18; k++)
            Console.WriteLine("{0} {1}", l_k[k], r_k[k]);
#endif
        Matrix<long> ans = new Matrix<long>(1, 3);
        ans[0, 1] = a;
        ans[0, 2] = 1;
        for (int k = 1; k <= 18; k++)
        {
            if (r_k[k] < l_k[k]) continue;
            if (l_k[k] == -1) continue;
            Matrix<long> X = new Matrix<long>(3, 3);
            X[0, 0] = (long)Pow(10, k);
            X[1, 0] = 1;
            X[1, 1] = 1;
            X[2, 1] = b;
            X[2, 2] = 1;
            X.Pow(r_k[k] - l_k[k] + 1);
            ans = ans * X;
        }
        Console.WriteLine(ans[0, 0]);
    }

    /* siがk桁以下であるようなiの最大値(a+bi<10^kを解く) */
    static long kDig(long k)
    {
        if (k < a.ToString().Length) return -1;
        long t = (long)Pow(10, k) - a;
        long v = t / b;
        if (t % b == 0) v--;
        return Min(v, l - 1);
    }
}

/* T型の行列 */
struct Matrix<T>
{
    private T[,] A; //各値を格納
    public T this[int i, int j]
    {
        get
        {
            try { return A[i, j]; } catch { throw; }
        }
        set
        {
            try { A[i, j] = (dynamic)value % mod; } catch { throw; }
        }
    }
    public int width; //列の個数
    public int height; //行の個数
    public static long mod = (long)1e9 + 7;

    /* コンストラクタ(行数、列数、mod(省略可)を指定) */
    public Matrix(int height, int width)
    {
        this.width = width;
        this.height = height;
        A = new T[height, width];
    }

    /* 余りを設定 */
    public static void SetMod(long m)
    {
        mod = m;
    }

    /* 行列を標準出力に出力 */
    public void Show()
    {
        for (int i = 0; i < height; i++)
        {
            for (int j = 0; j < width; j++)
            {
                Console.Write("{0} ", A[i, j]);
            }
            Console.WriteLine("\b");
        }
    }

    /* n×nの単位行列を作り、返す */
    public static Matrix<T> E(int n)
    {
        Matrix<T> E = new Matrix<T>(n, n);
        for (int i = 0; i < n; i++)
            E[i, i] = (dynamic)1;
        return E;
    }

    /* A => -A */
    public static Matrix<T> operator -(Matrix<T> A)
    {
        for (int i = 0; i < A.height; i++)
            for (int j = 0; j < A.width; j++)
                A[i, j] *= (dynamic)(-1);
        return A;
    }

    /* A => +A */
    public static Matrix<T> operator +(Matrix<T> A)
    {
        return A;
    }

    /* (A,B) => A + B */
    public static Matrix<T> operator +(Matrix<T> A, Matrix<T> B)
    {
        if (A.width != B.width || A.height != B.height)
            throw new ArithmeticException();
        Matrix<T> C = new Matrix<T>(A.width, B.width);
        for (int i = 0; i < A.height; i++)
            for (int j = 0; j < A.width; j++)
                C[i, j] = ((dynamic)A[i, j] + (dynamic)B[i, j]) % (dynamic)mod;
        return C;
    }

    /* (A,B) => A - B */
    public static Matrix<T> operator -(Matrix<T> A, Matrix<T> B)
    {
        return A + (-B);
    }

    /* (A,B) => A * B */
    public static Matrix<T> operator *(Matrix<T> A, Matrix<T> B)
    {
        if (A.width != B.height)
            throw new ArithmeticException();
        int n = A.height;
        int m = B.width;
        int p = A.width;
        Matrix<T> C = new Matrix<T>(n, m);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                for (int k = 0; k < p; k++)
                    C[i, j] = ((dynamic)C[i, j] + (dynamic)A[i, k] * (dynamic)B[k, j]) % (dynamic)mod;
        return C;
    }

    /* thisをk乗する */
    public void Pow(long k)
    {
        if (k < 0)
            throw new ArithmeticException();
        this = Pow(this, k);
    }

    /* (A,k) => A^k (kは整数) */
    public static Matrix<T> Pow(Matrix<T> A, long k)
    {
        if (A.width != A.height)
            throw new ArithmeticException();
        if (k < 0)
            throw new ArithmeticException();
        if (k == 0)
            return E(A.width);
        Matrix<T> t = Pow(A, k / 2);
        if (k % 2 == 0)
            return t * t;
        return t * t * A;
    }
}

Measured memory_bytes: 31500