'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library.standard_gates import XGate

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # i を control として y に S[i] を加算しないといけない
    for j in reversed(range(m)):
        for i in range(n):
            if S[i] & (1 << j):
                # y に (1 << j) を加算
                for k in range(n - 1, j, -1):
                    qc.append(XGate().control(k - j + 1), [i] + list(range(n + j, n + k + 1)))
                qc.cx(i, n + j)

    return qc

from qiskit.quantum_info import Statevector
if __name__ == "__main__":
    qc = solve(5, 5, [31, 31, 31, 31, 31])
    qc.draw('mpl').savefig('a.png')
    print(Statevector(qc))
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
from qiskit.circuit.library.standard_gates import XGate

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # i を control として y に S[i] を加算しないといけない
    for j in reversed(range(m)):
        for i in range(n):
            if S[i] & (1 << j):
                # y に (1 << j) を加算
                for k in range(n - 1, j, -1):
                    qc.append(XGate().control(k - j + 1), [i] + list(range(n + j, n + k + 1)))
                qc.cx(i, n + j)

    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, S: list[int]) -> 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 を逆フーリエ変換
    qc.append(QFT(m).inverse(), range(n, n + m))

    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, S: list[int]) -> 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 を逆フーリエ変換
    qc.append(QFT(m).inverse(), range(n, n + m))

    return qc.decompose()
'''


'''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, S: list[int]) -> 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])

    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] & (1 << j)) != 0:
                qc.cx(x[i], y[j])

    return qc
'''


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

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

    qc.reset(y)
    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])

    return qc
'''


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

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 gates
    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 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)

    qc.h(y)

    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 QuantumCircuit, QuantumRegister

import math

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)

    qc.h(y)

    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 QuantumCircuit
