#include<bits/stdc++.h>
#define re register
#define in inline
#define dou long double
using namespace std;
const int N = 1e6 + 10;
const int M = 1e6 + 10;
const int INF = 0x3f3f3f3f;
//const int mod=9882443535;
const dou eps = 1e-5;
int mod;
in int read() {
re int x = 0, f = 0; re char c = getchar();
while (!isdigit(c)) f |= (c == '-'), c = getchar();
while (isdigit(c)) x = (x << 3) + (x << 1) + c - '0', c = getchar();
return f ? -x : x;
}
in void write(re int x) {
if (x < 0) putchar('-'), x = -x;
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
struct edge {
int u, v;
int nx;
}e[M << 2];
int tot, head[N];
int res;
in void add(re int u, re int v) {
e[++tot].u = u;
e[tot].v = v;
e[tot].nx = head[u];
head[u] = tot;
}
int dep[N], fa[N], siz[N], son[N];
int rt;
in void dfs1(re int u, re int f, re int deep) {
//第一个dfs 算出 fa dep size son
//每个点的 父节点 深度 子树大小 重儿子
dep[u] = deep;
fa[u] = f;
siz[u] = 1;
int maxson = -1;
for (re int i = head[u]; i; i = e[i].nx) {
re int v = e[i].v;
if (v == f) continue;//判断回边
dfs1(v, u, deep + 1);
siz[u] += siz[v];
if (siz[v] > maxson) {
son[u] = v;
maxson = siz[v];
}
}
}
int id[N], wt[N], w[N], top[N], idx;
in void dfs2(re int u, re int topf) {
/* 找dfs序, 处理每个链找出 ?顶部
*/
id[u] = ++idx;
wt[id[u]] = u;
top[u] = topf;
if (!son[u]) return;
dfs2(son[u], topf);//先走重儿子
for (re int i = head[u]; i; i = e[i].nx) {
int v = e[i].v;
if (v == fa[u] || v == son[u]) continue;
dfs2(v, v);//走轻边~~
}
}
int jump(int x, int k) {
while (k >= id[x] - id[top[x]] + 1 && x != rt) {
k -= (id[x] - id[top[x]] + 1);
x = fa[top[x]];
}
return wt[id[x] - k];//这个很帅,我靠
}
unsigned int S;
unsigned int get(unsigned int x) {
x ^= x << 13;
x ^= x >> 17;
x ^= x << 5;
return S = x;
}
int n, m;
signed main() {
n = read(); m = read();
cin >> S;
rt = 1;
for (int i = 1; i <= n; i++) {
fa[i] = read();
if (!fa[i]) {
rt = i;
}
else {
add(fa[i],i);
}
}
dfs1(rt, 0, 1);
dfs2(rt, rt);
long long ans = 0;
int lastans = 0;
for (int i = 1; i <= m; i++) {
int x = (get(S) ^ lastans) % n + 1;
int k = (get(S) ^ lastans) % dep[x];
lastans = jump(x, k);
ans ^=(long long) i * lastans;
}
write(ans); putchar(10);
return 0;
}
树链剖分,对了两个点