#include <iostream>
#include <sstream>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <numeric>
#include <algorithm>
#include <string>
#include <complex>
 
#include <cassert>
#include <cstdlib>
#include <cmath>
#include <cstdio>
#include <cstring>
 
#define REP(i,e) for(int i=0;i<(int)(e);i++)
#define FOR(i,b,e) for(int i=(int)(b);i<(int)(e);i++)
#define ALL(c) (c).begin(), (c).end()
#define EACH(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();++it)
#define RALL(c) (c).rbegin(), (c).rend()
#define ALLA(a,n) ((a)+0), ((a)+n)
 
using namespace std;
 
typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef vector<string> vstring;
typedef vector<double> vdouble;
 
template<class T>void pp(T v,int n){ REP(i,n)cout<<v[i]<< ' ' ; cout << endl; }
template<class T>void pp(T v){ EACH(it,v) cout << *it << ' ' ; cout << endl;  }
template<class T>T& ls(T& a,T b){ if(b<a) a=b; return a; }
template<class T>T& gs(T& a,T b){ if(b>a) a=b; return a; }
inline ll to_i(const string& s){ll n;sscanf(s.c_str(),"%lld",&n);return n;}
inline string to_s(ll n){char buf[32];sprintf(buf,"%lld",n);return string(buf);}

const int N = 4;

ll MOD = 1;

class MInt {
  ll value;
public:
  MInt() : value(0) {}
  MInt(int v) : value(v) { value %= MOD; }
  MInt(ll v) : value(v) { value %= MOD; }
  MInt& operator+=(const MInt &r) {
    value += r.value; if (value > MOD) value -= MOD; return *this;
  }
  MInt& operator-=(const MInt &r) {
    value -= r.value; if (value < 0) value += MOD; return *this;
  }
  MInt& operator*=(const MInt &r) {
    value *= r.value; value %= MOD; return *this;
  }
  MInt& operator/=(const MInt &r) {
    (*this) *= r.inv(); return *this;
  }
  MInt operator+(const MInt &r) const { MInt result = *this; result += r; return result; }
  MInt operator-(const MInt &r) const { MInt result = *this; result -= r; return result; }
  MInt operator*(const MInt &r) const { MInt result = *this; result *= r; return result; }
  MInt operator/(const MInt &r) const { MInt result = *this; result /= r; return result; }
  MInt pow(ll p) const {
    assert(0 <= p);
    MInt result = 1, x = *this;
    for (;p;p >>= 1) {
      if (p & 1) result *= x;
      x *= x;
    }
    return result;
  }
  MInt inv() const { return this->pow(MOD - 2); }
  operator ll() const { return value; }
  
};

template<int N, typename T> class Matrix {
  T value[N][N];
public:
  Matrix() { fill(0); }

  void fill(T t) { REP(i,N) REP(j,N) value[i][j] = t; }
  void identity() { fill(0); REP(i,N) value[i][i] = 1; }
  Matrix<N, T>& operator*=(const Matrix<N, T> &that) {
    Matrix<N, T> tmp;
    tmp.fill(0);
    REP(i,N) REP(j,N) REP(k,N) tmp.value[i][j] += value[i][k] * that.value[k][j];
    *this = tmp;
    return *this;
  }
  Matrix<N, T> operator*(const Matrix<N, T> &that) const {
    Matrix<N, T> result = *this;
    result *= that;
    return result;
  }
  vector<T> operator*(const vector<T> &v) const {
    vector<T> result(N);
    REP(i,N) REP(j,N) result[i] += value[i][j] * v[j];
    return result;
  }
  void set(int i, int j, T val) { value[i][j] = val; }

  Matrix<N, T> pow(ll p) {
    assert(0 <= p);
    Matrix<N, T> result, sq = *this;
    result.identity();
    for (; p; p >>= 1) {
      if (p & 1) result *= sq;
      sq *= sq;
    }
    return result;
  }

  Matrix<N, T>& pow_naive(ll p) {
    Matrix<N, T> a = *this;
    this->identity();
    REP(i,p) (*this) *= a;
    return *this;
  }

  void print() const { REP(i,N) pp(value[i], N); }
};


typedef Matrix<4, MInt> Mat;

ll calc(ll l, ll a, ll b, MInt base) {
  //cout << "in calc: " << l << ' ' << a << ' ' << b << ' ' << base << endl;
  Mat mt;
  mt.set(0, 0, 1);
  mt.set(1, 1, 1);
  mt.set(2, 1, 1);
  mt.set(2, 2, 1);
  mt.set(3, 2, 1);
  mt.set(3, 3, base);
  mt = mt.pow(l);
  
  // Mat naive = mt;

  // cout << "Matrix: before" << endl;
  // mt.print();
  // cout << endl;

  // cout << "Matrix: after" << endl;
  // mt.print();
  // cout << endl;

  // naive.pow_naive(l);
  // cout << "Matrix: after (naive)" << endl;
  // naive.print();
  // cout << endl;
  
  vector<MInt> x = { a, b, a, 0 };
  vector<MInt> result = mt * x;

  // cout << l << ' ' << a << ' ' << b << ' ' << base << endl;
  // cout << "result vector" << endl;
  // pp(result);
  // cout << endl;
  
  // cout << "out calc " << result[3] << endl;  
  return result[3];
}

int main() {
  ll l, a, b, m;
  while (cin >> l >> a >> b >> m) {
    // if ((double) a + b * (l - 1) >= numeric_limits<ll>().max()) {
    //   cout << "INVALID" << endl;
    //   continue;
    // } 
    
    MOD = m;

    // returns max i where s_i < upper
    auto index = [&](ll upper) { return (upper - a - 1) / b; };
    
    ll left = 1;
    ll s_next = 0;
    MInt result = 0;
    const ll s_max = a + b * (l - 1);
    FOR(digit, 1, 20) {
      if (s_next >= l) break;
      ll right = left * 10.0 > s_max + 1 ? s_max + 1 : left * 10;
      ll s_until = min(index(right), l - 1);
      ll len = max(0LL, s_until - s_next + 1);

      // cout << digit << " digits number: " << left << " - " << right << endl;
      // cout << "s: " << s_next << ' ' << s_until << endl;
      // cout << "index, l, a = " << index(right) << ' ' << l << ' ' << a << endl;
      // cout << "s[i]: " << (a + b * s_next) << ' ' << (a + b * s_until) << endl;
      // cout << len << " elements" << endl;
      // cout << "len, digit = " << len << " " << digit << endl;
      // cout << "calc = " << calc(len, MInt(a) + MInt(b) * MInt(s_next), b, left * 10) << endl;
      // cout << endl; 
      result *= MInt(10).pow(len).pow(digit);
      result += calc(len, MInt(a) + MInt(b) * MInt(s_next), b, MInt(left) * MInt(10));
      s_next += len;
      left *= 10;
    }

    cout << result << endl;
  }
}


Measured memory_bytes: 888