#include "bits/stdc++.h"
#include<unordered_map>
#pragma warning(disable:4996)
using namespace std;




int mod = 1000000007;
struct Mod {
public:
	int num;
	Mod() : num(0) { ; }
	Mod(long long int n) : num((n % mod + mod) % mod) { ; }
	Mod(int n) : num((n % mod + mod) % mod) { ; }
	operator int() { return num; }
};

Mod operator+(const Mod a, const Mod b) { return Mod((a.num + b.num) % mod); }
Mod operator+(const long long int a, const Mod b) { return Mod(a + b.num); }
Mod operator+(const Mod a, const long long int  b) { return b+a; }
Mod operator++(Mod &a) { return a + Mod(1); }
Mod operator-(const Mod a, const Mod b) { return Mod((mod + a.num - b.num) % mod); }
Mod operator-(const long long int a, const Mod b) { return Mod(a) - b; }
Mod operator--(Mod &a) { return a - Mod(1); }
Mod operator*(const Mod a, const Mod b) { return Mod(((long long)a.num * b.num) % mod); }
Mod operator*(const long long int a, const Mod b) { return Mod(a*b.num); }
Mod operator*(const Mod a, const int b) { return Mod(b)*a; }
Mod operator+=(Mod &a, const Mod b) { return a = a + b; }
Mod operator+=(long long int &a, const Mod b) { return a = a + b; }
Mod operator-=(Mod &a, const Mod b) { return a = a - b; }
Mod operator-=(long long int &a, const Mod b) { return a = a - b; }
Mod operator*=(Mod &a, const Mod b) { return a = a * b; }
Mod operator*=(long long int &a, const Mod b) { return a = a * b; }
Mod operator^(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = (a * a) ^ (n / 2);
	if (n % 2) res = res * a;
	return res;
}
Mod mod_pow(const Mod a, const int n) {
	if (n == 0) return Mod(1);
	Mod res = mod_pow((a * a), (n / 2));
	if (n % 2) res = res * a;
	return res;
}
Mod inv(const Mod a) { return a ^ (mod - 2); }
Mod operator/(const Mod a, const Mod b) {
	assert(b.num != 0);
	return a * inv(b);
}
Mod operator/(const long long int a, const Mod b) {
	assert(b.num != 0);
	return Mod(a) * inv(b);
}
Mod operator/=(Mod &a, const Mod b) {
	assert(b.num != 0);
	return a = a * inv(b);
}

#define MAX_MOD_N 1024000

Mod fact[MAX_MOD_N], factinv[MAX_MOD_N];
void init() {
	fact[0] = Mod(1); factinv[0] = 1;
	for (int i = 0; i < MAX_MOD_N - 1; ++i) {
		fact[i + 1] = fact[i] * Mod(i + 1);
		factinv[i + 1] = factinv[i] / Mod(i + 1);
	}
}
Mod comb(const int a, const int b) {
	return fact[a] * factinv[b] * factinv[a - b];
}


#define Seg_Max_N (1<<18) 
// update(l,r,v) := [l,r]の区間に対してvを一様に足す. k,a,bは飾り

struct NODE {
	long long int sum;//更新された値. この値を参照する時は評価が完全に完了しているようにする.
	long long int lazy;	//遅延されている値を保存している
	NODE() {
		sum = lazy = 0;
	}
};

NODE seg[2 * Seg_Max_N];

// inlineつけないと大変なことになるよ!(遅い)
inline void lazy_evaluate_node(int k, int a, int b) {
	seg[k].sum += seg[k].lazy * (b - a + 1);
	seg[k].sum %= mod;
	if (k < Seg_Max_N) { // 2*k(左の子番号) < 2*N (節点の数) のイメージで. 末端ノードじゃなきゃ伝搬するのと等価.
		seg[2 * k].lazy += seg[k].lazy;	//次は君が伝搬してね☆って感じ.
		seg[2 * k].lazy %= mod;
		seg[2 * k + 1].lazy += seg[k].lazy;
		seg[2 * k+1].lazy %= mod;
	}
	seg[k].lazy = 0;
}

inline void update_node(int k) { // kの子が既に評価されていることが前提. 末端以外のときしか呼び出さないような位置に書くのでif文要らない.
	seg[k].sum = seg[2 * k].sum + seg[2 * k + 1].sum;
	seg[k].sum %= mod;
}

// update(l,r,v) := [l,r]を更新する. 区間は1-indexed.
void update(int l, int r, int v, int k = 1, int a = 1, int b = Seg_Max_N) {
	if (l < 0 || r<0)assert(false);
	lazy_evaluate_node(k, a, b); 	// とりあえず辿ったノードは都合がいいので伝搬しとけ精神.

	if (b < l || r < a) //[a,b]と[l,r]が交差している場合
		return;
	if (l <= a && b <= r) { // [l,r]が[a,b]を完全に含んでいる場合
		seg[k].lazy += v;
		seg[k].lazy %= mod;
		lazy_evaluate_node(k, a, b); //一回遅延評価しとかないと都合悪いので.
		return;
	}

	int m = (a + b) / 2;
	update(l, r, v, 2 * k, a, m);
	update(l, r, v, 2 * k + 1, m + 1, b);
	update_node(k);
}

// get(l,r) := [l,r]に対するクエリの答えを得る. 区間は1-indexed.
long long int get(int l, int r, int k = 1, int a = 1, int b = Seg_Max_N) {
	if (l < 0 || r<0)assert(false);
	lazy_evaluate_node(k, a, b); // とりあえず辿ったノードは都合がいいので伝搬しとけ精神.

	if (b < l || r < a) //[a,b]と[l,r]が交差している場合
		return 0;

	if (l <= a && b <= r) { // [l,r]が[a,b]を完全に含んでいる場合
		return seg[k].sum;
	}

	int m = (a + b) / 2;
	Mod vl = get(l, r, 2 * k, a, m);
	Mod vr = get(l, r, 2 * k + 1, m + 1, b);
	update_node(k);
	return vl + vr;
}

long long int powint(long long int a, long long int b) {
	assert(b >= 0);
	if (b == 0)return 1;
	if (b == 1)return a;
	long long int ans = 1;
	long long int aa = powint(a, b / 2);
	ans *= aa*aa;
	if (b % 2)ans *= a;
	return ans;
}

int main() {
	while (1) {
		for (int i = 0; i < 2 * Seg_Max_N; ++i) {
			seg[i].lazy = 0;
			seg[i].sum = 0;
		}
		long long int A, B, P; cin >> A >> B >> P;
		if (!A)break;
		mod = P;
		update(1, B - A+1,1);

		for (int id = 0; id < B - A; ++id) {
			long long int num = id + A;
			long long int adp = get(id+1, id+1);
			long long int now = num;
			int keta= (to_string(now).size());
			while (1) {
				long long int amin = now;
				long long int amax = min(powint(10, keta) - 1, B);
				if (amin > amax)break;
				if (amin == num)amin++;
				
				update(amin-A+1, amax - A+1, adp);
				now = now * 10;
				keta++;
			}
		}
		Mod ans = get(1, B - A + 1);
		cout << ans << endl;

	}
	return 0;
}

Measured memory_bytes: 19468