'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    for i in range(n):
        # Add S[i] to y if x[i] is 1
        if S[i] != 0:
            for j in range(m):
                if (S[i] >> j) & 1:
                    qc.cx(x[i], y[j])

    # Write your code here:

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for j in range(m-1,-1,-1):
        qc.h(n+j)
        for l in range(j-1,-1,-1):
            qc.cp(2*math.pi/2**(j-l+1),n+l,n+j)
    for i in range(n):
        for j in range(m):
            qc.cp(2*math.pi*S[i]/2**(m-j),i,n+j)
    for j in range(m-1,-1,-1):
        qc.h(n+j)
        for l in range(j-1,-1,-1):
            qc.cp(-2*math.pi/2**(j-l+1),n+l,n+j)
    for k in range(m//2):
        qc.swap(n+k,n+m-1-k)
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for j in range(m-1,-1,-1):
        qc.h(n+j)
        for l in range(j-1,-1,-1):
            qc.cp(2*math.pi/2**(j-l+1),n+l,n+j)
    for k in range(m//2):
        qc.swap(n+k,n+m-1-k)
    for i in range(n):
        for j in range(m):
            qc.cp(2*math.pi*S[i]/2**(m-j),i,n+j)
    for j in range(m-1,-1,-1):
        qc.h(n+j)
        for l in range(j-1,-1,-1):
            qc.cp(-2*math.pi/2**(j-l+1),n+l,n+j)
    for k in range(m//2):
        qc.swap(n+k,n+m-1-k)
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

# from qiskit.quantum_info import Statevector

def quantum_fourier_transform(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)

    for i in range(n-1, -1, -1):
        qc.h(i)
        for j in range(i-1, -1, -1):
            qc.cp(2*math.pi/(2**(i-j+1)), j, i)

    i = 0
    while i<n-i-1:
        qc.swap(i, n-i-1)
        i += 1

    return qc.to_gate()

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # init = [0]*(2**(n+m))
    # init[3] = 1
    # qc.initialize(init)

    # Write your code here:

    qc.append(quantum_fourier_transform(m), y)
    for j in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(2**m)*(2**j), x[i], y[j])
    qc.append(quantum_fourier_transform(m).inverse(), y)

    return qc

# if __name__ == "__main__":
#     qc = solve(2, 2, [1, 2])
#     print(Statevector(qc))
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

# from qiskit.quantum_info import Statevector

def quantum_fourier_transform(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)

    for i in range(n-1, -1, -1):
        qc.h(i)
        for j in range(i-1, -1, -1):
            qc.cp(2*math.pi/(2**(i-j+1)), j, i)

    i = 0
    while i<n-i-1:
        qc.swap(i, n-i-1)
        i += 1

    return qc

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # init = [0]*(2**(n+m))
    # init[3] = 1
    # qc.initialize(init)

    # Write your code here:

    qc.compose(quantum_fourier_transform(m), y, inplace=True)
    for j in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(2**m)*(2**j), x[i], y[j])
    qc.compose(quantum_fourier_transform(m).inverse(), y, inplace=True)

    return qc

# if __name__ == "__main__":
#     qc = solve(2, 2, [1, 2])
#     print(Statevector(qc))
'''


'''python
import math

from qiskit import QuantumCircuit, QuantumRegister

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)

    for i in reversed(range(n)):
        qc.h(i)
        for j in reversed(range(i)):
            qc.cp(math.pi / 2 ** (i - j), j, i)

    for i in range(n // 2):
        qc.swap(i, n - i - 1)

    return qc

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    qft_m = qft(m)

    qc.compose(qft_m, y, inplace=True)

    for j in range(m):
        for i in range(n):
            theta = (2 * math.pi * S[i] / 2**m) * 2**j
            qc.cp(theta, x[i], y[j])

    qc.compose(qft_m.inverse(), y, inplace=True)

    return qc
'''


'''python
from qiskit import QuantumRegister, QuantumCircuit

# Let n = len(qubits)
# if no ctrl_qubits, adds 2 * len(qubits) circuit depth
# otherwise,
#  if n % 2 == 0, adds n * (n/2 + 1) circuit depth
#  otherwise, adds (n-1) * ((n-1)/2 + 1) + n circuit depth
def apply_QFT(qc, qubits, ctrl_qubit = None, inverse = False):
	from numpy import pi
	coef = -pi if inverse else pi
	if ctrl_qubit:
		for i in reversed(range(len(qubits))):
			qc.ch(ctrl_qubit, qubits[i])
			for j in reversed(range(i)):
				qc.mcp(coef / 2**(i - j), [ctrl_qubit, qubits[j]], qubits[i])
		for i in range(len(qubits) // 2):
			qc.cswap(ctrl_qubit, qubits[i], qubits[len(qubits) - 1 - i])
	else:
		for i in reversed(range(len(qubits))):
			qc.h(qubits[i])
			for j in reversed(range(i)):
				qc.cp(coef / 2**(i - j), qubits[j], qubits[i])
		for i in range(len(qubits) // 2):
			qc.swap(qubits[i], qubits[len(qubits) - 1 - i])
	return qc

def solve(n, m, s) -> QuantumCircuit:
	x, y = QuantumRegister(n), QuantumRegister(m)
	qc = QuantumCircuit(x, y)
	from numpy import pi
	apply_QFT(qc, y)
	for i in range(n):
		for j in range(m):
			qc.cp(pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	apply_QFT(qc, y, inverse = True)
	return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc.x(n)
    for i in range(m - 1, -1, -1):
        qc.h(i+n)
        for j in range(i - 1, -1, -1):
            qc.cp(np.pi / 2**(i - j), i+n, j+n)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        qc.h(i+n)

        for j in range(n):
            qc.cp(2*np.pi*S[j]/2**(m-i), i+n,j)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        for j in range(i):
            qc.cp(-np.pi / 2**(i - j), j+n, i+n)
        qc.h(i+n)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for i in range(m - 1, -1, -1):
        qc.h(i+n)
        for j in range(i - 1, -1, -1):
            qc.cp(np.pi / 2**(i - j), i+n, j+n)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        qc.h(i+n)

        for j in range(n):
            qc.cp(2*np.pi*S[j]/2**(m-i), i+n,j)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        for j in range(i):
            qc.cp(-np.pi / 2**(i - j), j+n, i+n)
        qc.h(i+n)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for i in range(m - 1, -1, -1):
        qc.h(i+n)
        for j in range(i - 1, -1, -1):
            qc.cp(np.pi / 2**(i - j), i+n, j+n)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        for j in range(n):
            qc.cp(2*np.pi*S[j]/2**(m-i), i+n,j)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        for j in range(i):
            qc.cp(-np.pi / 2**(i - j), j+n, i+n)
        qc.h(i+n)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    qc.cp(2*math.pi/(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qft_m = qft(m)
    qc = qc.compose(qft_m, y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k), y[k], x[i])
    qc = qc.compose(qft_m.inverse(), y)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    import math

    def qft(num_qubits: int) -> QuantumCircuit:
        qc = QuantumCircuit(num_qubits)
        for i in range(num_qubits):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, num_qubits):
                qc.cp(rotation, j, i)
                rotation /= 2
        # for i in range(num_qubits // 2):
        #     qc.swap(i, num_qubits - i - 1)
        # qc = qc.reverse_bits()
        return qc

    def add_k_fourier(
        qc: QuantumCircuit, k: int, control: QuantumRegister
    ) -> QuantumCircuit:
        for i in range(m):
            qc.crz(math.pi * k / 2**i, control_qubit=control, target_qubit=y[m - 1 - i])

    def swap_qubits(qc: QuantumCircuit, x: QuantumRegister):
        for i in range(len(x) // 2):
            qc.swap(x[i], x[len(x) - i - 1])

    # swap_qubits(qc, x)

    qc.compose(qft(m), inplace=True, qubits=y)

    for i in range(n):
        add_k_fourier(qc, S[n - 1 - i], x[n - 1 - i])

    qc.compose(qft(m).inverse(), inplace=True, qubits=y)

    # swap_qubits(qc, y)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    import math

    def qft(num_qubits: int) -> QuantumCircuit:
        qc = QuantumCircuit(num_qubits)
        for i in range(num_qubits):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, num_qubits):
                qc.cp(rotation, j, i)
                rotation /= 2
        # for i in range(num_qubits // 2):
        #     qc.swap(i, num_qubits - i - 1)
        # qc = qc.reverse_bits()
        return qc

    def add_k_fourier(
        qc: QuantumCircuit, k: int, control: QuantumRegister
    ) -> QuantumCircuit:
        for i in range(m):
            qc.crz(math.pi * k / 2**i, control_qubit=control, target_qubit=y[m - 1 - i])

    def swap_qubits(qc: QuantumCircuit, x: QuantumRegister):
        for i in range(len(x) // 2):
            qc.swap(x[i], x[len(x) - i - 1])

    # swap_qubits(qc, x)

    qc.compose(qft(m), inplace=True, qubits=y)

    for i in range(n):
        add_k_fourier(qc, S[i], x[i])

    qc.compose(qft(m).inverse(), inplace=True, qubits=y)

    # swap_qubits(qc, y)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import GlobalPhaseGate
import numpy as np
import math

def qft(n):
    qc = QuantumCircuit(n)

    thetas = []
    for k in range(0, 1+n):
        thetas.append(2 * math.pi / (2**k))

    for idx in range(0, n):
        qc.h(n-1-idx)
        for jdx in range(idx+1, n):
            thetaidx = jdx - idx + 1
            qc.cp(thetas[thetaidx], n-1-jdx, n-1-idx)

    for idx in range(0, n//2):
        qc.swap(idx, n-idx-1)

    return qc

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    qc = qc.compose(qft(m), y)

    for idx in range(0, n):
        for jdx in range(0, m):
            theta = 2 * math.pi * S[idx] * (2**jdx) / (2**m)
            qc.cp(theta, x[idx], y[jdx])

    qc = qc.compose(qft(m).inverse(), y)
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    # Apply controlled addition for each term in the function f(x)
    for i in range(n):
        # We use a controlled adder with x[i] controlling the addition of S[i]
        # Use the basic Toffoli and CNOT gates to achieve this
        if S[i] != 0:
            qc.append(qc.cx(x[i], y[0]), [x[i], y[0]])
            for j in range(1, m):
                qc.append(qc.cx(x[i], y[j]), [x[i], y[j]])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x = QuantumRegister(n, name='x')
    y = QuantumRegister(m, name='y')
    qc = QuantumCircuit(x, y)

    # Apply controlled addition for each coefficient S[i]
    for i in range(n):
        coeff = S[i]
        # Use multi-controlled addition gates to add the coefficients
        for j in range(m):
            if (coeff >> j) & 1:
                # Apply a controlled-X gate for each bit in y if the corresponding bit in coeff is 1
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # We will use a temporary register to hold the carry bits for addition
    carry = QuantumRegister(m)
    qc.add_register(carry)

    # Initialize carry bits to 0
    for j in range(m):
        qc.x(carry[j])  # Set carry bits to 0 initially

    # Iterate over each bit of x
    for i in range(n):
        if S[i] > 0:  # Only if S[i] is non-zero
            # We need to add S[i] to y if x[i] is 1
            # Convert S[i] to binary and apply controlled additions
            s_bin = format(S[i], f'0{m}b')  # Get binary representation of S[i]
            for j in range(m):
                if s_bin[j] == '1':
                    # Apply controlled addition of 1 to y[j] if x[i] is 1
                    qc.cx(x[i], y[j])  # Controlled NOT gate

    return qc
'''


'''python
from qiskit import QuantumCircuit
from math import pi

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    for i in range(n):
        j = n - 1 - i
        if i >= j:
            break
        qc.swap(i, j)

    for i in range(n):
        qc.h(i)
        for j in range(i + 1, n):
            theta = 2 * pi / (2 ** (j + 1 - i))
            qc.cp(theta, j, i)

    return qc

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc.compose(qft(m), y, inplace=True)
    for j in range(m):
        for i in range(n):
            theta = 2 * pi * S[i] * 2 ** (j - m)
            qc.cp(theta, j + n, i)

    qc.compose(qft(m).inverse(), y, inplace=True)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from math import pi

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    for i in range(n):
        j = n - 1 - i
        if i >= j:
            break
        qc.swap(i, j)

    for i in range(n):
        qc.h(i)
        for j in range(i + 1, n):
            theta = 2 * pi / (2 ** (j + 1 - i))
            qc.cp(theta, j, i)

    return qc

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc.compose(qft(m), y, inplace=True)
    for j in range(m):
        for i in range(n):
            theta = 2 * pi * S[i] * 2 ** (j - m)
            qc.cp(theta, j + n, i)

    qc.compose(qft(m).inverse(), y, inplace=True)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def QFT(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n):
        qc.h(n-i-1)
        for j in range(1, n-i):
            qc.cp(math.pi/2**j, n-i-j-1, n-i-1)
    for i in range(n//2):
        qc.swap(i, n-i-1)
    return qc

def IQFT(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n):
        qc.h(n-i-1)
        for j in range(1, n-i):
            qc.cp(-math.pi/2**j, n-i-j-1, n-i-1)
    for i in range(n//2):
        qc.swap(i, n-i-1)
    return qc

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    # QFT
    qc.compose(QFT(m), y, inplace=True)

    for j in range(m):
        # Oracle B5
        for i in range(n):
            qc.cp(2*math.pi*S[i]*2**j/2**m, y[j], x[i])

    # IQFT
    qc.compose(IQFT(m), y, inplace=True)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library.standard_gates  import PhaseGate
import math
def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
  x, y = QuantumRegister(n), QuantumRegister(m)
  qc = QuantumCircuit(x, y)
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(-2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  for i in range(n):
    for j in range(m):
      qc.append(PhaseGate(-2 * math.pi * S[i] / pow(2, m - j)).control(1), [i, n + j])
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for i in range(n):
        # Loop through each bit of y
        for j in range(m):
            # If the j-th bit of S[i] is 1, apply a controlled-NOT gate
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    def add_value_to_register(value, target_register):
        """Adds 'value' to the target quantum register (in-place addition)."""
        num_bits = len(target_register)
        for i in range(num_bits):
            if (value >> i) & 1:  # if the ith bit of value is 1
                qc.cx(target_register[i], target_register[(i + 1) % num_bits])  # Controlled-X

    # Iterate over all possible states of the n qubits
    for i in range(2 ** n):
        x_bits = [int(bit) for bit in format(i, f'0{n}b')]
        f_x = sum(S[j] * x_bits[j] for j in range(n))

        # Add f_x to the y register
        add_value_to_register(f_x, y)
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    # Implement controlled additions
    for i in range(n):
        for j in range(m):
            # Determine if we need to add 2^j to y[j] based on S[i] and controlled by x[i]
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

from qiskit.circuit.library import HGate, ZGate, XGate, PhaseGate
from qiskit import QuantumRegister
import math

def QFT(qc : QuantumCircuit, idx : list[int], inversed : bool = False) -> QuantumCircuit:
    n = len(idx)
    for i in range(n // 2):
        qc.swap(idx[i], idx[n - i - 1])
    for j in range(n):
        qc.h(idx[j])
        for k in range(j+1, n):
            theta = math.pi / (2 ** (k - j))
            if (inversed):
                theta *= -1
            qc.cp(theta, idx[k], idx[j])

    #for i in range(n // 2):
    #    qc.swap(idx[i], idx[n - i - 1])

    return qc

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    QFT(qc, list(range(n, n + m)))

    for j in range(m):
        for i in range(n):
            theta = (2 * math.pi * S[i] / (2 ** m)) * 2 ** j
            qc.cp(theta, x[i], y[j])

    QFT(qc, list(range(n, n + m)), inversed = True)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    for i in range(n,n+m):
        qc.h(i)
    for i in range(n,n+m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    # for i in range(m):
    #     if n+i < m-1-i:
    #         qc.swap(n+i,m-1-i)

    for i in range(n,n+m):
        for j in range(n,i):
            qc.cp(-np.pi/(2.0**(i-j)), j, i)
        qc.h(i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    for i in range(n,n+m):
        qc.h(i)
    for i in range(n,n+m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    # for i in range(m):
    #     if n+i < m-1-i:
    #         qc.swap(n+i,m-1-i)

    for i in range(n,n+m):
        for j in range(n,i):
            qc.cp(-np.pi/(2.0**(i-j)), j, i)
        qc.h(i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as n

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    for i in reversed(range(n,n+m)):
        qc.h(i)
        for j in reversed(range(n,i)):
            qc.cp(np.pi/(2.0 ** (i-j)), j, i)

    for i in range(n):
        if i < n-1-i:
            qc.swap(i,n-1-i)

    # for i in range(n,n+m):
    #     qc.h(i)
    for i in range(n,n+m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    # for i in range(m):
    #     if n+i < m-1-i:
    #         qc.swap(n+i,m-1-i)

    for i in range(n,n+m):
        for j in range(n,i):
            qc.cp(-np.pi/(2.0**(i-j)), j, i)
        qc.h(i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    for i in reversed(range(n,n+m)):
        qc.h(i)
        for j in reversed(range(n,i)):
            qc.cp(np.pi/(2.0 ** (i-j)), j, i)

    for i in range(n):
        if i < n-1-i:
            qc.swap(i,n-1-i)

    # for i in range(n,n+m):
    #     qc.h(i)
    for i in range(n,n+m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    # for i in range(m):
    #     if n+i < m-1-i:
    #         qc.swap(n+i,m-1-i)

    for i in range(n,n+m):
        for j in range(n,i):
            qc.cp(-np.pi/(2.0**(i-j)), j, i)
        qc.h(i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    for i in reversed(range(n,n+m)):
        qc.h(i)
        for j in reversed(range(n,i)):
            qc.cp(np.pi/(2.0 ** (i-j)), j, i)

    # for i in range(n,n+m):
    #     for j in range(n,i):
    #         qc.cp()
    #     qc.h(i)

    # for i in range(n,n+m):
    #     qc.h(i)
    for i in range(n,n+m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    # for i in range(m):
    #     if n+i < m-1-i:
    #         qc.swap(n+i,m-1-i)

    for i in range(n,n+m):
        for j in range(n,i):
            qc.cp(-np.pi/(2.0**(i-j)), j, i)
        qc.h(i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    ### B6

    for i in range(n,n+m):
        qc.h(i)
    for i in range(n,n+m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    for i in range(n,n+m):
        for j in range(n,i):
            qc.cp(-np.pi/(2.0**(i-j)), j, i)
        qc.h(i)

    ### B2

    for i in range(n, n+m):
        if L&(1<<i) == 0:
            qc.x(i)
    if m == 1:
        qc.p(theta, n+m-1)
    elif m == 2:
        qc.cp(theta, n+m-2, n+m-1)
    else:
        qc.mcp(theta, list(range(n, n+m-1)), n+m-1)
    for i in range(n, n+m):
        if L&(1<<i) == 0:
            qc.x(i)

    ### B6(uncomputation)
    for i in reversed(range(n,n+m)):
        qc.h(i)
        for j in reversed(range(n,i)):
            qc.cp(np.pi/(2.0**(i-j)), j, i)

    for i in reversed(range(n,n+m)):
        for j in reversed(range(n)):
            qc.cp(-2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    for i in range(n,n+m):
        qc.h(i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    ### B6

    for i in range(n,n+m):
        qc.h(i)
    for i in range(n,n+m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    for i in range(n,n+m):
        for j in range(n,i):
            qc.cp(-np.pi/(2.0**(i-j)), j, i)
        qc.h(i)

    ### B2

    for i in range(n, n+m):
        if L&(1<<(i-n)) == 0:
            qc.x(i)
    if m == 1:
        qc.p(theta, n+m-1)
    elif m == 2:
        qc.cp(theta, n+m-2, n+m-1)
    else:
        qc.mcp(theta, list(range(n, n+m-1)), n+m-1)
    for i in range(n, n+m):
        if L&(1<<(i-n)) == 0:
            qc.x(i)

    ### B6(uncomputation)
    for i in reversed(range(n,n+m)):
        qc.h(i)
        for j in reversed(range(n,i)):
            qc.cp(np.pi/(2.0**(i-j)), j, i)

    for i in reversed(range(n,n+m)):
        for j in reversed(range(n)):
            qc.cp(-2.0*np.pi/(2.0**m)*S[j]*(2.0**((n+m-1)-i)), i, j)

    for i in range(n,n+m):
        qc.h(i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    for i in range(m):
        qc.h(i+n)

        for j in range(n):
            qc.cp(2*np.pi*S[j]/2**(m-i), i+n,j)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        for j in range(i):
            qc.cp(-np.pi / 2**(i - j), j+n, i+n)
        qc.h(i+n)

    for i in range(m):
        if not ((L>>i)&1):
            qc.x(i+n)
    if m==1:
        qc.p(theta,n)

    else :
        qc.mcp(theta,[i+n for i in range(m-1)],n+m-1)

    for i in range(m):
        if not ((L>>i)&1):
            qc.x(i+n)

    for i in range(m - 1, -1, -1):
        qc.h(i+n)
        for j in range(i - 1, -1, -1):
            qc.cp(np.pi / 2**(i - j), i+n, j+n)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        for j in range(n):
            qc.cp(-2*np.pi*S[j]/2**(m-i), i+n,j)

        qc.h(i+n)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    for i in range(m):
        qc.h(i+n)

        for j in range(n):
            qc.cp(2*np.pi*S[j]/2**(m-i), i+n,j)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        for j in range(i):
            qc.cp(-np.pi / 2**(i - j), j+n, i+n)
        qc.h(i+n)

    for i in range(m):
        if not ((L>>i)&1):
            qc.x(i+n)
    if m==1:
        qc.p(theta,n)

    else :
        qc.mcp(theta,[i+n for i in range(m-1)],n+m-1)

    for i in range(m):
        if not ((L>>i)&1):
            qc.x(i+n)

    for i in range(m - 1, -1, -1):
        qc.h(i+n)
        for j in range(i - 1, -1, -1):
            qc.cp(np.pi / 2**(i - j), i+n, j+n)

    for i in range(m // 2):
        qc.swap(i+n, n+m - i - 1)

    for i in range(m):
        for j in range(n):
            qc.cp(-2*np.pi*S[j]/2**(m-i), i+n,j)

        qc.h(i+n)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:

    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    for i in range(n):
        for j in range(n):
            if S[j] != 0:
                qc.cx(x[j], y[i])
                qc.rz(2 * np.pi * S[j] / (2 ** m), y[i])
                qc.cx(x[j], y[i])

    for i in range(2 ** n):

        f_x = sum(S[j] * ((i >> j) & 1) for j in range(n))
        if f_x % (2 ** m) == L:
            qc.rz(theta, y[0])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import GlobalPhaseGate
import numpy as np
import math

def qft(n):
    qc = QuantumCircuit(n)

    thetas = []
    for k in range(0, 1+n):
        thetas.append(2 * math.pi / (2**k))

    for idx in range(0, n):
        qc.h(n-1-idx)
        for jdx in range(idx+1, n):
            thetaidx = jdx - idx + 1
            qc.cp(thetas[thetaidx], n-1-jdx, n-1-idx)

    for idx in range(0, n//2):
        qc.swap(idx, n-idx-1)

    return qc

def add(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    qc = qc.compose(qft(m), y)

    for idx in range(0, n):
        for jdx in range(0, m):
            theta = 2 * math.pi * S[idx] * (2**jdx) / (2**m)
            qc.cp(theta, x[idx], y[jdx])

    qc = qc.compose(qft(m).inverse(), y)
    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    qc.compose(add(n, m, S), inplace=True)

    lbits = []
    for idx in range(0, m):
        lbits.append(bool(L % 2))
        L = L // 2

    for idx in range(0, m):
        if not lbits[idx]:
            qc.x(y[idx])

    if m == 1:
        qc.p(theta, y[0])
    else:
        qc.mcp(theta, y[0:m-1], y[m-1])

    for idx in range(0, m):
        if not lbits[idx]:
            qc.x(y[idx])

    qc.compose(add(n, m, S).inverse(), inplace=True)
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
        for i in range(n):
        for _ in range(S[i]):  # Add S_i to the ancilla qubits based on x_i
            qc.cx(i, n + (S[i] % m))

    # Step 2: Check if f(x) mod 2^m equals L mod 2^m
    # Convert L to binary and store in ancilla qubits for comparison
    L_bin = format(L % (2**m), f'0{m}b')
    for i in range(m):
        if L_bin[i] == '0':
            qc.x(n + i)

    # Apply controlled phase shift if the ancilla qubits match L mod 2^m
    qc.mcx(list(range(n, n + m)), 0)  # Multi-controlled X gate
    qc.p(theta, 0)  # Apply phase shift e^(iθ) to the first qubit
    qc.mcx(list(range(n, n + m)), 0)  # Undo the multi-controlled X gate

    # Reapply X gates to reset ancilla qubits to the original state
    for i in range(m):
        if L_bin[i] == '0':
            qc.x(n + i)
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def QFT(qc : QuantumCircuit, idx : list[int], inversed : bool = False) -> QuantumCircuit:
    n = len(idx)
    for i in range(n // 2):
        qc.swap(idx[i], idx[n - i - 1])
    for j in range(n):
        qc.h(idx[j])
        for k in range(j+1, n):
            theta = math.pi / (2 ** (k - j))
            if (inversed):
                theta *= -1
            qc.cp(theta, idx[k], idx[j])

    #for i in range(n // 2):
    #    qc.swap(idx[i], idx[n - i - 1])

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    QFT(qc, list(range(n, n+m)))

    for j in range(m):
        for i in range(n):
            theta = 2 * math.pi * S[i] * (2 ** j) / (2 ** m)
            qc.cp(theta, x[i], y[j])

    QFT(qc, list(range(n, n+m)), inversed = True)

    for i in range(m):
        if not (1 << i) & L:
            qc.x(y[i])

    if n == 1:
        qc.p(theta, n + m - 1)
    else:
        qc.mcp(theta, list(n + range(m - 1)), n + m - 1)

    for i in range(m):
        if not (1 << i) & L:
            qc.x(y[i])

    QFT(qc, list(range(n, n+m)))

    for j in range(m):
        for i in range(n):
            theta = -2 * math.pi * S[i] * (2 ** j) / (2 ** m)
            qc.cp(theta, x[i], y[j])

    QFT(qc, list(range(n, n+m)), inversed = True)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc.compose(o_f(n,m,S), inplace=True)
    qc.compose(o_Pshift(m,L,theta),qubits=list(range(n,n+m)),inplace=True)
    qc.compose(o_f(n,m,S).inverse(), inplace=True)

    return qc

def o_f(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for j in range(m-1,-1,-1):
        qc.h(n+j)
        for l in range(j-1,-1,-1):
            qc.cp(2*math.pi/2**(j-l+1),n+l,n+j)
    for k in range(m//2):
        qc.swap(n+k,n+m-1-k)
    for i in range(n):
        for j in range(m):
            qc.cp(2*math.pi*S[i]/2**(m-j),i,n+j)
    for j in range(m-1,-1,-1):
        qc.h(n+j)
        for l in range(j-1,-1,-1):
            qc.cp(-2*math.pi/2**(j-l+1),n+l,n+j)
    for k in range(m//2):
        qc.swap(n+k,n+m-1-k)
    return qc

def o_Pshift(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    L_code = format(L, f'0{n}b')[::-1]
    print(L_code)
    for i in range(n):
        if L_code[i] == "0":
            qc.x(i)
    if n >= 2:
        qc.mcp(theta,list(range(n-1)),n-1)
    else:
        qc.p(theta, 0)
    for i in range(n):
        if L_code[i] == "0":
            qc.x(i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library.standard_gates  import PhaseGate
import math
def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
  x, y = QuantumRegister(n), QuantumRegister(m)
  qc = QuantumCircuit(x, y)
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(-2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  for i in range(n):
    for j in range(m):
      qc.append(PhaseGate(-2 * math.pi * S[i] / pow(2, m - j)).control(1), [i, n + j])
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  for i in range(m):
    if ((L >> i) & 1) == 0:
      qc.x(n + i)
  if m == 1:
    qc.p(theta, n)
  else:
    qc.append(PhaseGate(theta).control(m - 1), list(range(n, n + m)))
  for i in range(m):
    if ((L >> i) & 1) == 0:
      qc.x(n + i)
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  for i in range(n):
    for j in range(m):
      qc.append(PhaseGate(2 * math.pi * S[i] / pow(2, m - j)).control(1), [i, n + j])
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(-2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library.standard_gates  import PhaseGate
import math
def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
  x, y = QuantumRegister(n), QuantumRegister(m)
  qc = QuantumCircuit(x, y)
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(-2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  for i in range(n):
    for j in range(m):
      qc.append(PhaseGate(-2 * math.pi * S[i] / pow(2, m - j)).control(1), [i, n + j])
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  for i in range(m):
    if ((L >> i) & 1) == 0:
      qc.x(n + i)
  if m == 1:
    qc.p(theta, n)
  else:
    qc.append(PhaseGate(theta).control(m - 1), list(range(n, n + m)))
  for i in range(m):
    if ((L >> i) & 1) == 0:
      qc.x(n + i)
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(-2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  for i in range(n):
    for j in range(m):
      qc.append(PhaseGate(2 * math.pi * S[i] / pow(2, m - j)).control(1), [i, n + j])
  for i in range(m - 1, -1, -1):
    for j in range(m - 1, i, -1):
      qc.append(PhaseGate(2 * math.pi * math.pow(2, i - 1 - j)).control(1), [n + i, n + j])
    qc.h(n + i)
  for i in range(m // 2):
    qc.cx(n + i, n + m - 1 - i)
    qc.cx(n + m - 1 - i, n + i)
    qc.cx(n + i, n + m - 1 - i)
  return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library.standard_gates import U1Gate
from math import pi

def QFT(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)

    for i in range(n//2):
        qc.swap(i, n-i-1)
    for i in range(n):
        qc.h(i)
        for j in range(i+1, n):
            qc.append(U1Gate(pi/2**(j-i)).control(1), [j, i])
    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # y をフーリエ変換
    for i in range(m):
        qc.h(n + i)

    # S[i] をフーリエ変換したものを掛ける
    for i in range(n):
        for j in range(m):
            qc.append(U1Gate(2 * pi * S[i] / 2 ** (m - j)).control(1), [i, n + j])

    # y を逆フーリエ変換
    for i in range(m//2):
        qc.swap(n + i, n + m-i-1)
    for i in range(m):
        qc.h(n + i)
        for j in range(i+1, m):
            qc.append(U1Gate(-pi/2**(j-i)).control(1), [n + j, n + i])

    # y == L のところに e^iθ を掛ける
    for i in range(m):
        if ~L & (1 << i):
            qc.x(n + i)
    qc.append(U1Gate(theta).control(m-1) if m else U1Gate(theta), range(n, n+m))
    for i in range(m):
        if ~L & (1 << i):
            qc.x(n + i)

    # さっきの逆

    # y をフーリエ変換
    for i in range(m//2):
        qc.swap(n + i, n + m-i-1)
    for i in range(m):
        qc.h(n + i)
        for j in range(i+1, m):
            qc.append(U1Gate(pi/2**(j-i)).control(1), [n + j, n + i])

    # S[i] をフーリエ変換したものを割る
    for i in range(n):
        for j in range(m):
            qc.append(U1Gate(-2 * pi * S[i] / 2 ** (m - j)).control(1), [i, n + j])

    # y をフーリエ変換
    for i in range(m):
        qc.h(n + i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library.standard_gates import U1Gate
from math import pi

def QFT(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)

    for i in range(n//2):
        qc.swap(i, n-i-1)
    for i in range(n):
        qc.h(i)
        for j in range(i+1, n):
            qc.append(U1Gate(pi/2**(j-i)).control(1), [j, i])
    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # y をフーリエ変換
    for i in range(m):
        qc.h(n + i)

    # S[i] をフーリエ変換したものを掛ける
    for i in range(n):
        for j in range(m):
            qc.append(U1Gate(2 * pi * S[i] / 2 ** (m - j)).control(1), [i, n + j])

    # y を逆フーリエ変換
    for i in range(m//2):
        qc.swap(n + i, n + m-i-1)
    for i in range(m):
        qc.h(n + i)
        for j in range(i+1, m):
            qc.append(U1Gate(-pi/2**(j-i)).control(1), [n + j, n + i])

    # y == L のところに e^iθ を掛ける
    for i in range(m):
        if ~L & (1 << i):
            qc.x(n + i)
    qc.append(U1Gate(theta).control(m-1) if m > 1 else U1Gate(theta), range(n, n+m))
    for i in range(m):
        if ~L & (1 << i):
            qc.x(n + i)

    # さっきの逆

    # y をフーリエ変換
    for i in range(m//2):
        qc.swap(n + i, n + m-i-1)
    for i in range(m):
        qc.h(n + i)
        for j in range(i+1, m):
            qc.append(U1Gate(pi/2**(j-i)).control(1), [n + j, n + i])

    # S[i] をフーリエ変換したものを割る
    for i in range(n):
        for j in range(m):
            qc.append(U1Gate(-2 * pi * S[i] / 2 ** (m - j)).control(1), [i, n + j])

    # y をフーリエ変換
    for i in range(m):
        qc.h(n + i)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    # Compute the value of L mod 2^m
    L_mod = L % (2 ** m)

    # Apply the function f(x) = S0*x0 + S1*x1 + ... + S(n-1)*x(n-1)
    for i in range(n):
        if S[i] != 0:
            qc.cx(x[i], y[0])  # Add a controlled-NOT (CNOT) to y based on x[i]
            for j in range(1, m):
                if S[i] & (1 << j):
                    qc.cx(x[i], y[j])

    # Apply the phase shift conditional on f(x) == L mod 2^m
    for i in range(m):
        if (L_mod & (1 << i)) != 0:
            qc.h(y[i])

    # Apply the phase shift
    qc.rz(theta, y[0])

    # Revert the state to its original form
    for i in range(m):
        if (L_mod & (1 << i)) != 0:
            qc.h(y[i])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    qc.cp(2*math.pi/(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc.h(y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k), y[k], x[i])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    b=[0]*n
    for i in range(n):
        b[i]=L%2
        L//=2
    for i in range(n):
        if b[i]==0:
            qc.x(i)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if b[i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(m, L, theta), y)
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumRegister, QuantumCircuit

# Let n = len(qubits)
# if no ctrl_qubits, adds 2 * len(qubits) circuit depth
# otherwise,
#  if n % 2 == 0, adds n * (n/2 + 1) circuit depth
#  otherwise, adds (n-1) * ((n-1)/2 + 1) + n circuit depth
def apply_QFT(qc, qubits, ctrl_qubit = None, inverse = False):
	from numpy import pi
	coef = -pi if inverse else pi
	if ctrl_qubit:
		for i in reversed(range(len(qubits))):
			qc.ch(ctrl_qubit, qubits[i])
			for j in reversed(range(i)):
				qc.mcp(coef / 2**(i - j), [ctrl_qubit, qubits[j]], qubits[i])
		for i in range(len(qubits) // 2):
			qc.cswap(ctrl_qubit, qubits[i], qubits[len(qubits) - 1 - i])
	else:
		for i in reversed(range(len(qubits))):
			qc.h(qubits[i])
			for j in reversed(range(i)):
				qc.cp(coef / 2**(i - j), qubits[j], qubits[i])
		for i in range(len(qubits) // 2):
			qc.swap(qubits[i], qubits[len(qubits) - 1 - i])
	return qc

def solve(n, m, L, s, theta) -> QuantumCircuit:
	x, y = QuantumRegister(n), QuantumRegister(m)
	qc = QuantumCircuit(x, y)
	from numpy import pi
	for j in range(m):
		qc.h(y[j])
	for i in range(n):
		for j in range(m):
			qc.cp(pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	apply_QFT(qc, y, inverse = True)
	if m == 1:
		if L == 0:
			qc.x(y[0])
		qc.p(theta)
		if L == 0:
			qc.x(y[0])
	else:
		for j in range(m):
			if ~L >> j & 1:
				qc.x(y[j])
		qc.mcp(theta, range(m - 1), m - 1)
		for j in range(m):
			if ~L >> j & 1:
				qc.x(y[j])
	apply_QFT(qc, y)
	for i in range(n):
		for j in range(m):
			qc.cp(-pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	for j in range(m):
		qc.h(y[j])
	return qc
'''


'''python
from qiskit import QuantumRegister, QuantumCircuit

# Let n = len(qubits)
# if no ctrl_qubits, adds 2 * len(qubits) circuit depth
# otherwise,
#  if n % 2 == 0, adds n * (n/2 + 1) circuit depth
#  otherwise, adds (n-1) * ((n-1)/2 + 1) + n circuit depth
def apply_QFT(qc, qubits, ctrl_qubit = None, inverse = False):
	from numpy import pi
	coef = -pi if inverse else pi
	if ctrl_qubit:
		for i in reversed(range(len(qubits))):
			qc.ch(ctrl_qubit, qubits[i])
			for j in reversed(range(i)):
				qc.mcp(coef / 2**(i - j), [ctrl_qubit, qubits[j]], qubits[i])
		for i in range(len(qubits) // 2):
			qc.cswap(ctrl_qubit, qubits[i], qubits[len(qubits) - 1 - i])
	else:
		for i in reversed(range(len(qubits))):
			qc.h(qubits[i])
			for j in reversed(range(i)):
				qc.cp(coef / 2**(i - j), qubits[j], qubits[i])
		for i in range(len(qubits) // 2):
			qc.swap(qubits[i], qubits[len(qubits) - 1 - i])
	return qc

def solve(n, m, L, s, theta) -> QuantumCircuit:
	x, y = QuantumRegister(n), QuantumRegister(m)
	qc = QuantumCircuit(x, y)
	from numpy import pi
	for j in range(m):
		qc.h(y[j])
	for i in range(n):
		for j in range(m):
			qc.cp(pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	apply_QFT(qc, y, inverse = True)
	if m == 1:
		if L == 0:
			qc.x(y[0])
		qc.p(theta)
		if L == 0:
			qc.x(y[0])
	else:
		for j in range(m):
			if ~L >> j & 1:
				qc.x(y[j])
		qc.mcp(theta, list(range(m - 1)), m - 1)
		for j in range(m):
			if ~L >> j & 1:
				qc.x(y[j])
	apply_QFT(qc, y)
	for i in range(n):
		for j in range(m):
			qc.cp(-pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	for j in range(m):
		qc.h(y[j])
	return qc
'''


'''python
from qiskit import QuantumRegister, QuantumCircuit

# Let n = len(qubits)
# if no ctrl_qubits, adds 2 * len(qubits) circuit depth
# otherwise,
#  if n % 2 == 0, adds n * (n/2 + 1) circuit depth
#  otherwise, adds (n-1) * ((n-1)/2 + 1) + n circuit depth
def apply_QFT(qc, qubits, ctrl_qubit = None, inverse = False):
	from numpy import pi
	coef = -pi if inverse else pi
	if ctrl_qubit:
		for i in reversed(range(len(qubits))):
			qc.ch(ctrl_qubit, qubits[i])
			for j in reversed(range(i)):
				qc.mcp(coef / 2**(i - j), [ctrl_qubit, qubits[j]], qubits[i])
		for i in range(len(qubits) // 2):
			qc.cswap(ctrl_qubit, qubits[i], qubits[len(qubits) - 1 - i])
	else:
		for i in reversed(range(len(qubits))):
			qc.h(qubits[i])
			for j in reversed(range(i)):
				qc.cp(coef / 2**(i - j), qubits[j], qubits[i])
		for i in range(len(qubits) // 2):
			qc.swap(qubits[i], qubits[len(qubits) - 1 - i])
	return qc

def solve(n, m, L, s, theta) -> QuantumCircuit:
	x, y = QuantumRegister(n), QuantumRegister(m)
	qc = QuantumCircuit(x, y)
	from numpy import pi
	for j in range(m):
		qc.h(y[j])
	for i in range(n):
		for j in range(m):
			qc.cp(pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	apply_QFT(qc, y, inverse = True)
	if m == 1:
		if L == 0:
			qc.x(y[0])
		qc.p(theta, y[0])
		if L == 0:
			qc.x(y[0])
	else:
		for j in range(m):
			if ~L >> j & 1:
				qc.x(y[j])
		qc.mcp(theta, list(range(m - 1)), m - 1)
		for j in range(m):
			if ~L >> j & 1:
				qc.x(y[j])
	apply_QFT(qc, y)
	for i in range(n):
		for j in range(m):
			qc.cp(-pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	for j in range(m):
		qc.h(y[j])
	return qc
'''


'''python
from qiskit import QuantumRegister, QuantumCircuit

# Let n = len(qubits)
# if no ctrl_qubits, adds 2 * len(qubits) circuit depth
# otherwise,
#  if n % 2 == 0, adds n * (n/2 + 1) circuit depth
#  otherwise, adds (n-1) * ((n-1)/2 + 1) + n circuit depth
def apply_QFT(qc, qubits, ctrl_qubit = None, inverse = False):
	from numpy import pi
	coef = -pi if inverse else pi
	if ctrl_qubit:
		for i in reversed(range(len(qubits))):
			qc.ch(ctrl_qubit, qubits[i])
			for j in reversed(range(i)):
				qc.mcp(coef / 2**(i - j), [ctrl_qubit, qubits[j]], qubits[i])
		for i in range(len(qubits) // 2):
			qc.cswap(ctrl_qubit, qubits[i], qubits[len(qubits) - 1 - i])
	else:
		for i in reversed(range(len(qubits))):
			qc.h(qubits[i])
			for j in reversed(range(i)):
				qc.cp(coef / 2**(i - j), qubits[j], qubits[i])
		for i in range(len(qubits) // 2):
			qc.swap(qubits[i], qubits[len(qubits) - 1 - i])
	return qc

def solve(n, m, L, s, theta) -> QuantumCircuit:
	x, y = QuantumRegister(n), QuantumRegister(m)
	qc = QuantumCircuit(x, y)
	from numpy import pi
	for j in range(m):
		qc.h(y[j])
	for i in range(n):
		for j in range(m):
			qc.cp(pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	apply_QFT(qc, y, inverse = True)
	if m == 1:
		if L == 0:
			qc.x(y[0])
		qc.p(theta, y[0])
		if L == 0:
			qc.x(y[0])
	else:
		for j in range(m):
			if ~L >> j & 1:
				qc.x(y[j])
		qc.mcp(theta, y[:m - 1], y[m - 1])
		for j in range(m):
			if ~L >> j & 1:
				qc.x(y[j])
	apply_QFT(qc, y)
	for i in range(n):
		for j in range(m):
			qc.cp(-pi * s[i] / 2**(m - 1 - j), x[i], y[j])
	for j in range(m):
		qc.h(y[j])
	return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    # Compute the function f(x) using controlled additions
    for i in range(n):
        if S[i] != 0:
            for j in range(m):
                if (S[i] >> j) & 1:
                    qc.cx(x[i], y[j])

    # Create the comparison register
    comparison = QuantumRegister(m, 'comparison')
    qc.add_register(comparison)

    # Initialize the comparison register to the value L
    for j in range(m):
        if (L >> j) & 1:
            qc.x(comparison[j])

    # Apply a controlled phase shift based on the comparison
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], comparison[j])

    # Apply phase shift based on comparison
    qc.append(QuantumCircuit(m).compose(QuantumCircuit(m, name='phase_shift'), inplace=False), comparison)
    qc.rz(2 * np.pi * theta, comparison)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    # Compute the function f(x) using controlled additions
    for i in range(n):
        if S[i] != 0:
            for j in range(m):
                if (S[i] >> j) & 1:
                    qc.cx(x[i], y[j])

    # Create the comparison register
    comparison = QuantumRegister(m, 'comparison')
    qc.add_register(comparison)

    # Initialize the comparison register to the value L
    for j in range(m):
        if (L >> j) & 1:
            qc.x(comparison[j])

    # Apply a controlled phase shift based on the comparison
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], comparison[j])

    # Apply phase shift based on comparison
    qc.append(QuantumCircuit(m).compose(QuantumCircuit(m, name='phase_shift'), inplace=False), comparison)
    qc.rz(2 * np.pi * theta, comparison)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for i in range(2**n):
        # Compute f(x) for the current x
        f_x = sum(S[j] * ((i >> j) & 1) for j in range(n))
        f_x_mod = f_x % (2**m)

        # Apply phase shift if f(x) == L (mod 2^m)
        if f_x_mod == L:
            # Apply phase shift to |x⟩ and |0⟩ (for simplicity, we use the gate directly)
            angle = 2 * np.pi * theta / (2 ** m)
            qc.u1(angle, y[0])  # Apply phase shift to the first qubit in y
            # Note: This is a simplified example. For a full implementation, controlled phase operations are needed.

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # Step 1: Compute f(x) in the y register
    for i in range(n):
        for j in range(m):
            if (S[i] & (1 << j)) != 0:
                qc.cx(x[i], y[j])

    # Step 2: Compare f(x) with L
    for j in range(m):
        if (L & (1 << j)) == 0:
            qc.x(y[j])

    # Step 3: Apply controlled phase rotation
    qc.mcry(theta, y[:], x[n-1])

    # Step 4: Uncompute steps 2 and 1
    for j in range(m):
        if (L & (1 << j)) == 0:
            qc.x(y[j])

    for i in range(n-1, -1, -1):
        for j in range(m-1, -1, -1):
            if (S[i] & (1 << j)) != 0:
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    # Step 1: Compute f(x) in the y register
    for i in range(n):
        for j in range(m):
            if (S[i] & (1 << j)) != 0:
                qc.cx(x[i], y[j])

    # Step 2: Compare f(x) with L
    for j in range(m):
        if (L & (1 << j)) == 0:
            qc.x(y[j])

    # Step 3: Apply controlled phase rotation
    qc.mcry(theta, y[:], x[n-1])

    # Step 4: Uncompute steps 2 and 1
    for j in range(m):
        if (L & (1 << j)) == 0:
            qc.x(y[j])

    for i in range(n-1, -1, -1):
        for j in range(m-1, -1, -1):
            if (S[i] & (1 << j)) != 0:
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x = QuantumRegister(n, 'x')
    y = QuantumRegister(m, 'y')
    qc = QuantumCircuit(x, y)

    # Step 1: Compute f(x) = S0*x0 + S1*x1 + ... + Sn-1*xn-1
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    # Step 2: Compare f(x) mod 2^m with L
    L_bin = format(L, f'0{m}b')
    for j in range(m):
        if L_bin[j] == '0':
            qc.x(y[j])

    # Step 3: Apply the phase shift theta if comparison is successful
    qc.mcx(y, y[0])  # Multi-controlled X gate on ancilla to check if f(x) == L mod 2^m
    qc.p(theta, y[0])  # Apply the phase shift

    # Step 4: Reverse the comparison operation to uncompute ancilla qubits
    qc.mcx(y, y[0])

    # Reverse Step 2
    for j in range(m):
        if L_bin[j] == '0':
            qc.x(y[j])

    # Reverse Step 1: Uncompute f(x)
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x = QuantumRegister(n, 'x')
    y = QuantumRegister(m, 'y')
    qc = QuantumCircuit(x, y)

    # Step 1: Compute f(x) = S0*x0 + S1*x1 + ... + Sn-1*xn-1
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    # Step 2: Compare f(x) mod 2^m with L
    L_bin = format(L, f'0{m}b')
    for j in range(m):
        if L_bin[j] == '0':
            qc.x(y[j])

    # Step 3: Apply the phase shift theta if comparison is successful
    # Use an ancilla qubit for the multi-controlled phase shift
    if m > 1:
        ancilla = QuantumRegister(1, 'ancilla')
        qc.add_register(ancilla)
        qc.mcx(y, ancilla[0])  # Multi-controlled X gate to check if f(x) == L mod 2^m
        qc.p(theta, ancilla[0])  # Apply the phase shift
        qc.mcx(y, ancilla[0])  # Uncompute the ancilla
    else:
        qc.p(theta, y[0])  # For m=1, we directly apply the phase shift without ancilla

    # Step 4: Reverse the comparison operation to uncompute ancilla qubits
    for j in range(m):
        if L_bin[j] == '0':
            qc.x(y[j])

    # Reverse Step 1: Uncompute f(x)
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x = QuantumRegister(n, 'x')
    y = QuantumRegister(m, 'y')
    qc = QuantumCircuit(x, y)

    # Step 1: Compute f(x) = S0*x0 + S1*x1 + ... + Sn-1*xn-1
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    # Step 2: Compare f(x) mod 2^m with L
    L_bin = format(L, f'0{m}b')
    for j in range(m):
        if L_bin[j] == '0':
            qc.x(y[j])

    # Step 3: Apply the phase shift theta if comparison is successful
    qc.mcx(y[:-1], y[-1])  # Multi-controlled X gate on y[0:m-1] controlling y[m-1]
    qc.p(theta, y[-1])     # Apply the phase shift to the last qubit in y register
    qc.mcx(y[:-1], y[-1])  # Uncompute the mcx operation

    # Step 4: Reverse the comparison operation to uncompute ancilla qubits
    for j in range(m):
        if L_bin[j] == '0':
            qc.x(y[j])

    # Reverse Step 1: Uncompute f(x)
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x = QuantumRegister(n, 'x')
    y = QuantumRegister(m, 'y')
    qc = QuantumCircuit(x, y)

    # Step 1: Calculate f(x) = S0*x0 + S1*x1 + ... + Sn-1*xn-1
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    # Step 2: Apply an X gate to y qubits where L has a 0 in the binary representation
    L_bin = format(L, f'0{m}b')
    for j in range(m):
        if L_bin[j] == '0':
            qc.x(y[j])

    # Step 3: Apply the phase shift theta if f(x) == L (mod 2^m)
    qc.mcx(list(y), y[0])  # Multi-controlled X gate on all y qubits controlling y[0]
    qc.p(theta, y[0])      # Apply the phase shift to y[0] if the condition is satisfied
    qc.mcx(list(y), y[0])  # Uncompute the mcx operation to maintain reversibility

    # Step 4: Reverse the X gates to restore y qubits to their original state
    for j in range(m):
        if L_bin[j] == '0':
            qc.x(y[j])

    # Step 5: Reverse the computation of f(x) by applying CX gates again
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # Calculate the target value of f(x)
    target_value = L % (2 ** m)

    # Add a quantum phase oracle
    # This requires applying controlled phase shifts based on S
    for i in range(n):
        if S[i] != 0:
            qc.cx(x[i], y[0])  # Example, use controlled-X gates here as placeholders

    # Apply a conditional phase gate
    # We need to encode the function and apply the phase based on the result
    qc.append(
        # Replace with actual implementation
        # Controlled phase gate applying e^{i*theta} if f(x) == L (mod 2^m)
        QuantumCircuit(m).to_gate().control(n),
        [*x, *y]
    )

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x = QuantumRegister(n, name='x')
    y = QuantumRegister(m, name='y')
    qc = QuantumCircuit(x, y)

    # Calculate f(x) = S0 * x0 + S1 * x1 + ... + Sn-1 * xn-1
    # Encode the phase flip for f(x) = L mod 2^m

    # Define the value to compare against
    target_value = L % (2 ** m)

    # Add phase flip for f(x) == target_value
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:  # Check if the j-th bit of S[i] is 1
                qc.cx(x[i], y[j])  # Controlled-X gate

    # Apply the conditional phase shift
    # We will use a phase flip if f(x) == target_value
    for k in range(m):
        if ((target_value >> k) & 1) == 1:
            qc.rz(2 * theta, y[k])  # Apply the phase shift to the y register

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit import Gate
from qiskit.circuit.library import ZGate, PhaseGate, U1

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # Define the function f(x) using an auxiliary qubit
    aux = QuantumRegister(1)
    qc.add_register(aux)

    # Apply the controlled operations to implement f(x) = L
    # Create the controlled addition circuit
    qc.add_register(QuantumRegister(n + m + 1))

    # Apply the controlled addition
    for i in range(n):
        if S[i] != 0:
            qc.cx(x[i], aux[0])  # Controlled NOT gate (used for addition)
            qc.rz(2 * S[i] * theta, aux[0])

    # Apply the phase gate to |x⟩_n |0⟩_m if f(x) = L
    qc.append(PhaseGate(theta), [aux[0]])

    # Clean up: Remove auxiliary qubit
    qc.remove_register(aux)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x = QuantumRegister(n, name='x')
    y = QuantumRegister(m, name='y')
    qc = QuantumCircuit(x, y)

    # Adding an ancillary qubit for the phase application
    aux = QuantumRegister(1, name='aux')
    qc.add_register(aux)

    # Initialize auxiliary qubit to |1>
    qc.x(aux[0])

    # Apply the addition of S coefficients
    for i in range(n):
        if S[i] != 0:
            # Apply a controlled-phase gate to simulate the effect of S[i]
            qc.cp(2 * np.pi * S[i] / (2**m), x[i], aux[0])

    # Apply the phase gate based on theta
    qc.append(PhaseGate(theta), [aux[0]])

    # Clean up: Remove auxiliary qubit
    qc.remove_register(aux)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    # Define quantum registers
    x = QuantumRegister(n, name='x')  # Input register
    y = QuantumRegister(m, name='y')  # Output register

    # Create quantum circuit
    qc = QuantumCircuit(x, y)

    # To implement f(x) = S0*x0 + S1*x1 + ... + Sn-1*xn-1 (mod 2^m)
    # Use an additional auxiliary qubit for phase application
    aux = QuantumRegister(1, name='aux')
    qc.add_register(aux)

    # Initialize auxiliary qubit to |1>
    qc.x(aux[0])

    # Apply the function f(x) as controlled addition
    for i in range(n):
        if S[i] != 0:
            for j in range(m):
                # Apply controlled addition for each bit of y
                qc.cu1(np.pi * S[i] / (2 ** j), x[i], y[j])

    # Apply phase shift if f(x) = L (mod 2^m)
    qc.append(QuantumCircuit(*y, *aux).u1(theta, aux[0]), [aux[0]])

    # Clean up: Remove auxiliary qubit
    qc.remove_register(aux)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import PhaseGate

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x = QuantumRegister(n, name='x')
    y = QuantumRegister(m, name='y')
    qc = QuantumCircuit(x, y)

    # Define the auxiliary qubit
    aux = QuantumRegister(1, name='aux')
    qc.add_register(aux)

    # Initialize auxiliary qubit to |1>
    qc.x(aux[0])

    # Apply the function f(x) using controlled-phase gates
    # To simulate f(x) mod 2^m using controlled gates
    for i in range(n):
        if S[i] != 0:
            for j in range(m):
                qc.cx(x[i], y[j])  # Apply controlled X gates
                qc.rz(2 * np.pi * S[i] / (2**m), y[j])  # Apply rotation for phase

    # Apply phase shift theta if f(x) = L (mod 2^m)
    qc.append(PhaseGate(theta), [aux[0]])

    # Clean up auxiliary qubit
    qc.remove_register(aux)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library import MCXGate, PhaseGate
import numpy as np

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    # Quantum registers
    x = QuantumRegister(n, name='x')
    y = QuantumRegister(m, name='y')
    qc = QuantumCircuit(x, y)

    # Create an additional auxiliary qubit for phase application
    aux = QuantumRegister(1, name='aux')
    qc.add_register(aux)

    # Initialize auxiliary qubit to |1>
    qc.x(aux[0])

    # Apply the function f(x) = S0*x0 + S1*x1 + ... + Sn-1*xn-1 mod 2^m
    # Here we use controlled additions to accumulate the result in the y register
    for i in range(n):
        if S[i] != 0:
            for j in range(m):
                qc.cx(x[i], y[j])
                qc.rz(2 * np.pi * S[i] / (2 ** j), y[j])

    # Apply phase shift if f(x) = L mod 2^m
    phase_shift = np.exp(1j * theta)
    for k in range(m):
        if (L >> k) & 1:
            qc.cx(aux[0], y[k])
            qc.p(theta, y[k])

    # Cleanup: Remove auxiliary qubit
    qc.remove_register(aux)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    # Step 1: Compute f(x) and store in y register
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    # Step 2: Apply modular addition of L to the y register
    for j in range(m):
        if (L >> j) & 1:
            qc.x(y[j])

    # Step 3: Apply the controlled phase shift based on whether y equals 0 (i.e., f(x) = L mod 2^m)
    qc.append(QFT(m, do_swaps=False).inverse(), y)  # Apply inverse QFT to y
    qc.mcx(list(y), y[0])  # Apply multi-controlled X gate if y is in |0>
    qc.u1(theta, y[0])  # Apply phase shift of theta
    qc.mcx(list(y), y[0])  # Uncompute the multi-controlled X gate
    qc.append(QFT(m, do_swaps=False), y)  # Apply QFT to return y to original state

    # Step 4: Undo the modular addition of L
    for j in range(m):
        if (L >> j) & 1:
            qc.x(y[j])

    # Step 5: Uncompute f(x) from y register
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                qc.cx(x[i], y[j])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from math import pi

def r(qc:QuantumCircuit, ctrl:int, targ:int, l:int):
    angle = 2*math.pi(1<<l), ctrl, targ
    qc.cp(angle, ctrl,targ)

def qft(n:int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1,i)
        qc.cx(i,n-i-1)
    for i in range(0,n):
        qc.h(i)
        for j in range(1, n-1):
            r(qc, i+j, i, j+1)
    return qc

def B_6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for i in range(m):
        for j in range(n):
            theta = 2*math.pi*S[j]/(1<<m)*(1<<i)
            qc.cp(theta, y[i], x[j])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def B_2(n:int, L:int, theta:float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    c= n*[0]
    for a in range(n):
        b[a]=L%2
        L//=2
    for d in range(n):
        if b[d]==0:
            qc.x(d)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if b[i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(B_6(n, m, S))
    qc = qc.compose(B_2(m, L, theta), y)
    qc = qc.compose(B_6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from math import pi

def r(qc:QuantumCircuit, ctrl:int, targ:int, l:int):
    angle = 2*math.pi(1<<l), ctrl, targ
    qc.cp(angle, ctrl,targ)

def qft(n:int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1,i)
        qc.cx(i,n-i-1)
    for i in range(0,n):
        qc.h(i)
        for j in range(1, n-1):
            r(qc, i+j, i, j+1)
    return qc

def B_6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for i in range(m):
        for j in range(n):
            theta = 2*math.pi*S[j]/(1<<m)*(1<<i)
            qc.cp(theta, y[i], x[j])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def B_2(n:int, L:int, theta:float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    c= n*[0]
    for a in range(n):
        c[a]=L%2
        L//=2
    for d in range(n):
        if c[d]==0:
            qc.x(d)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if c[i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(B_6(n, m, S))
    qc = qc.compose(B_2(m, L, theta), y)
    qc = qc.compose(B_6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from math import pi

def r(qc:QuantumCircuit, ctrl:int, targ:int, l:int):
    angle = 2*math.pi(1<<l)
    qc.cp(angle, ctrl,targ)

def qft(n:int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1,i)
        qc.cx(i,n-i-1)
    for i in range(0,n):
        qc.h(i)
        for j in range(1, n-1):
            r(qc, i+j, i, j+1)
    return qc

def B_6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for i in range(m):
        for j in range(n):
            theta = 2*math.pi*S[j]/(1<<m)*(1<<i)
            qc.cp(theta, y[i], x[j])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def B_2(n:int, L:int, theta:float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    c= n*[0]
    for a in range(n):
        c[a]=L%2
        L//=2
    for d in range(n):
        if c[d]==0:
            qc.x(d)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if [i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(B_6(n, m, S))
    qc = qc.compose(B_2(m, L, theta), y)
    qc = qc.compose(B_6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from math import pi

def r(qc:QuantumCircuit, ctrl:int, targ:int, l:int):
    angle = 2*math.pi(1<<l)
    qc.cp(angle, ctrl,targ)

def qft(n:int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1,i)
        qc.cx(i,n-i-1)
    for i in range(0,n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def B_6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for i in range(m):
        for j in range(n):
            theta = 2*math.pi*S[j]/(1<<m)*(1<<i)
            qc.cp(theta, y[i], x[j])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def B_2(n:int, L:int, theta:float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    c= n*[0]
    for a in range(n):
        c[a]=L%2
        L//=2
    for d in range(n):
        if c[d]==0:
            qc.x(d)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if [i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(B_6(n, m, S))
    qc = qc.compose(B_2(m, L, theta), y)
    qc = qc.compose(B_6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from math import pi

def r(qc:QuantumCircuit, control:int, target:int, l:int):
    angle = 2*math.pi(1<<l)
    qc.cp(angle, control, target)

def qft(n:int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def B_6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for i in range(m):
        for j in range(n):
            qc.cp(2*math.pi*S[j]/(1<<m)*(1<<i), y[i], x[j])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def B_2(n:int, L:int, theta:float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    c= [0]*n
    for a in range(n):
        c[a]=L%2
        L//=2
    for a in range(n):
        if c[a]==0:
            qc.x(a)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if [i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(B_6(n, m, S))
    qc = qc.compose(B_2(m, L, theta), y)
    qc = qc.compose(B_6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    angle = 2*math.pi(1<<l)
    qc.cp(angle, control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def B_6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for i in range(m):
        for j in range(n):
            qc.cp(2*math.pi*S[j]/(1<<m)*(1<<i), y[i], x[j])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def B_2(n:int, L:int, theta:float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    c= [0]*n
    for a in range(n):
        c[a]=L%2
        L//=2
    for a in range(n):
        if c[a]==0:
            qc.x(a)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if [i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(B_6(n, m, S))
    qc = qc.compose(B_2(m, L, theta), y)
    qc = qc.compose(B_6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    #angle = 2*math.pi(1<<l)
    qc.cp(2*math.pi(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k), y[k], x[i])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n:int, L:int, theta:float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    c= [0]*n
    for a in range(n):
        c[a]=L%2
        L//=2
    for a in range(n):
        if c[a]==0:
            qc.x(a)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if [i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(m, L, theta), y)
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    #angle = 2*math.pi(1<<l)
    qc.cp(2*math.pi/(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k), y[k], x[i])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    b=[0]*n
    for i in range(n):
        b[i]=L%2
        L//=2
    for i in range(n):
        if b[i]==0:
            qc.x(i)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if b[i]==0:
            qc.x(i)

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(m, L, theta), y)
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    angle = 2*math.pi(1<<l)
    qc.cp(angle, control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for i in range(m):
        for j in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<i), y[i], x[j])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    c=[0]*n
    for i in range(n):
        c[i]=L%2
        L//=2
    for i in range(n):
        if c[i]==0:
            qc.x(i)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if c[i]==0:
            qc.x(i)
    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(m, L, theta), y)
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    #angle = 2*math.pi(1<<l)
    qc.cp(2*math.pi(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k, y[k], x[i])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    b=[0]*n
    for i in range(n):
        b[i]=L%2
        L//=2
    for i in range(n):
        if b[i]==0:
            qc.x(i)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if b[i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(m, L, theta), y)
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    #angle = 2*math.pi(1<<l)
    qc.cp(2*math.pi(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n:int, m:int, S:list[int]) -> QuantumCircuit:
    x = QuantumRegister(n)
    y = QuantumRegister(m)
    qc = QuantumCircuit(x,y)

    #Appy superposition gate on y-reg
    qc.h(y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k), y[k], x[i])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    b=[0]*n
    for i in range(n):
        b[i]=L%2
        L//=2
    for i in range(n):
        if b[i]==0:
            qc.x(i)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if b[i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(m, L, theta), y)
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    qc.cp(2*math.pi/(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc.h(y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k), y[k], x[i])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    b=[0]*n
    for i in range(n):
        b[i]=L%2
        L//=2
    for i in range(n):
        if b[i]==0:
            qc.x(i)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if b[i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(m, L, theta), y)
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

from qiskit import QuantumCircuit

def B2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n):
        if not (L>>i & 1):
            qc.x(i)
    if n==1:
        qc.p(theta, 0)
    else:
        qc.mcp(theta, list(range(n-1)), n-1)
    for i in range(n):
        if not (L>>i & 1):
            qc.x(i)
    return qc

def QFT(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n):
        qc.h(n-i-1)
        for j in range(1, n-i):
            qc.cp(math.pi/2**j, n-i-j-1, n-i-1)
    for i in range(n//2):
        qc.swap(i, n-i-1)
    return qc

def IQFT(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n):
        qc.h(n-i-1)
        for j in range(1, n-i):
            qc.cp(-math.pi/2**j, n-i-j-1, n-i-1)
    for i in range(n//2):
        qc.swap(i, n-i-1)
    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    for j in range(m):
        qc.h(y[j])
        # Oracle B5
        for i in range(n):
            qc.cp(2*math.pi*S[i]*2**j/2**m, y[j], x[i])
    # IQFT
    qc.compose(IQFT(m), y, inplace=True)

    qc.compose(B2(m, L, theta), y, inplace=True)

    # QFT
    qc.compose(QFT(m), y, inplace=True)

    for j in range(m):
        # Oracle B5(minus)
        for i in range(n):
            qc.cp(-2*math.pi*S[i]*2**j/2**m, y[j], x[i])

    # IQFT
    qc.compose(IQFT(m), y, inplace=True)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    qc.cp(2*math.pi/(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc.h(y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k), y[k], x[i])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    b=[0]*n
    for i in range(n):
        b[i]=L%2
        L//=2
    for i in range(n):
        if b[i]==0:
            qc.x(i)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if b[i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(n, L, theta))
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math

def r(qc: QuantumCircuit, control: int, target: int, l: int):
    qc.cp(2*math.pi/(1<<l), control, target)

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n//2):
        qc.cx(i, n-i-1)
        qc.cx(n-i-1, i)
        qc.cx(i, n-i-1)
    for i in range(0, n):
        qc.h(i)
        for j in range(1, n-i):
            r(qc, i+j, i, j+1)
    return qc

def b6(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc.h(y)
    for k in range(m):
        for i in range(n):
            qc.cp(2*math.pi*S[i]/(1<<m)*(1<<k), y[k], x[i])
    qc = qc.compose(qft(m).inverse(), y)

    return qc

def b2(n: int, L: int, theta: float) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:
    b=[0]*n
    for i in range(n):
        b[i]=L%2
        L//=2
    for i in range(n):
        if b[i]==0:
            qc.x(i)
    if n>1:
        qc.mcp(theta, list(range(n-1)), n-1)
    else:
        qc.p(theta, 0)
    for i in reversed(range(n)):
        if b[i]==0:
            qc.x(i)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    qc = qc.compose(b6(n, m, S))
    qc = qc.compose(b2(n, L, theta), y)
    qc = qc.compose(b6(n, m, S).inverse())

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def PS_oracle(n, L, theta):

    qc = QuantumCircuit(n)
    # Write your code here:
    #for i in range(n):
    #   qc.h(i)

    binary = bin(L)
    ctrl_state = binary[-1:1:-1]

    print(ctrl_state)

    ctrl_state = ctrl_state + (n - len(ctrl_state))*'0'
    print(ctrl_state)

    print(ctrl_state[0])

    if n > 1:

        if ctrl_state[0] == '0':
            ctrl_state = ctrl_state[-1:0:-1]
            print(ctrl_state)
            qc.x(0)
            qc.mcp(theta, control_qubits= [i for i in range(1,n)] , ctrl_state = ctrl_state,target_qubit= 0)
            qc.x(0)

        else :
            ctrl_state = ctrl_state[-1:0:-1]
            print(ctrl_state)
            qc.mcp(theta, control_qubits= [i for i in range(1,n)] , ctrl_state = ctrl_state,target_qubit= 0)

    #qc.measure_all()
    else :
        if L == 0:
            qc.x(0)
        qc.p(theta , 0)
        if L == 0:
            qc.x(0)

    return qc

def qft(n):
    qc = QuantumCircuit(n)

    thetas = []
    for k in range(0, 1+n):
        thetas.append(2 * math.pi / (2**k))

    for idx in range(0, n):
        qc.h(n-1-idx)
        for jdx in range(idx+1, n):
            thetaidx = jdx - idx + 1
            qc.cp(thetas[thetaidx], n-1-jdx, n-1-idx)

    for idx in range(0, n//2):
        qc.swap(idx, n-idx-1)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    qc.h(y)
    for idx in range(0, n):
        for jdx in range(0, m):
            theta = 2 * math.pi * S[idx] * (2**jdx) / (2**m)
            qc.cp(theta, x[idx], y[jdx])

    qc = qc.compose(qft(m).inverse(), y)
    qc = qc.compose(PS_oracle(m, L, theta), y)

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import math
import numpy as np

def PS_oracle(n, L, theta):

    qc = QuantumCircuit(n)
    # Write your code here:
    #for i in range(n):
    #   qc.h(i)

    binary = bin(L)
    ctrl_state = binary[-1:1:-1]

    print(ctrl_state)

    ctrl_state = ctrl_state + (n - len(ctrl_state))*'0'
    print(ctrl_state)

    print(ctrl_state[0])

    if n > 1:

        if ctrl_state[0] == '0':
            ctrl_state = ctrl_state[-1:0:-1]
            print(ctrl_state)
            qc.x(0)
            qc.mcp(theta, control_qubits= [i for i in range(1,n)] , ctrl_state = ctrl_state,target_qubit= 0)
            qc.x(0)

        else :
            ctrl_state = ctrl_state[-1:0:-1]
            print(ctrl_state)
            qc.mcp(theta, control_qubits= [i for i in range(1,n)] , ctrl_state = ctrl_state,target_qubit= 0)

    #qc.measure_all()
    else :
        if L == 0:
            qc.x(0)
        qc.p(theta , 0)
        if L == 0:
            qc.x(0)

    return qc

def qft(n):
    qc = QuantumCircuit(n)

    thetas = []
    for k in range(0, 1+n):
        thetas.append(2 * math.pi / (2**k))

    for idx in range(0, n):
        qc.h(n-1-idx)
        for jdx in range(idx+1, n):
            thetaidx = jdx - idx + 1
            qc.cp(thetas[thetaidx], n-1-jdx, n-1-idx)

    for idx in range(0, n//2):
        qc.swap(idx, n-idx-1)

    return qc

def solve(n: int, m: int, L: int, S: list[int], theta: float) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:

    qc.h(y)
    for idx in range(0, n):
        for jdx in range(0, m):
            theta = 2 * math.pi * S[idx] * (2**jdx) / (2**m)
            qc.cp(theta, x[idx], y[jdx])

    qc = qc.compose(qft(m).inverse(), y)
    qc = qc.compose(PS_oracle(m, L, theta), y)

    return qc
'''