from qiskit.circuit.library.standard_gates  import PhaseGate
import math
def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
  qc = QuantumCircuit(n + m)
  qc.x(0)
  for i in range(m):
    qc.h(n + 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
from qiskit.circuit.library.standard_gates  import PhaseGate
import math
def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
  qc = QuantumCircuit(n + m)
  for i in range(m):
    qc.h(n + 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,m):
        qc.h(i)
    for i in range(n,m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**(i-n)), j, i)

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

    for i in range(n,m):
        for j in range(n,i):
            qc.cp(-np.pi/(2.0**(i-j)), k, i)
        qc.h(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,m):
        qc.h(i)
    for i in range(n,m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**(i-n)), j, i)

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

    for i in range(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

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**(i-n)), j, i)

    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

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,m):
        for j in range(n):
            qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**(i-n)), j, i)

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

    for i in range(n,nm):
        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

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

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

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

    for i in range(n,nm):
        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

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**(i-n)), j, i)

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

    # for i in range(n,nm):
    #     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

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**(i-n)), j, i)

    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

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**(i-n)), j, i)

    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

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.x(0)
    #         qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**(i-n)), j, i)

    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

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**(i-n)), j, i)

    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

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(np.pi, 0, 1)
            # qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**(i-n)), j, i)

    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

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.x(0)
            # qc.cp(np.pi, 0, 1)
            # qc.cp(2.0*np.pi/(2.0**m)*S[j]*(2.0**(i-n)), j, i)

    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**(i-n)), j, i)

    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**(i-n)), j, i)

    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**(i-n)), 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 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/S[j]*(2.0**((n-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 QuantumRegister, QuantumCircuit
from numpy import pi

def solve(n, m, s) -> QuantumCircuit:
	from qiskit.circuit.library import QFT
	x, y = QuantumRegister(n), QuantumRegister(m)
	qc = QuantumCircuit(x, y)
	for i in range(n):
		qc.append(QFT(m).control(1), [x[i]] + list(y))
		for j in range(m):
			qc.cp(2 * pi * s[i] / 2**(m - j), x[i], y[j])
		qc.append(QFT(m, inverse = True).control(1), [x[i]] + list(y))
	return qc
'''


'''python
from qiskit import QuantumRegister, QuantumCircuit

# Adds 2 * len(qubits) 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
	for i in range(n):
		apply_QFT(qc, y, x[i])
		for j in range(m):
			qc.cp(2 * pi * s[i] / 2**(m - j), x[i], y[j])
		apply_QFT(qc, y, x[i], inverse = True)
	return qc
'''


'''python
from qiskit import QuantumRegister, QuantumCircuit

# Adds 2 * len(qubits) 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
	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)
	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)

    # Implement the oracle
    for i in range(n):
        for j in range(m):
            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, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # Implement the oracle
    for i in range(n):
        si = S[i]
        for j in range(m):
            if si & 1:
                qc.cx(x[i], y[j])
            si >>= 1

        # Reverse the additions for qubits other than the least significant
        if i > 0:
            si = S[i]
            for j in range(m-1, 0, -1):
                if si & (1 << j):
                    for k in range(j):
                        qc.cx(y[j], y[k])

    return qc
'''


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

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

    # Implement f(x) using controlled rotations
    for i in range(n):
        for j in range(m):
            angle = (S[i] * 2**j * 2 * pi) / (2**m)
            qc.cry(angle, 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)

    # Implement f(x) using controlled additions
    for i in range(n):
        # Convert S[i] to binary representation
        si_binary = format(S[i], f'0{m}b')[::-1]  # Reverse for little-endian

        # Apply controlled-X gates for each bit of S[i]
        for j in range(m):
            if si_binary[j] == '1':
                qc.cx(x[i], y[j])

    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:
    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
'''


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

def calc_f(m: int, S: list[int], qc: QuantumCircuit, r: QuantumRegister) -> None:
    for i in range(len(r)):
        qc.p(2 * math.pi / (2 ** m) * S[i], r[i])

def inv_qft(qc: QuantumCircuit, r: QuantumRegister) -> None:
    n = len(r)

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

    for i in reversed(range(n)):
        for j in reversed(range(i + 1, n)):
            theta = 2 * math.pi / (2 ** (j - i + 1))
            qc.cp(- theta, r[n - 1 - j], r[n - 1 - i])
        qc.h(r[n - 1 - 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:
    calc_f(m, S, qc, x)
    inv_qft(qc, y)
    return qc
'''


'''python
from qiskit import QuantumCircuit
import math

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:

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

    # swap
    for i in range(n // 2):
        qc.swap(i, n - 1 - 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.h(y)
    for j in range(m):
        for i in range(n):
            qc.cp(2 * math.pi / (2 ** m) * S[i] * (2 ** j), y[j], x[i])

    qc.compose(qc_f, x, inplace=True)
    qc.copmose(qft(m).inverse(), y, inplace=True)
    return qc
'''


'''python
from qiskit import QuantumCircuit
import math

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:

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

    # swap
    for i in range(n // 2):
        qc.swap(i, n - 1 - 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.h(y)
    for j in range(m):
        for i in range(n):
            qc.cp(2 * math.pi / (2 ** m) * S[i] * (2 ** j), y[j], x[i])
    qc.copmose(qft(m).inverse(), y, inplace=True)
    return qc
'''


'''python
from qiskit import QuantumCircuit
import math

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:

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

    # swap
    for i in range(n // 2):
        qc.swap(i, n - 1 - 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.h(y)
    for j in range(m):
        for i in range(n):
            qc.cp(2 * math.pi / (2 ** m) * S[i] * (2 ** j), y[j], x[i])
    qc.compose(qft(m).inverse(), y, inplace=True)
    return qc
'''


'''python
from qiskit import QuantumCircuit
import math

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)
    # Write your code here:
    qc.h(y)
    for j in range(m):
        for i in range(n):
            qc.cp(2 * math.pi / (2 ** m) * S[i] * (2 ** j), y[j], x[i])
    qc.compose(qft(m).inverse(), y, inplace=True)
    return qc
'''


'''python
from qiskit import QuantumCircuit
import math

def qft(n: int) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    # Write your code here:

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

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

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

    qc.h(y)

    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 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 X gates to flip the bits of y that correspond to non-zero coefficients in S
    for i in range(n):
        if S[i] != 0:
            qc.x(y[S[i] % m])

    # Apply controlled-X gates to compute the sum modulo 2^m
    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                (link unavailable)(x[i], y[j])

    # Apply X gates again to flip the bits of y back
    for i in range(n):
        if S[i] != 0:
            qc.x(y[S[i] % m])
    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)
    for i in range(len(S)):
        for j in range(m):
            if (S[i]&(1<<j)) > 0:
                for k in range(m-1, j, -1):
                    qc.h(n+k)
                    qc.mcp(math.pi, list(range(n,n+k)), n+k)
                    qc.h(n+k)
                qc.x(n+j)
    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)
    for i in range(len(S)):
        for j in range(m):
            if (S[i]&(1<<j)) > 0:
                for k in range(m-1, j-1, -1):
                    qc.h(n+k)
                    qc.mcp(math.pi, [i, **(list(range(n+j,n+k))) ], n+k)
                    qc.h(n+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)
    for i in range(len(S)):
        for j in range(m):
            if (S[i]&(1<<j)) > 0:
                for k in range(m-1, j-1, -1):
                    qc.h(n+k)
                    qc.mcp(math.pi, [i, *(list(range(n+j,n+k))) ], n+k)
                    qc.h(n+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)
    for i in range(len(S)):
        for j in range(m-1, 0, -1):
            rem = (1<<j)-S[i]%(1<<j)
            for k in range(j-1, -1, -1):
                if rem >= (1<<k):
                    qc.mpc(math.pi, [ i, *(list(range(n+j-1, n+k-1, -1))) ], n+j)
                    if k > 0:
                        rem -= (1<<k)
                        qc.x(n+k)
            rem = (1<<j)-S[i]%(1<<j)
            for k in range(j-1, -1, -1):
                if rem >= (1<<k):
                    if k > 0:
                        rem -= (1<<k)
                        qc.x(n+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)
    for i in range(len(S)):
        for j in range(m-1, 0, -1):
            qc.h(n+j)
            rem = (1<<j)-S[i]%(1<<j)
            for k in range(j-1, -1, -1):
                if rem <= (1<<k):
                    qc.mpc(math.pi, [ i, *(list(range(n+j-1, n+k-1, -1))) ], n+j)
                    if k > 0:
                        qc.x(n+k)
                else:
                    rem -= (1<<k)
            rem = (1<<j)-S[i]%(1<<j)
            for k in range(j-1, -1, -1):
                if rem > (1<<k):
                    rem -= (1<<k)
                else if k > 0:
                    qc.x(n+k)
            qc.h(n+j)
            if (S[i]&(1<<j)) > 0:
                qc.cx(i, n+j)
        if S[i]%2 == 1:
            qc.cx(i, n)
    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)
    for i in range(len(S)):
        for j in range(m-1, 0, -1):
            qc.h(n+j)
            rem = (1<<j)-S[i]%(1<<j)
            for k in range(j-1, -1, -1):
                if rem <= (1<<k):
                    qc.mcp(math.pi, [ i, *(list(range(n+j-1, n+k-1, -1))) ], n+j)
                    if k > 0:
                        qc.x(n+k)
                else:
                    rem -= (1<<k)
            rem = (1<<j)-S[i]%(1<<j)
            for k in range(j-1, -1, -1):
                if rem > (1<<k):
                    rem -= (1<<k)
                elif k > 0:
                    qc.x(n+k)
            qc.h(n+j)
            if (S[i]&(1<<j)) > 0:
                qc.cx(i, n+j)
        if S[i]%2 == 1:
            qc.cx(i, n)
    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.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)
    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister
import qiskit.circuit.library as qlib
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):
        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 qiskit.circuit.library as qlib
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(min(n, m)):
        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 qiskit.circuit.library as qlib
import numpy as np

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    now = 0
    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 qiskit.circuit.library as qlib
import numpy as np

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

    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1:
                for k in range(j + 1, m):
                    if (S[i] >> k) & 1:
                        qc.cx(y[k], y[j])

    return qc
'''


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

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

    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] & (1<<m):
                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)

    for i in range(2**n):
        j = 0
        for k in range(n):
            j += ((i >> k) & 1) * S[k]
        j %= 2**m

        if i == j:
            continue

        for k in range(n):
            if (i >> k) & 1 == 0:
                qc.x(x[k])

        for k in range(m):
            if (j >> k) & 1 == 1:
                qc.mcx(x, y[k])

        for k in range(n):
            if (i >> k) & 1 == 0:
                qc.x(x[k])

    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)

    for i in range(n):
        for j in range(m):
            if (S[i] >> j) & 1 == 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)

    for i in reversed(range(n)):
        for j in range(m):
            if (S[i] >> j) & 1 == 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:

    import math

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

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

    qc.compose(qft(n), inplace=True, qubits=x)

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

    qc.compose(qft(n).inverse(), inplace=True, qubits=x)

    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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[i])

    qc.compose(qft(n), inplace=True, qubits=x)

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

    qc.compose(qft(n).inverse(), inplace=True, qubits=x)

    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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[i])

    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)

    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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[i])

    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)

    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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        # for i in range(n // 2):
        #     qc.swap(i, n - 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, y[i])
            # qc.rz(math.pi * k / 2**i, y[i])

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

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

    qc.compose(qft(m).inverse(), inplace=True, qubits=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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[i])
            # qc.rz(math.pi * k / 2**i, y[i])

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

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

    qc.compose(qft(m).inverse(), inplace=True, qubits=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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[i])
            # qc.rz(math.pi * k / 2**i, y[i])

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

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

    qc.compose(qft(m).inverse(), inplace=True, qubits=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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[i])
            # qc.rz(math.pi * k / 2**i, y[i])

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

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

    qc.compose(qft(m).inverse(), inplace=True, qubits=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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[i])
            # qc.rz(math.pi * k / 2**i, y[i])

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

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

    qc.compose(qft(m).inverse(), inplace=True, qubits=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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[m - i - 1])

    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)

    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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[m - i - 1])

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

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

    qc.compose(qft(m).inverse(), inplace=True, qubits=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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[m - i - 1])

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

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

    qc.compose(qft(m).inverse(), inplace=True, qubits=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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        # for i in range(n // 2):
        #     qc.swap(i, n - 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, y[m - 1 - i])

    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)

    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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[i])

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

    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

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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[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

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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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, y[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

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(n: int) -> QuantumCircuit:
        qc = QuantumCircuit(n)
        for i in range(n):
            qc.h(i)
            rotation = math.pi / 2
            for j in range(i + 1, n):
                qc.cp(rotation, j, i)
                rotation /= 2
        for i in range(n // 2):
            qc.swap(i, n - 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(2 * math.pi * k / 2**i, control, y[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

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, y[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

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

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

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[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

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

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

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, i, j)
                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

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, i, j)
                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 ** (m - 1 - 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

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)
    # Write your code here:
    S = S[::-1]
    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, i, j)
                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[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

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, i, j)
                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[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)

    qc.measure_all()
    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, i, j)
                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(len(y)):
            qc.crz(math.pi * k / (2**i), control_qubit=control, target_qubit=y[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

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, i, j)
                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(len(y)):
            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)
    # swap_qubits(qc, y)

    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

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, i, j)
                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(len(y)):
            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)
    # swap_qubits(qc, y)

    # qc.compose(qft(m), inplace=True, qubits=y)
    qc.append(qft(m).to_gate().inverse(), qargs=y)

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

    # qc.compose(qft(m).inverse(), inplace=True, qubits=y)
    qc.append(qft(m).to_gate().inverse(), qargs=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, i, j)
                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(len(y)):
            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)
    # swap_qubits(qc, y)

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

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

    qc = qc.compose(qft(m).inverse(), 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, i, j)
                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(
        c: QuantumCircuit, k: int, control: QuantumRegister
    ) -> QuantumCircuit:
        for i in range(len(y)):
            c.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)
    # swap_qubits(qc, y)

    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, x)
    # 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, i, j)
                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(
        c: QuantumCircuit, k: int, control: QuantumRegister
    ) -> QuantumCircuit:
        for i in range(len(y)):
            c.crz(math.pi * k / (2**i), control_qubit=control, target_qubit=y[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)
    swap_qubits(qc, y)

    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, x)
    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, i, j)
                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(c: QuantumCircuit, k: int, control: QuantumRegister) -> QuantumCircuit:
        for i in range(len(y)):
            c.crz(math.pi * k / (2**i), control_qubit=control, target_qubit=y[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)
    # swap_qubits(qc, y)

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

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

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

    # swap_qubits(qc, x)
    # 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, i, j)
                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(c: QuantumCircuit, k: int, control: QuantumRegister) -> QuantumCircuit:
        for i in range(len(y)):
            c.crz(math.pi * k / (2**i), control_qubit=control, target_qubit=y[i])

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

    for i in range(m):
        qc.h(y[i])

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

    qc.compose(qft(m).inverse(), inplace=True, qubits=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, i, j)
                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(c: QuantumCircuit, k: int, control: QuantumRegister) -> QuantumCircuit:
        for i in range(len(y)):
            c.crz(math.pi * k / (2**i), control_qubit=control, target_qubit=y[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)
    # swap_qubits(qc, y)

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

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

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

    # swap_qubits(qc, x)
    swap_qubits(qc, y)

    return qc
'''


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

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 U(n: int, m: int, pow: int, S: list[int]) -> QuantumCircuit:
    qc = QuantumCircuit(n)
    for i in range(n):
        qc.p(2*math.pi*S[i]*pow/2**m, 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:
    for i in range(m):
        qc.h(y[i])
        qc.append(U(n, m, 2**i, S).to_gate().control(1), [y[i]]+[x[i] for i in range(n)])
    qc.append(IQFT(m).to_gate(), y)

    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:
    # IQFT
    qc0 = QuantumCircuit(m)
    for i in range(m):
        qc0.h(m-i-1)
        for j in range(1, m-i):
            qc0.cp(-math.pi/2**j, m-i-j-1, m-i-1)
    for i in range(m//2):
        qc0.swap(i, m-i-1)
    IQFT = qc0.to_gate()

    for j in range(m):
        qc.h(y[j])
        # Oracle B5
        qc1 = QuantumCircuit(n)
        for i in range(n):
            qc1.p(2*math.pi*S[i]*2**i/2**m, i)
        U = qc1.to_gate()

        qc.append(U.control(1), [y[j]]+[x[i] for i in range(n)])

    qc.append(IQFT, y)

    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):
        qc.h(y[j])
        # Oracle B5
        for i in range(n):
            qc.cp(2*math.pi*S[i]*2**i/2**m, y[j], x[i])

    #IQFT
    for i in range(m):
        qc.h(y[m-i-1])
        for j in range(1, m-i):
            qc.cp(-math.pi/2**j, y[m-i-j-1], y[m-i-1])
    for i in range(m//2):
        qc.swap(i, y[m-i-1])

    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 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):
        qc.h(y[j])
        # Oracle B5
        for i in range(n):
            qc.cp(2*math.pi*S[i]*2**i/2**m, y[j], x[i])

    #IQFT
    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 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):
        qc.h(y[j])
        # Oracle B5
        for i in range(n):
            qc.cp((2*math.pi*S[i]/2**m)*2**i, y[j], x[i])

    #IQFT
    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 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)
    # 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**m)*2**i, y[j], x[i])

    #IQFT
    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 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)
    # 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**m)*2**j, y[j], x[i])

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

    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[])

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

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

