#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
#define REP(i,n) for(int i=0,_n=(int)(n);i<_n;++i)
#define ALL(v) (v).begin(),(v).end()
#define CLR(t,v) memset(t,(v),sizeof(t))
template<class T1,class T2>ostream& operator<<(ostream& os,const pair<T1,T2>&a){return os<<"("<<a.first<<","<<a.second<< ")";}
template<class T>void pv(T a,T b){for(T i=a;i!=b;++i)cout<<(*i)<<" ";cout<<endl;}
template<class T>void chmin(T&a,const T&b){if(a>b)a=b;}
template<class T>void chmax(T&a,const T&b){if(a<b)a=b;}

ll MOD;

#define SZ(v) ((int)(v).size())
typedef vector<ll> Array;
typedef vector<Array> Matrix;

Matrix zero(int N){ return Matrix(N, Array(N)); }

Matrix identity(int N) {
  Matrix A = zero(N);
  REP(i, N) A[i][i] = 1;
  return A;
}

Array mul(const Matrix &A, const Array &x){
  const int N = SZ(A);
  const int M = SZ(A[0]);
  Array y(N);
  REP(i, N) REP(j, M) {
    y[i] += A[i][j] * x[j];
    y[i] %= MOD;
  }
  return y;
}

Matrix mul(const Matrix &A, const Matrix& B) {
  const int N = SZ(A);
  const int P = SZ(A[0]);
  const int M = SZ(B[0]);
  Matrix C(N, Array(M));
  REP(i, N) REP(j, M) REP(k, P) {
    C[i][j] += A[i][k] * B[k][j];
    if (C[i][j] >= MOD) C[i][j] %= MOD;
  }
  return C;
}

Matrix pow(Matrix A, ll b) {
  Matrix C = identity(SZ(A));
  while (b > 0) {
    if ((b & 1) == 1) C = mul(C, A);
    A = mul(A, A);
    b >>= 1;
  }
  return C;
}

void print(const Matrix& A){
  REP(i, SZ(A)){
    REP(j, SZ(A[0])){
      cout << A[i][j] << " ";
    }
    cout << endl;
  }
  cout << "---------------------" << endl;
}


ll mod_pow(ll a, ll b, ll p) {
  ll res = 1;
  while (b > 0) {
    if (b & 1) res = (res * a) % p;
    a = (a * a) % p;
    b >>= 1;
  }
  return res;
}


int getKeta(ll x) {
  int res = 0;
  while (x > 0) {
    x /= 10;
    res++;
  }
  return res;
}

// k 桁になる要素の添え字の両端の添え字
pair<ll,ll> ketaRange(ll A, ll B, ll L, int k) {
  ll lb, ub;
  {
    ll lo = -1;
    ll hi = L;
    while (hi - lo > 1) {
      ll mid = (hi + lo) / 2;
      int keta = getKeta(A + B * mid);
      if (keta < k) { lo = mid; } else { hi = mid; }
    }
    lb = hi;
  }
  {
    ll lo = -1;
    ll hi = L;
    while (hi - lo > 1) {
      ll mid = (hi + lo) / 2;
      int keta = getKeta(A + B * mid);
      if (keta <= k) { lo = mid; } else { hi = mid; }
    }
    ub = hi;
  }
  return {lb, ub};
}

ll solve(ll A, ll B, ll L) {
  ll res = 0;
  for (int k = 1; k <= 18; k++) {
    ll from, to;
    tie(from,to) = ketaRange(A, B, L, k);
    ll n = to - from;
    if (n == 0) continue;
    // cout << k << ":" << from << " " << to << endl;
    const ll TEN = pow(10, k);

    Matrix M = zero(3);
    M[0][0] = TEN; M[0][1] = 1;
    M[1][1] = 1; M[1][2] = 1;
    M[2][2] = 1;
    Array b = Array({0, A+from*B, B});

    REP(i, 3) REP(j, 3) M[i][j] %= MOD;
    REP(i, b.size()) b[i] %= MOD;

    M = pow(M, n);
    Array R = mul(M, b);
    // cout << "k=" << k << ", n="<< n << ", res=" << R[0] << endl;
    res = (res * mod_pow(TEN % MOD, n, MOD) % MOD + (R[0] % MOD)) % MOD;
  }
  return res;
}

int main2() {
  ll L, A, B;
  cin >> L >> A >> B >> MOD;
  ll ans = solve(A, B, L);
  cout << ans << endl;
  return 0;
}

int main() {
  // ll A = 1;
  // ll B = 170;
  // ll L = 30;
  // REP(i, L) {
  //   ll s = A + B * i;
  //   cout << getKeta(s) << " " << s << endl;
  // }
  // for (int k = 1; k <= 10; k++) {
  //   cout << k << ":" << ketaRange(A, B, L, k) << endl;
  // }
  // return 0;

#ifdef LOCAL
  for (;!cin.eof();cin>>ws)
#endif
    main2();
  return 0;
}


Measured memory_bytes: 256