#pragma GCC optimize("O3")
#pragma GCC target("avx512vl,avx512dq")
#include "circuit.h"
#include <algorithm>
#include <array>
#include <cassert>
#include <vector>
constexpr int mod = 1e9 + 2022;
int add(int a, int b) {
return a + b - mod * (a + b >= mod);
}
int mul(int a, int b) {
return a * 1ULL * b % mod;
}
int n, m;
std::vector<int> prv;
std::vector<int> data;
std::vector<int> all;
std::vector<int> shit;
std::vector<std::vector<int>> nxt;
// void count() {
// for (int i = n - 1; i >= 0; i--) {
// int all = 1, sum = 0;
// for (int id = 0; id < nxt[i].size(); id++) {
// int t = nxt[i][id];
// int s = dp[t][0];
// sum = add(mul(sum, s), mul(all, dp[t][1]));
// all = mul(all, s);
// }
// all = mul(all, nxt[i].size());
// dp[i] = {all, sum};
// }
// }
void init(int n, int m, std::vector<int> P, std::vector<int> A) {
::n = n;
::m = m;
data = A;
prv = P;
all.assign(n + m, 1);
nxt.resize(n);
for (int i = 1; i < n + m; i++) {
nxt[prv[i]].push_back(i);
}
for (int i = n - 1; i >= 0; i--) {
int& s = all[i];
for (int t : nxt[i]) {
s = mul(s, all[t]);
}
s = mul(s, nxt[i].size());
}
shit.assign(m, 0);
auto fuck = [&](auto fuck, int i, int val) {
if (i >= n) {
shit[i - n] = val;
return;
}
int g = nxt[i].size();
std::vector<int> prf(g + 1, 1), suf(g + 1, 1);
for (int j = 0; j < g; j++) {
prf[j + 1] = mul(prf[j], all[nxt[i][j]]);
suf.rbegin()[j + 1] = mul(suf.rbegin()[j], all[nxt[i].rbegin()[j]]);
}
for (int j = 0; j < g; j++) {
int t = nxt[i][j];
fuck(fuck, t, mul(val, mul(prf[j], suf[j + 1])));
}
};
fuck(fuck, 0, 1);
}
int count_ways(int L, int R) {
L -= n;
R -= n;
R++;
for (int i = L; i < R; i++) {
data[i] ^= 1;
}
int64_t sum = 0;
for (int i = 0; i < m; i++) {
sum += shit[i] * bool(data[i]);
}
sum %= mod;
return sum;
}