from qiskit.circuit.library import HGate, ZGate, XGate, PhaseGate
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[])

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

    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, AncillaRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    # Define quantum registers
    x = QuantumRegister(n, 'x')
    y = QuantumRegister(m, 'y')
    anc = AncillaRegister(n, 'anc')
    qc = QuantumCircuit(x, y, anc)

    # Compute f(x) using controlled addition
    # We need to add `S_i` to `y` for each `x_i` == 1

    # To compute f(x) = S_0*x_0 + S_1*x_1 + ... + S_{n-1}*x_{n-1}
    # We will use ancilla qubits to temporarily store intermediate sums

    for i in range(n):
        if S[i] > 0:
            # Convert S[i] to binary representation
            binary_S_i = [int(b) for b in format(S[i], f'0{m}b')]
            for j in range(m):
                if binary_S_i[j] == 1:
                    # Apply controlled additions to the `y` qubits
                    qc.cx(x[i], y[j])

    # Use ancilla qubits to facilitate the controlled additions
    for i in range(n):
        if S[i] > 0:
            # Apply controlled adders to add S_i to the y register
            binary_S_i = [int(b) for b in format(S[i], f'0{m}b')]
            for j in range(m):
                if binary_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:
    # Create quantum registers for x and y
    x = QuantumRegister(n, 'x')
    y = QuantumRegister(m, 'y')

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

    # Function to add value to a register with controlled addition
    def controlled_addition(x_reg, y_reg, value):
        bin_value = format(value, f'0{len(y_reg)}b')
        for bit, q in zip(bin_value, y_reg):
            if bit == '1':
                qc.cx(x_reg[0], q)
                x_reg = x_reg[1:]

    # Add S_i to y for each x_i == 1
    for i in range(n):
        if S[i] > 0:
            controlled_addition([x[i]], y, S[i])

    return qc
