#include <bits/stdc++.h>
#define show(x) cerr << #x << " = " << x << endl
using namespace std;
using ll = long long;
using ld = long double;
constexpr ll MOD = 1000000007LL;
template <typename T>
constexpr T INF = numeric_limits<T>::max() / 10;
template <typename Functor>
struct fix_type
{
    Functor functor;
    template <typename... Args>
    decltype(auto) operator()(Args&&... args) const& { return functor(functor, std::forward<Args>(args)...); }
};
template <typename Functor>
fix_type<typename std::decay<Functor>::type> fix(Functor&& functor) { return {std::forward<Functor>(functor)}; }
template <typename Base>
class BinaryIndexedTree
{
private:
    static constexpr int sz(const int n)
    {
        int ans = 1;
        for (; n > ans; ans <<= 1) {}
        return ans;
    }

public:
    using T = typename Base::T;
    using AbelGroup = Base;
    BinaryIndexedTree(const int n) : data_num(n), size(sz(n)), value(size + 1, AbelGroup::id()) { assert(n > 0); }
    T accumulate(const int a) const  // [0,a]
    {
        T sum = AbelGroup::id();
        for (int ind = a + 1; ind > 0;) { sum = op(sum, value[ind]), ind &= ind - 1; }
        return sum;
    }
    T accumulate(const int l, const int r) const { return (l >= r or r > data_num) ? 0 : op(accumulate(r - 1), AbelGroup::inv(l == 0 ? AbelGroup::id() : accumulate(l - 1))); }
    void add(const int a, const T& val)
    {
        for (int ind = a + 1; ind <= size;) { value[ind] = op(value[ind], val), ind += ind & (-ind); }
    }
    void set(const int a, const T& val) { add(a, op(val, AbelGroup::inv(get(a)))); }
    T get(const int a) const { return accumulate(a, a + 1); }
    vector<T> data() const
    {
        vector<T> ans(data_num);
        for (int i = 0; i < data_num; i++) { ans[i] = get(i); }
        return ans;
    }

private:
    const int data_num;
    const int size;
    const AbelGroup op{};
    vector<T> value;
};

template <typename T>
ostream& operator<<(ostream& os, const BinaryIndexedTree<T>& bit)
{
    const auto v = bit.data();
    os << "[";
    for (const auto e : v) { os << e << ","; }
    return (os << "]" << endl);
}

ll P;
struct Sum
{
    using T = ll;
    T operator()(const T& a, const T& b) const { return (a + b) % P; }
    static T inv(const T& a) { return (P - a) % P; }
    static constexpr T id() { return 0; }
};
int main()
{
    while (true) {
        ll A, B;
        cin >> A >> B >> P;
        if (A == 0 and B == 0 and P == 0) { break; }
        const ll NUM = B - A + 1;
        auto dig = [](const ll n) {
            int ans = -1;
            for (ll num = 1; num <= n; ans++, num *= 10) {}
            return ans;
        };
        const int MAXD = dig(B);
        auto lower = [&](const ll n, const int di) {
            ll ans = n;
            for (int i = 0; i < di - dig(n); i++) { ans *= 10; }
            return di == dig(n) ? ans + 1 : ans;
        };
        auto upper = [&](const int dig) {
            ll ans = 1;
            for (int i = 0; i <= dig; i++) { ans *= 10; }
            return min(ans, B + 1);
        };
        BinaryIndexedTree<Sum> bit(NUM);
        for (int i = NUM - 1; i >= 0; i--) {
            const ll num = i + A;
            const int d = dig(num);
            ll sum = 1;
            for (int t = d; t <= MAXD; t++) {
                const ll u = upper(t) - A, l = lower(num, t) - A;
                (sum += bit.accumulate(l, u)) %= P;
            }
            bit.add(i, sum);
        }
        cout << bit.accumulate(NUM - 1) << endl;
    }
    return 0;
}



Measured memory_bytes: 4088