At least in the Julia version it is pretty simple:

```
using ITensors
N = 10
space_odd = [QN("Podd", 0, 2) => 1, QN("Podd", 1, 2) => 1]
space_even = [QN("Peven", 0, 2) => 1, QN("Peven", 1, 2) => 1]
index_space(n) = isodd(n) ? space_odd : space_even
s = [Index(index_space(n), "Qubit,n=$n") for n in 1:N]
# Alternatively using siteinds
#s_odd = siteinds("Qubit", N÷2; conserve_parity=true, qnname_parity="Podd")
#s_even = siteinds("Qubit", N÷2; conserve_parity=true, qnname_parity="Peven")
#s = collect(Iterators.flatten(zip(s_odd, s_even)))
state_odd = [isodd(n) ? 1 : 2 for n in 1:N÷2]
state_even = [isodd(n) ? 1 : 2 for n in 1:N÷2]
psi0 = productMPS(s, collect(Iterators.flatten(zip(state_odd, state_even))))
function random_gate(s, i, j)
return randomITensor(dag(s[i]), dag(s[j]), s[i]', s[j]')
end
rg = [random_gate(s, i, j) for i in 1:N, j in 1:N]
g1 = [rg[n, n+1] for n in 1:N-1]
g = copy(g1)
nlayers = 8
for _ in 1:nlayers
append!(g, g1)
end
psi = apply(g, psi0)
```

I showed the custom one first to show you that you can really generalize the QNs however you want to, the siteinds version is basically doing the same thing internally but with some hardcoded options for the QNs.