#!/usr/bin/env python3 -I
"""N(lam,nu) = #{ L'' >= O^n : L''/O^n of type lam, x_nu unimodular on L'' } over O=F_q[[t]].
x_nu = sum_i t^{a_i} J_2 on blocks (e_{2i-1},e_{2i}).  Elements of O/t^N as int tuples (coeffs mod q).
Lattices L'' = O^n + sum_i t^{-lam_i} O u_i enumerated through sublattices L''' = t^N L'' with
t^N O^n <= L''' <= O^n in Hermite normal form (upper triangular, diagonal t^{d_i}, 0<=d_i<=N).
Unimodularity <=> all x(g,g') in O for generators and |a| = |lam| (Pfaffian degree)."""
import sys, itertools
q = int(sys.argv[1]); n = int(sys.argv[2]); N = int(sys.argv[3])
lams = [tuple(map(int, s.split(','))) for s in sys.argv[4].split(';')]
nus = [tuple(map(int, s.split(','))) for s in sys.argv[5].split(';')]
M = 2 * N + 4  # working precision
def pmul(a, b):
    c = [0] * M
    for i, x in enumerate(a):
        if x:
            for j, y in enumerate(b):
                if i + j < M: c[i + j] = (c[i + j] + x * y) % q
    return c
def padd(a, b): return [(x + y) % q for x, y in zip(a, b)]
def mono(k): v = [0] * M; v[k] = 1; return v
def val(a):
    for i, x in enumerate(a):
        if x: return i
    return 10**9
def xform(nu):  # matrix of x_nu with entries as polys
    X = [[[0] * M for _ in range(n)] for _ in range(n)]
    for i, a in enumerate(nu):
        X[2*i][2*i+1] = mono(a); X[2*i+1][2*i] = [(-c) % q for c in mono(a)]
    return X
def smith_type(d, H):  # type of O^n / L''' from HNF columns; compute via minors valuations is costly;
    # instead compute elementary divisors by valuation of gcd of k x k minors (small n).
    import itertools as it
    rows = range(n)
    def det_val(rs, cs):
        best = 10**9
        for perm in it.permutations(cs):
            v = 0
            for r, c in zip(rs, perm):
                v += val(H[r][c])
                if v >= best: break
            else:
                # valuation of a sum can exceed min; use exact minor instead
                pass
        return None
    return None
def elem_divs(H):
    # exact Smith form over O truncated at precision M via row/col ops (valuation pivoting)
    A = [[list(H[i][j]) for j in range(n)] for i in range(n)]
    divs = []
    rows = list(range(n)); cols = list(range(n))
    for step in range(n):
        best = None
        for i in range(step, n):
            for j in range(step, n):
                v = val(A[i][j])
                if best is None or v < best[0]: best = (v, i, j)
        v, pi, pj = best
        if v >= M: divs.append(M); continue
        A[step], A[pi] = A[pi], A[step]
        for r in A: r[step], r[pj] = r[pj], r[step]
        piv = A[step][step]
        # make pivot t^v: multiply row by inverse of unit part
        u = piv[v:] + [0] * v
        # inverse of unit series u mod t^M
        inv = [0] * M; inv[0] = pow(u[0], -1, q)
        for k in range(1, M):
            s = sum(u[i] * inv[k - i] for i in range(1, k + 1)) % q
            inv[k] = (-s * inv[0]) % q
        A[step] = [pmul(inv, c) for c in A[step]]
        for i in range(step + 1, n):
            w = val(A[i][step])
            if w >= M: continue
            f = [0] * M
            for k in range(M - w): f[k + (w - v)] = A[i][step][k + w] if k + (w - v) < M else 0
            # f = A[i][step] / t^v
            f = [0] * M
            for k in range(v, M):
                if k - v < M: f[k - v] = A[i][step][k]
            A[i] = [padd(A[i][c], [(-y) % q for y in pmul(f, A[step][c])]) for c in range(n)]
        for j in range(step + 1, n):
            f = [0] * M
            for k in range(v, M): f[k - v] = A[step][j][k]
            for i in range(n):
                A[i][j] = padd(A[i][j], [(-y) % q for y in pmul(f, A[i][step])])
        divs.append(v)
    return sorted(divs, reverse=True)
def hnf_lattices():
    # columns h_j = t^{d_j} e_j + sum_{i<j} h_{ij} e_i, h_{ij} poly of degree < d_i
    for d in itertools.product(range(N + 1), repeat=n):
        slots = [(i, j) for j in range(n) for i in range(j)]
        ranges = [range(q ** d[i]) for (i, j) in slots]
        for choice in itertools.product(*ranges):
            H = [[[0] * M for _ in range(n)] for _ in range(n)]
            for j in range(n): H[j][j] = mono(d[j])
            for (i, j), c in zip(slots, choice):
                k = 0
                while c:
                    H[i][j][k] = c % q; c //= q; k += 1
            yield d, H
res = {(l, v): 0 for l in lams for v in nus}
X = {v: xform(v) for v in nus}
for d, H in hnf_lattices():
    ed = elem_divs(H)                      # type of O^n/L'''
    lam = tuple(sorted([N - e for e in ed], reverse=True))  # type of L''/O^n
    if lam not in lams: continue
    for v in nus:
        if sum(v) != sum(lam): continue
        ok = True
        for j1 in range(n):
            for j2 in range(j1 + 1, n):
                s = [0] * M
                for i1 in range(n):
                    if val(H[i1][j1]) >= M: continue
                    for i2 in range(n):
                        if val(X[v][i1][i2]) >= M: continue
                        s = padd(s, pmul(pmul(H[i1][j1], X[v][i1][i2]), H[i2][j2]))
                if val(s) < 2 * N: ok = False; break
            if not ok: break
        if ok: res[(lam, v)] += 1
for (l, v), c in sorted(res.items()): print('q=%d lam=%s nu=%s N=%d' % (q, l, v, c))
