import java.io.*;
import java.util.Arrays;
import java.util.Locale;
import java.util.StringTokenizer;
public class TaskE {
private final InputReader reader;
private final OutputWriter writer;
public TaskE(InputReader reader, OutputWriter writer) {
this.reader = reader;
this.writer = writer;
}
public static void main
(String[] args
) { InputReader reader
= new InputReader
(System.
in); OutputWriter writer
= new OutputWriter
(System.
out); new TaskE(reader, writer).run();
writer.writer.flush();
}
int[] L;
int[][] LT;
int[] deg2;
int lcp(int a, int b) {
if (a > b) {
int t = a;
a = b;
b = t;
}
if (a == b)
throw new AssertionError();
int k = deg2[b - a];
return Math.
min(LT
[k
][a
], LT
[k
][b
- (1 << k
)]); }
void buildSuffixArray(char[] S) {
int n = S.length;
int[] P, nP, eq, neq, cnt;
P = new int[n];
nP = new int[n];
cnt
= new int[Math.
max(28, n
)]; eq = new int[n];
neq = new int[n];
for (int i = 0; i < n; i++)
cnt[S[i] - 'a']++;
for (int i = 1; i < 28; i++)
cnt[i] += cnt[i - 1];
for (int i = n - 1; i >= 0; i--) {
P[--cnt[S[i] - 'a']] = i;
eq[i] = S[i] - 'a';
}
int mx = 28;
for (int k = 1; k < n && (k == 1 || mx != n); k <<= 1) {
for (int i = 0; i < n; i++)
P[i] = (P[i] >= k) ? P[i] - k : P[i] - k + n;
for (int i = 0; i < n; i++)
cnt[eq[P[i]]]++;
for (int i = 1; i < mx; i++)
cnt[i] += cnt[i - 1];
for (int i = n - 1; i >= 0; i--)
nP[--cnt[eq[P[i]]]] = P[i];
neq[nP[0]] = 0;
for (int i = 1; i < n; i++)
neq[nP[i]] = neq[nP[i - 1]] + ((eq[nP[i]] != eq[nP[i - 1]] ||
eq[(nP[i] + k < n) ? nP[i] + k : nP[i] + k - n] !=
eq[(nP[i - 1] + k < n) ? nP[i - 1] + k : nP[i - 1] + k - n]) ? 1 : 0);
mx = neq[nP[n - 1]] + 1;
for (int i = 0; i < n; i++) {
P[i] = nP[i];
eq[i] = neq[i];
}
}
L = new int[n];
int[] IP = new int[n];
for (int i = 0; i < n; i++)
IP[P[i]] = i;
int cur = 0;
for (int i = 0; i < n; i++) {
if (IP[i] + 1 != n) {
int a = i, b = P[IP[i] + 1];
while (S[a + cur] == S[b + cur])
cur++;
L[IP[a]] = cur;
}
cur
= Math.
max(cur
- 1,
0); }
deg2 = new int[n + 1];
deg2[0] = -42;
deg2[1] = 0;
for (int i = 2; i <= n; i++)
deg2[i] = 1 + deg2[i >> 1];
LT = new int[deg2[n] + 1][n];
for (int i = 0; i < n; i++)
LT[0][i] = L[i];
for (int l = 1; l <= deg2[n]; l++)
for (int i = 0; i + (1 << l) <= n; i++)
LT
[l
][i
] = Math.
min(LT
[l
- 1][i
], LT
[l
- 1][i
+ (1 << (l
- 1))]); SA = P;
ISA = IP;
}
class Event implements Comparable
<Event
> { int t;
int id;
int a, b;
Event(int t,
int id,
int a,
int b
) { this.t = t;
this.a = a;
this.b = b;
this.id = id;
}
@Override
public int compareTo
(Event other
) { return Integer.
compare(this.
t, other.
t); }
}
int[] SA, ISA;
int[] beg;
int[] len;
int[] color;
int ept = 0;
void addQuery(int a, int b, int k, int id) {
int ln = len[k];
k = ISA[beg[k]];
int l = -1, r = k;
while (r - l > 1) {
int m = (l + r) / 2;
if (lcp(m, k) < ln)
l = m;
else
r = m;
}
int L = r;
l = k;
r = SA.length;
while (r - l > 1) {
int m = (l + r) / 2;
if (lcp(k, m) < ln)
r = m;
else
l = m;
}
int R = l;
E
[ept
++] = new Event(L
- 1, ~id, a, b
); E
[ept
++] = new Event(R, id, a, b
); }
int[] F;
void inc(int x) {
for(; x < F.length; x |= x + 1)
F[x]++;
}
int get(int x) {
int ans = 0;
for (; x >= 0; x &= x + 1, --x)
ans += F[x];
return ans;
}
public void run() {
int n = reader.nextInt();
int q = reader.nextInt();
char[] S = new char[1000 * 1000 + 42];
beg = new int[n];
len = new int[n];
int pt = 0;
for (int i = 0; i < n; i++) {
char[] T = reader.next().toCharArray();
len[i] = T.length;
beg[i] = pt;
for (int j = 0; j < T.length; j++) {
S[pt + j] = T[j];
}
pt += T.length;
S[pt++] = 'z' + 1;
}
S[pt++] = 'z' + 2;
color = new int[pt];
pt = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < len[i]; j++)
color[pt + j] = i;
pt += len[i] + 1;
}
buildSuffixArray(S);
/*for (int i = 0; i < pt; i++)
writer.printf("%2d %2d %s\n", SA[i], L[i], String.valueOf(S, SA[i], pt - SA[i]));
writer.printf("\n");
writer.writer.flush();*/
for (int i = 0; i < q; i++) {
int l = reader.nextInt() - 1;
int r = reader.nextInt() - 1;
int k = reader.nextInt() - 1;
addQuery(l, r, k, i);
}
F = new int[n];
int[] ans = new int[q];
int cpt = 0;
while (cpt <= e.t) {
inc(color[SA[cpt]]);
cpt++;
}
int id = e.id;
int mul = (id >= 0) ? 1 : -1;
id = (id >= 0) ? id : ~id;
int a = e.a;
int b = e.b;
ans[id] += mul * (get(b) - get(a - 1));
}
for (int a : ans)
writer.printf("%d\n", a);
}
static class InputReader {
tokenizer = null;
}
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
}
}
return tokenizer.nextToken();
}
public int nextInt() {
}
public double nextDouble() {
return Double.
parseDouble(next
()); }
public long nextLong() {
return Long.
parseLong(next
()); }
}
static class OutputWriter {
}
}
}
}
aW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEudXRpbC5BcnJheXM7CmltcG9ydCBqYXZhLnV0aWwuTG9jYWxlOwppbXBvcnQgamF2YS51dGlsLlN0cmluZ1Rva2VuaXplcjsKCnB1YmxpYyBjbGFzcyBUYXNrRSB7CiAgICBwcml2YXRlIGZpbmFsIElucHV0UmVhZGVyIHJlYWRlcjsKICAgIHByaXZhdGUgZmluYWwgT3V0cHV0V3JpdGVyIHdyaXRlcjsKCiAgICBwdWJsaWMgVGFza0UoSW5wdXRSZWFkZXIgcmVhZGVyLCBPdXRwdXRXcml0ZXIgd3JpdGVyKSB7CiAgICAgICAgdGhpcy5yZWFkZXIgPSByZWFkZXI7CiAgICAgICAgdGhpcy53cml0ZXIgPSB3cml0ZXI7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyB2b2lkIG1haW4oU3RyaW5nW10gYXJncykgewogICAgICAgIElucHV0UmVhZGVyIHJlYWRlciA9IG5ldyBJbnB1dFJlYWRlcihTeXN0ZW0uaW4pOwogICAgICAgIE91dHB1dFdyaXRlciB3cml0ZXIgPSBuZXcgT3V0cHV0V3JpdGVyKFN5c3RlbS5vdXQpOwogICAgICAgIG5ldyBUYXNrRShyZWFkZXIsIHdyaXRlcikucnVuKCk7CiAgICAgICAgd3JpdGVyLndyaXRlci5mbHVzaCgpOwogICAgfQoKICAgIGludFtdIEw7CiAgICBpbnRbXVtdIExUOwogICAgaW50W10gZGVnMjsKCiAgICBpbnQgbGNwKGludCBhLCBpbnQgYikgewogICAgICAgIGlmIChhID4gYikgewogICAgICAgICAgICBpbnQgdCA9IGE7CiAgICAgICAgICAgIGEgPSBiOwogICAgICAgICAgICBiID0gdDsKICAgICAgICB9CiAgICAgICAgaWYgKGEgPT0gYikKICAgICAgICAgICAgdGhyb3cgbmV3IEFzc2VydGlvbkVycm9yKCk7CiAgICAgICAgaW50IGsgPSBkZWcyW2IgLSBhXTsKICAgICAgICByZXR1cm4gTWF0aC5taW4oTFRba11bYV0sIExUW2tdW2IgLSAoMSA8PCBrKV0pOwogICAgfQoKICAgIHZvaWQgYnVpbGRTdWZmaXhBcnJheShjaGFyW10gUykgewogICAgICAgIGludCBuID0gUy5sZW5ndGg7CiAgICAgICAgaW50W10gUCwgblAsIGVxLCBuZXEsIGNudDsKICAgICAgICBQID0gbmV3IGludFtuXTsKICAgICAgICBuUCA9IG5ldyBpbnRbbl07CiAgICAgICAgY250ID0gbmV3IGludFtNYXRoLm1heCgyOCwgbildOwogICAgICAgIGVxID0gbmV3IGludFtuXTsKICAgICAgICBuZXEgPSBuZXcgaW50W25dOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgICAgICAgICBjbnRbU1tpXSAtICdhJ10rKzsKICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IDI4OyBpKyspCiAgICAgICAgICAgIGNudFtpXSArPSBjbnRbaSAtIDFdOwogICAgICAgIGZvciAoaW50IGkgPSBuIC0gMTsgaSA+PSAwOyBpLS0pIHsKICAgICAgICAgICAgUFstLWNudFtTW2ldIC0gJ2EnXV0gPSBpOwogICAgICAgICAgICBlcVtpXSA9IFNbaV0gLSAnYSc7CiAgICAgICAgfQogICAgICAgIGludCBteCA9IDI4OwogICAgICAgIGZvciAoaW50IGsgPSAxOyBrIDwgbiAmJiAoayA9PSAxIHx8IG14ICE9IG4pOyBrIDw8PSAxKSB7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgICAgICAgICAgICAgUFtpXSA9IChQW2ldID49IGspID8gUFtpXSAtIGsgOiBQW2ldIC0gayArIG47CiAgICAgICAgICAgIEFycmF5cy5maWxsKGNudCwgMCk7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgICAgICAgICAgICAgY250W2VxW1BbaV1dXSsrOwogICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IG14OyBpKyspCiAgICAgICAgICAgICAgICBjbnRbaV0gKz0gY250W2kgLSAxXTsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IG4gLSAxOyBpID49IDA7IGktLSkKICAgICAgICAgICAgICAgIG5QWy0tY250W2VxW1BbaV1dXV0gPSBQW2ldOwogICAgICAgICAgICBuZXFbblBbMF1dID0gMDsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPCBuOyBpKyspCiAgICAgICAgICAgICAgICBuZXFbblBbaV1dID0gbmVxW25QW2kgLSAxXV0gKyAoKGVxW25QW2ldXSAhPSBlcVtuUFtpIC0gMV1dIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVxWyhuUFtpXSArIGsgPCBuKSA/IG5QW2ldICsgayA6IG5QW2ldICsgayAtIG5dICE9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVxWyhuUFtpIC0gMV0gKyBrIDwgbikgPyBuUFtpIC0gMV0gKyBrIDogblBbaSAtIDFdICsgayAtIG5dKSA/IDEgOiAwKTsKICAgICAgICAgICAgbXggPSBuZXFbblBbbiAtIDFdXSArIDE7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgICAgICAgICBQW2ldID0gblBbaV07CiAgICAgICAgICAgICAgICBlcVtpXSA9IG5lcVtpXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBMID0gIG5ldyBpbnRbbl07CiAgICAgICAgaW50W10gSVAgPSBuZXcgaW50W25dOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKQogICAgICAgICAgICBJUFtQW2ldXSA9IGk7CiAgICAgICAgaW50IGN1ciA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICAgICAgaWYgKElQW2ldICsgMSAhPSBuKSB7CiAgICAgICAgICAgICAgICBpbnQgYSA9IGksIGIgPSBQW0lQW2ldICsgMV07CiAgICAgICAgICAgICAgICB3aGlsZSAoU1thICsgY3VyXSA9PSBTW2IgKyBjdXJdKQogICAgICAgICAgICAgICAgICAgIGN1cisrOwogICAgICAgICAgICAgICAgTFtJUFthXV0gPSBjdXI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgY3VyID0gTWF0aC5tYXgoY3VyIC0gMSwgMCk7CiAgICAgICAgfQogICAgICAgIGRlZzIgPSBuZXcgaW50W24gKyAxXTsKICAgICAgICBkZWcyWzBdID0gLTQyOwogICAgICAgIGRlZzJbMV0gPSAwOwogICAgICAgIGZvciAoaW50IGkgPSAyOyBpIDw9IG47IGkrKykKICAgICAgICAgICAgZGVnMltpXSA9IDEgKyBkZWcyW2kgPj4gMV07CiAgICAgICAgTFQgPSBuZXcgaW50W2RlZzJbbl0gKyAxXVtuXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKICAgICAgICAgICAgTFRbMF1baV0gPSBMW2ldOwogICAgICAgIGZvciAoaW50IGwgPSAxOyBsIDw9IGRlZzJbbl07IGwrKykKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgKyAoMSA8PCBsKSA8PSBuOyBpKyspCiAgICAgICAgICAgICAgICBMVFtsXVtpXSA9IE1hdGgubWluKExUW2wgLSAxXVtpXSwgTFRbbCAtIDFdW2kgKyAoMSA8PCAobCAtIDEpKV0pOwogICAgICAgIFNBID0gUDsKICAgICAgICBJU0EgPSBJUDsKICAgIH0KCiAgICBjbGFzcyBFdmVudCBpbXBsZW1lbnRzIENvbXBhcmFibGU8RXZlbnQ+IHsKICAgICAgICBpbnQgdDsKICAgICAgICBpbnQgaWQ7CiAgICAgICAgaW50IGEsIGI7CiAgICAgICAgRXZlbnQoaW50IHQsIGludCBpZCwgaW50IGEsIGludCBiKSB7CiAgICAgICAgICAgIHRoaXMudCA9IHQ7CiAgICAgICAgICAgIHRoaXMuYSA9IGE7CiAgICAgICAgICAgIHRoaXMuYiA9IGI7CiAgICAgICAgICAgIHRoaXMuaWQgPSBpZDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBjb21wYXJlVG8oRXZlbnQgb3RoZXIpIHsKICAgICAgICAgICAgcmV0dXJuIEludGVnZXIuY29tcGFyZSh0aGlzLnQsIG90aGVyLnQpOwogICAgICAgIH0KICAgIH0KCiAgICBpbnRbXSBTQSwgSVNBOwogICAgaW50W10gYmVnOwogICAgaW50W10gbGVuOwogICAgaW50W10gY29sb3I7CiAgICBFdmVudFtdIEU7CiAgICBpbnQgZXB0ID0gMDsKCiAgICB2b2lkIGFkZFF1ZXJ5KGludCBhLCBpbnQgYiwgaW50IGssIGludCBpZCkgewogICAgICAgIGludCBsbiA9IGxlbltrXTsKICAgICAgICBrID0gSVNBW2JlZ1trXV07CiAgICAgICAgaW50IGwgPSAtMSwgciA9IGs7CiAgICAgICAgd2hpbGUgKHIgLSBsID4gMSkgewogICAgICAgICAgICBpbnQgbSA9IChsICsgcikgLyAyOwogICAgICAgICAgICBpZiAobGNwKG0sIGspIDwgbG4pCiAgICAgICAgICAgICAgICBsID0gbTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgciA9IG07CiAgICAgICAgfQogICAgICAgIGludCBMID0gcjsKICAgICAgICBsID0gazsKICAgICAgICByID0gU0EubGVuZ3RoOwogICAgICAgIHdoaWxlIChyIC0gbCA+IDEpIHsKICAgICAgICAgICAgaW50IG0gPSAobCArIHIpIC8gMjsKICAgICAgICAgICAgaWYgKGxjcChrLCBtKSA8IGxuKQogICAgICAgICAgICAgICAgciA9IG07CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIGwgPSBtOwogICAgICAgIH0KICAgICAgICBpbnQgUiA9IGw7CiAgICAgICAgRVtlcHQrK10gPSBuZXcgRXZlbnQoTCAtIDEsIH5pZCwgYSwgYik7CiAgICAgICAgRVtlcHQrK10gPSBuZXcgRXZlbnQoUiwgaWQsIGEsIGIpOwogICAgfQoKICAgIGludFtdIEY7CiAgICB2b2lkIGluYyhpbnQgeCkgewogICAgICAgIGZvcig7IHggPCBGLmxlbmd0aDsgeCB8PSB4ICsgMSkKICAgICAgICAgICAgRlt4XSsrOwogICAgfQoKICAgIGludCBnZXQoaW50IHgpIHsKICAgICAgICBpbnQgYW5zID0gMDsKICAgICAgICBmb3IgKDsgeCA+PSAwOyB4ICY9IHggKyAxLCAtLXgpCiAgICAgICAgICAgIGFucyArPSBGW3hdOwogICAgICAgIHJldHVybiBhbnM7CiAgICB9CgogICAgcHVibGljIHZvaWQgcnVuKCkgewogICAgICAgIGludCBuID0gcmVhZGVyLm5leHRJbnQoKTsKICAgICAgICBpbnQgcSA9IHJlYWRlci5uZXh0SW50KCk7CiAgICAgICAgY2hhcltdIFMgPSBuZXcgY2hhclsxMDAwICogMTAwMCArIDQyXTsKICAgICAgICBiZWcgPSBuZXcgaW50W25dOwogICAgICAgIGxlbiA9IG5ldyBpbnRbbl07CiAgICAgICAgaW50IHB0ID0gMDsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgICAgICBjaGFyW10gVCA9IHJlYWRlci5uZXh0KCkudG9DaGFyQXJyYXkoKTsKICAgICAgICAgICAgbGVuW2ldID0gVC5sZW5ndGg7CiAgICAgICAgICAgIGJlZ1tpXSA9IHB0OwogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IFQubGVuZ3RoOyBqKyspIHsKICAgICAgICAgICAgICAgIFNbcHQgKyBqXSA9IFRbal07CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcHQgKz0gVC5sZW5ndGg7CiAgICAgICAgICAgIFNbcHQrK10gPSAneicgKyAxOwogICAgICAgIH0KICAgICAgICBTW3B0KytdID0gJ3onICsgMjsKICAgICAgICBTID0gQXJyYXlzLmNvcHlPZihTLCBwdCk7CiAgICAgICAgY29sb3IgPSBuZXcgaW50W3B0XTsKICAgICAgICBwdCA9IDA7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspIHsKICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPCBsZW5baV07IGorKykKICAgICAgICAgICAgICAgIGNvbG9yW3B0ICsgal0gPSBpOwogICAgICAgICAgICBwdCArPSBsZW5baV0gKyAxOwogICAgICAgIH0KCiAgICAgICAgYnVpbGRTdWZmaXhBcnJheShTKTsKICAgICAgICAvKmZvciAoaW50IGkgPSAwOyBpIDwgcHQ7IGkrKykKICAgICAgICAgICAgd3JpdGVyLnByaW50ZigiJTJkICUyZCAlc1xuIiwgU0FbaV0sIExbaV0sIFN0cmluZy52YWx1ZU9mKFMsIFNBW2ldLCBwdCAtIFNBW2ldKSk7CiAgICAgICAgd3JpdGVyLnByaW50ZigiXG4iKTsKICAgICAgICB3cml0ZXIud3JpdGVyLmZsdXNoKCk7Ki8KCgogICAgICAgIEUgPSBuZXcgRXZlbnRbMiAqIHFdOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcTsgaSsrKSB7CiAgICAgICAgICAgIGludCBsID0gcmVhZGVyLm5leHRJbnQoKSAtIDE7CiAgICAgICAgICAgIGludCByID0gcmVhZGVyLm5leHRJbnQoKSAtIDE7CiAgICAgICAgICAgIGludCBrID0gcmVhZGVyLm5leHRJbnQoKSAtIDE7CiAgICAgICAgICAgIGFkZFF1ZXJ5KGwsIHIsIGssIGkpOwogICAgICAgIH0KICAgICAgICBBcnJheXMuc29ydChFKTsKICAgICAgICBGID0gbmV3IGludFtuXTsKICAgICAgICBpbnRbXSBhbnMgPSBuZXcgaW50W3FdOwogICAgICAgIGludCBjcHQgPSAwOwogICAgICAgIGZvciAoRXZlbnQgZSA6IEUpIHsKICAgICAgICAgICAgd2hpbGUgKGNwdCA8PSBlLnQpIHsKICAgICAgICAgICAgICAgIGluYyhjb2xvcltTQVtjcHRdXSk7CiAgICAgICAgICAgICAgICBjcHQrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICBpbnQgaWQgPSBlLmlkOwogICAgICAgICAgICBpbnQgbXVsID0gKGlkID49IDApID8gMSA6IC0xOwogICAgICAgICAgICBpZCA9IChpZCA+PSAwKSA/IGlkIDogfmlkOwogICAgICAgICAgICBpbnQgYSA9IGUuYTsKICAgICAgICAgICAgaW50IGIgPSBlLmI7CiAgICAgICAgICAgIGFuc1tpZF0gKz0gbXVsICogKGdldChiKSAtIGdldChhIC0gMSkpOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCBhIDogYW5zKQogICAgICAgICAgICB3cml0ZXIucHJpbnRmKCIlZFxuIiwgYSk7CiAgICB9CgoKICAgIHN0YXRpYyBjbGFzcyBJbnB1dFJlYWRlciB7CiAgICAgICAgcHVibGljIEJ1ZmZlcmVkUmVhZGVyIHJlYWRlcjsKICAgICAgICBwdWJsaWMgU3RyaW5nVG9rZW5pemVyIHRva2VuaXplcjsKCiAgICAgICAgcHVibGljIElucHV0UmVhZGVyKElucHV0U3RyZWFtIHN0cmVhbSkgewogICAgICAgICAgICByZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKHN0cmVhbSksIDMyNzY4KTsKICAgICAgICAgICAgdG9rZW5pemVyID0gbnVsbDsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBTdHJpbmcgbmV4dCgpIHsKICAgICAgICAgICAgd2hpbGUgKHRva2VuaXplciA9PSBudWxsIHx8ICF0b2tlbml6ZXIuaGFzTW9yZVRva2VucygpKSB7CiAgICAgICAgICAgICAgICB0cnkgewogICAgICAgICAgICAgICAgICAgIHRva2VuaXplciA9IG5ldyBTdHJpbmdUb2tlbml6ZXIocmVhZGVyLnJlYWRMaW5lKCkpOwogICAgICAgICAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBSdW50aW1lRXhjZXB0aW9uKGUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIHJldHVybiB0b2tlbml6ZXIubmV4dFRva2VuKCk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgaW50IG5leHRJbnQoKSB7CiAgICAgICAgICAgIHJldHVybiBJbnRlZ2VyLnBhcnNlSW50KG5leHQoKSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgZG91YmxlIG5leHREb3VibGUoKSB7CiAgICAgICAgICAgIHJldHVybiBEb3VibGUucGFyc2VEb3VibGUobmV4dCgpKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBsb25nIG5leHRMb25nKCkgewogICAgICAgICAgICByZXR1cm4gTG9uZy5wYXJzZUxvbmcobmV4dCgpKTsKICAgICAgICB9CiAgICB9CgogICAgc3RhdGljIGNsYXNzIE91dHB1dFdyaXRlciB7CiAgICAgICAgcHVibGljIFByaW50V3JpdGVyIHdyaXRlcjsKCiAgICAgICAgT3V0cHV0V3JpdGVyKE91dHB1dFN0cmVhbSBzdHJlYW0pIHsKICAgICAgICAgICAgd3JpdGVyID0gbmV3IFByaW50V3JpdGVyKHN0cmVhbSk7CiAgICAgICAgfQoKICAgICAgICBwdWJsaWMgdm9pZCBwcmludGYoU3RyaW5nIGZvcm1hdCwgT2JqZWN0Li4uIGFyZ3MpIHsKICAgICAgICAgICAgd3JpdGVyLnByaW50KFN0cmluZy5mb3JtYXQoTG9jYWxlLkVOR0xJU0gsIGZvcm1hdCwgYXJncykpOwogICAgICAgIH0KICAgIH0KfQoK