using System;
using static System.Console;
using System.Linq;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Runtime.Intrinsics.X86;
class Program
{
static int NN => int.Parse(ReadLine());
static long[] NList => ReadLine().Split().Select(long.Parse).ToArray();
public static void Main()
{
Solve();
}
static void Solve()
{
var c = NList;
var (n, m, q) = ((int)c[0], (int)c[1], (int)c[2]);
var s = ReadLine();
var k = NList;
WriteLine(string.Join(" ", Suffix(n, m, q, s, k)));
}
static long[] Suffix(int n, long m, int q, string s, long[] k)
{
var h1 = new StringHash(SHI.H1, s);
var h2 = new StringHash(SHI.H2, s);
for (var i = 1; i < n; ++i)
{
if (n % i == 0)
{
var sh1 = h1.GetHash(0, i - 1);
var sh2 = h2.GetHash(0, i - 1);
var flg = true;
for (var j = i; j < n; j += i)
{
var nsh1 = h1.GetHash(j, j + i - 1);
var nsh2 = h2.GetHash(j, j + i - 1);
if (sh1 != nsh1 || sh2 != nsh2)
{
flg = false;
break;
}
}
if (flg)
{
s = s[0..i];
m *= n / i;
n = i;
break;
}
}
}
return SuffixImpl(n, m, q, s, k);
}
static long[] SuffixImpl(int n, long m, int q, string s, long[] k)
{
var t = s + s;
var sa = SuffixArray(t);
var list = new List<(int pos, long min, long max)>(sa.Length);
var offset = 1L;
for (var i = 0; i < sa.Length; ++i)
{
if (sa[i] >= n)
{
list.Add((sa[i], offset, offset));
++offset;
}
else
{
list.Add((sa[i], offset, offset + m - 2));
offset += m - 1;
}
}
var qlist = new List<(int id, long k)>(q);
for (var i = 0; i < q; ++i) qlist.Add((i, k[i]));
qlist.Sort((l, r) => l.k.CompareTo(r.k));
var ans = new long[q];
var pos = 0;
foreach (var qi in qlist)
{
while (list[pos].max < qi.k) ++pos;
if (list[pos].pos >= n)
{
ans[qi.id] = list[pos].pos + (m - 2L) * n + 1;
}
else
{
ans[qi.id] = list[pos].pos + (list[pos].max - qi.k) * n + 1;
}
}
return ans;
}
public class SHI
{
public static SHI H1 = new SHI(29, 998_244_391, 722_866_628);
public static SHI H2 = new SHI(31, 998_244_397, 193_208_593);
public int Mul;
public int Mod;
public int Rev;
public SHI(int mul, int mod, int rev)
{
Mul = mul; Mod = mod; Rev = rev;
}
}
/// 部分文字列に対するハッシュコードを計算する
class StringHash
{
int mul;
int mod;
long[] pow;
long[] rev;
// ここをFenwicktree等に変更することで、文字列の変更ができる
long[] cum;
// FenwickTree cum;
public StringHash(SHI ini, string s)
{
mul = ini.Mul;
mod = ini.Mod;
pow = new long[s.Length + 1];
rev = new long[s.Length + 1];
pow[0] = 1;
rev[0] = 1;
cum = new long[s.Length + 1];
// cum = new FenwickTree(s.Length + 1);
for (var i = 1; i <= s.Length; ++i)
{
pow[i] = pow[i - 1] * mul % mod;
rev[i] = rev[i - 1] * ini.Rev % mod;
cum[i] = (cum[i - 1] + (s[i - 1] - 'a' + 1) * pow[i]) % mod;
// cum.Add(i, (s[i - 1] - 'a' + 1) * pow[i] % mod);
}
}
/// 部分文字列s[l..r]のハッシュ1を求める l,rは0-based
public int GetHash(int l, int r)
{
if (l > r) return 0;
return (int)((cum[r + 1] + mod - cum[l]) % mod * rev[l] % mod);
}
// public int GetHash(int l, int r)
// {
// if (l > r) return 0;
// return (int)((cum.Sum(r + 1) - cum.Sum(l) + mod) % mod * rev[l] % mod);
// }
}
// s.Substring(i) を辞書順でソートしたときの i のリストを返却する
// O(n)
static int[] SuffixArray(string s)
{
var n = s.Length;
var s2 = new int[n];
for (var i = 0; i < n; ++i) s2[i] = (int)s[i];
return SaIs(s2, 255);
}
// 時間 O(nlogn), 空間 O(n)
static int[] SuffixArray(int[] s)
{
var n = s.Length;
var idx = new List(n);
for (var i = 0; i < n; ++i) idx.Add(i);
idx.Sort((l, r) => s[l].CompareTo(s[r]));
var s2 = new int[n];
var now = 0;
for (var i = 0; i < n; ++i)
{
if (i > 0 && s[idx[i - 1]] != s[idx[i]]) ++now;
s2[idx[i]] = now;
}
return SaIs(s2, now);
}
// sに含まれる値が 0 から upper までの間に限られる場合
// O(n + upper)
static int[] SuffixArray(int[] s, int upper)
{
return SaIs(s, upper);
}
// 文字列 s の Suffix Array を並べたとき隣接する項目の Longest Common Path を求める
static int[] LcpArray(string s, int[] sa)
{
var n = s.Length;
var s2 = new int[n];
for (var i = 0; i < n; ++i) s2[i] = (int)s[i];
return LcpArray(s2, sa);
}
static int[] LcpArray(int[] s, int[] sa)
{
var n = s.Length;
var rnk = new int[n];
for (var i = 0; i < n; ++i) rnk[sa[i]] = i;
var lcp = new int[n - 1];
var h = 0;
for (var i = 0; i < n; ++i)
{
if (h > 0) --h;
if (rnk[i] == 0) continue;
var j = sa[rnk[i] - 1];
for (; j + h < n && i + h < n; ++h)
{
if (s[j + h] != s[i + h]) break;
}
lcp[rnk[i] - 1] = h;
}
return lcp;
}
// s と s.Substring(i) の Longest Common Prefix の長さを格納した配列を取得する
static int[] ZAlgorithm(string s)
{
var n = s.Length;
var s2 = new int[n];
for (var i = 0; i < n; ++i) s2[i] = (int)s[i];
return ZAlgorithm(s2);
}
static int[] ZAlgorithm(int[] s)
{
var n = s.Length;
if (n == 0) return new int[] {};
var z = new int[n];
for (int i = 1, j = 0; i < n; ++i)
{
z[i] = (j + z[j] <= i) ? 0 : Math.Min(j + z[j] - i, z[i - j]);
while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
if (j + z[j] < i + z[i]) j = i;
}
z[0] = n;
return z;
}
static int[] SaNaive(int[] s)
{
var n = s.Length;
var sa = new List(n);
for (var i = 0; i < n; ++i)
{
sa.Add(i);
}
sa.Sort((l, r) => {
if (l == r) return 1;
while (l < n && r < n)
{
if (s[l] != s[r]) return s[l] < s[r] ? -1 : 1;
++l;
++r;
}
return l == n ? -1 : 1;
});
return sa.ToArray();
}
static int[] SaDoubling(int[] s)
{
var n = s.Length;
var sa = new List(n);
var rnk = s;
var tmp = new int[n];
for (var i = 0; i < n; ++i) sa.Add(i);
for (var k = 1; k < n; k *= 2)
{
Comparison cmp = (x, y) =>
{
if (rnk[x] != rnk[y]) return rnk[x] < rnk[y] ? -1 : 1;
var rx = x + k < n ? rnk[x + k] : -1;
var ry = y + k < n ? rnk[y + k] : -1;
return rx < ry ? -1 : 1;
};
sa.Sort(cmp);
tmp[sa[0]] = 0;
for (var i = 1; i < n; ++i) tmp[sa[i]] = tmp[sa[i - 1]] + (cmp(sa[i - 1], sa[i]) == -1 ? 1 : 0);
var tmp2 = tmp;
tmp = rnk;
rnk = tmp2;
}
return sa.ToArray();
}
const int THRESHOLD_NAIVE = 10;
const int THRESHOLD_DOUBLING = 40;
static int[] SaIs(int[] s, int upper)
{
var n = s.Length;
if (n == 0) return new int[0];
if (n == 1) return new int[] { 0 };
if (n == 2)
{
if (s[0] < s[1]) return new int[] { 0, 1 };
else return new int[] { 1, 0 };
}
if (n < THRESHOLD_NAIVE) return SaNaive(s);
if (n < THRESHOLD_DOUBLING) return SaDoubling(s);
var sa = new int[n];
var ls = new bool[n];
for (var i = n - 2; i >= 0; --i) ls[i] = (s[i] == s[i + 1]) ? ls[i + 1] : (s[i] < s[i + 1]);
var sumL = new int[upper + 1];
var sumS = new int[upper + 1];
for (var i = 0; i < n; ++i)
{
if (!ls[i]) ++sumS[s[i]];
else ++sumL[s[i] + 1];
}
for (var i = 0; i <= upper; ++i)
{
sumS[i] += sumL[i];
if (i < upper) sumL[i + 1] += sumS[i];
}
Func, int> induce = (List _lms) =>
{
for (var i = 0; i < sa.Length; ++i) sa[i] = -1;
var buf = new int[upper + 1];
Array.Copy(sumS, buf, sumS.Length);
foreach (var d in _lms)
{
if (d == n) continue;
sa[buf[s[d]]++] = d;
}
Array.Copy(sumL, buf, sumL.Length);
sa[buf[s[n - 1]]++] = n - 1;
for (var i = 0; i < n; ++i)
{
var v = sa[i];
if (v >= 1 && !ls[v - 1]) sa[buf[s[v - 1]]++] = v - 1;
}
Array.Copy(sumL, buf, sumL.Length);
for (var i = n - 1; i >= 0; --i)
{
var v = sa[i];
if (v >= 1 && ls[v - 1]) sa[--buf[s[v - 1] + 1]] = v - 1;
}
return 0;
};
var lmsMap = new int[n + 1];
for (var i = 0; i < lmsMap.Length; ++i) lmsMap[i] = -1;
var m = 0;
for (var i = 1; i < n; ++i)
{
if (!ls[i - 1] && ls[i]) lmsMap[i] = m++;
}
var lms = new List(m);
for (var i = 1; i < n; ++i)
{
if (!ls[i - 1] && ls[i]) lms.Add(i);
}
induce(lms);
if (m > 0)
{
var sortedLms = new List(m);
foreach (var v in sa)
{
if (lmsMap[v] != -1) sortedLms.Add(v);
}
var recS = new int[m];
var recUpper = 0;
recS[lmsMap[sortedLms[0]]] = 0;
for (var i = 1; i < m; ++i)
{
var l = sortedLms[i - 1];
var r = sortedLms[i];
var endL = (lmsMap[l] + 1 < m) ? lms[lmsMap[l] + 1] : n;
var endR = (lmsMap[r] + 1 < m) ? lms[lmsMap[r] + 1] : n;
var same = true;
if (endL - l != endR - r) same = false;
else
{
while (l < endL)
{
if (s[l] != s[r]) break;
++l;
++r;
}
same = (l != n && s[l] == s[r]);
}
if (!same) ++recUpper;
recS[lmsMap[sortedLms[i]]] = recUpper;
}
var recSa = SaIs(recS, recUpper);
for (var i = 0; i < m; ++i) sortedLms[i] = lms[recSa[i]];
induce(sortedLms);
}
return sa;
}
// クヌース-モリス-プラット法
static int[] InitKmp(T[] w) where T : IEquatable
{
var result = new int[w.Length];
result[0] = -1;
if (w.Length > 1) result[1] = 0;
var pos = 0;
for (var i = 1; i < result.Length - 1; ++i)
{
if (w[pos].Equals(w[i])) ++pos;
else pos = 0;
result[i + 1] = pos;
}
return result;
}
static int KMPSearch(T[] s, T[] w, int start, int[] subTable) where T : IEquatable
{
var m = start;
var i = 0;
while (m + i < s.Length)
{
if (s[m + i].Equals(w[i]))
{
++i;
if (i == w.Length) return m;
}
else
{
++m;
if (i > 0)
{
m += i - subTable[i];
i = subTable[i];
}
}
}
return -1;
}
}