#include <iostream>
#include <vector>
#include <cmath>
#include <thread>
using namespace std;
const int MAXN = 200005;
const int LOGN = 20;
int n, m, q;
vector<int> edges[MAXN];
int digits[MAXN];
int up[MAXN][LOGN];
int depth[MAXN];
int len_u[MAXN];
int f[MAXN];
int pow10[MAXN];
void dfs(int u, int p) {
up[u][0] = p;
for (int k = 1; k < LOGN; ++k) {
up[u][k] = up[up[u][k - 1]][k - 1];
}
if (p == 0) {
f[u] = digits[u] % m;
len_u[u] = 1;
depth[u] = 0;
} else {
f[u] = (1LL * f[p] * 10 + digits[u]) % m;
len_u[u] = len_u[p] + 1;
depth[u] = depth[p] + 1;
}
for (int v : edges[u]) {
if (v != p) {
dfs(v, u);
}
}
}
int lca(int u, int v) {
if (depth[u] < depth[v]) swap(u, v);
for (int k = LOGN - 1; k >= 0; --k) {
if (depth[u] - (1 << k) >= depth[v]) {
u = up[u][k];
}
}
if (u == v) return u;
for (int k = LOGN - 1; k >= 0; --k) {
if (up[u][k] != up[v][k]) {
u = up[u][k];
v = up[v][k];
}
}
return up[u][0];
}
void solve() {
cin >> n >> m >> q;
for (int i = 0; i < n - 1; ++i) {
int x, y;
cin >> x >> y;
edges[x].emplace_back(y);
edges[y].emplace_back(x);
}
for (int i = 1; i <= n; ++i) {
char c;
cin >> c;
digits[i] = c - '0';
}
pow10[0] = 1 % m;
for (int i = 1; i <= n; ++i) {
pow10[i] = (1LL * pow10[i - 1] * 10) % m;
}
dfs(1, 0);
while (q--) {
int a, b;
cin >> a >> b;
int L = lca(a, b);
int len1 = len_u[a];
int len2 = len_u[b] - len_u[L];
int num1 = f[a];
int num2 = (f[b] - (1LL * f[L] * pow10[len_u[b] - len_u[L]]) % m + m) % m;
int result = (1LL * num1 * pow10[len2] + num2) % m;
cout << result << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Using a thread to increase the stack size
thread t(solve);
t.join();
return 0;
}