'''


'''python
from qiskit import QuantumCircuit, QuantumRegister

def solve(n: int, m: int, S: list[int]) -> QuantumCircuit:
    # Create quantum registers for x and y
    x = QuantumRegister(n, 'x')
    y = QuantumRegister(m, 'y')

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

    # Implement the controlled additions
    for i in range(n):
        # Create a controlled adder for each bit
        bin_S_i = format(S[i], f'0{m}b')  # Get binary representation of S[i]

        # Apply controlled additions based on the binary representation of S[i]
        for j in range(m):
            if bin_S_i[j] == '1':
                # Apply a controlled-X gate if the bit 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:
    # Create quantum registers for x and y
    x = QuantumRegister(n, 'x')
    y = QuantumRegister(m, 'y')

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

    # Iterate over each bit of x and the corresponding S coefficient
    for i in range(n):
        # Get the binary representation of S[i]
        bin_S_i = format(S[i], f'0{m}b')

        # For each bit in the binary representation, apply a controlled addition
        for j in range(m):
            if bin_S_i[j] == '1':
                # Apply controlled-X gate to add the corresponding bit of S[i]
                qc.cx(x[i], y[j])

    return qc
'''


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

def qft(n:int)->QuantumCircuit:
    qc = QuantumCircuit(n)
    for k in range(n):
        j = n-1-k
        if k>=j:
            break
        qc.swap(k,j)
    for i in range(n):
        qc.h(i)
        for l 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)
    for k in range(n):
        j = n-1-k
        if k>=j:
            break
        qc.swap(k,j)
    for i in range(n):
        qc.h(i)
        for l in range(i+1,n):
            theta = 2 * pi / (2**(l+1-i))
            qc.cp(theta, l, 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 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, S: list[int]) -> QuantumCircuit:
    x, y = QuantumRegister(n), QuantumRegister(m)
    qc = QuantumCircuit(x, y)

    # 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//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])

    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)
    for qubit in x:
        qc.h(qubit)

    # Apply the controlled-U gates based on the function f(x)
    for i in range(n):
        for j in range(m):
            if S[i] != 0:
                angle = 2 * np.pi * S[i] / (2 ** m)
                # Apply controlled-phase (CRZ) gate to the target qubits
                qc.crz(angle / (2 ** j), x[i], y[j])

    # Write your code here:

    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)
    # Loop over each qubit in the x register
    for i in range(n):
        # For each qubit in x, add controlled-phase gates to the y qubits
        for j in range(m):
            # Calculate the angle for the controlled-phase gate
            angle = 2 * np.pi * S[i] / (2 ** m)
            # Apply controlled-phase gates
            qc.crz(angle, x[i], y[j])

    # Write your code here:

    return qc
'''