You are given an angle $$$\text{ang}$$$. The Jury asks You to find such regular $$$n$$$-gon (regular polygon with $$$n$$$ vertices) that it has three vertices $$$a$$$, $$$b$$$ and $$$c$$$ (they can be non-consecutive) with $$$\angle{abc} = \text{ang}$$$ or report that there is no such $$$n$$$-gon.  If there are several answers, print the minimal one. It is guarantied that if answer exists then it doesn't exceed $$$998244353$$$.

The first line contains single integer $$$T$$$ ($$$1 \le T \le 180$$$) — the number of queries.  Each of the next $$$T$$$ lines contains one integer $$$\text{ang}$$$ ($$$1 \le \text{ang} < 180$$$) — the angle measured in degrees.

For each query print single integer $$$n$$$ ($$$3 \le n \le 998244353$$$) — minimal possible number of vertices in the regular $$$n$$$-gon or $$$-1$$$ if there is no such $$$n$$$.

NoteThe answer for the first query is on the picture above.The answer for the second query is reached on a regular $$$18$$$-gon. For example, $$$\angle{v_2 v_1 v_6} = 50^{\circ}$$$.The example angle for the third query is $$$\angle{v_{11} v_{10} v_{12}} = 2^{\circ}$$$.In the fourth query, minimal possible $$$n$$$ is $$$180$$$ (not $$$90$$$).

data Polygon = Polygon {ver :: Int, ang :: Float}

main = do
  queries <- getLine
  commands <- sequence (replicate (read queries) getLine)
  let min = foldl iterator [] commands
  let answers = reverse min
  mapM_ showMin answers

showMin :: Int -> IO ()
showMin x = print x

iterator :: [Int] -> String -> [Int]
iterator [] angle = let
  check = checkAngle (read angle)
  polygonList = map polygonGenerator [3 ..]
  posibleAnswers = filter check polygonList
  in [getVer (head posibleAnswers)]
iterator (a:as) angle = let
  check = checkAngle (read angle :: Float)
  polygonList = map polygonGenerator [3 ..]
  posibleAnswers = filter check polygonList
  in getVer (head posibleAnswers) : (a:as)

getVer :: Polygon -> Int
getVer Polygon {ver = x, ang = y} = x

polygonGenerator :: Int -> Polygon
polygonGenerator x = Polygon {ver = x, ang = (((fromIntegral x) - 2) * 180) / fromIntegral x}

checkAngle :: Float -> Polygon -> Bool
checkAngle angle Polygon {ver = x, ang = y} = let
  z = y / ((fromIntegral x) - 2)
  angulos = [y, (y - z) .. z]
  in if (angle `elem` angulos) then True else False

solve :: Int -> Int
solve ang =
    let n = 180 `div` (gcd 180 ang)
    in if ang <= 180 `div` n * (n - 2) then n else (2 * n)

main = do
    _ <- getLine
    contents <- getContents
    mapM_ (print . solve . read) $ lines contents

import Data.Fixed (mod')

{- el type Polygon contiene los siguientes parametros
   vertex = numero de vertices
   minAngle = el angulo minimo que puede poseer
   maxAngle = el angulo maximo que puede poseer -}
data Polygon = Polygon { vertex :: Int
                       , minAngle :: Float
                       , maxAngle :: Float
                       } deriving (Show)

-- poryList crea una lista de Polygon con la lista dada (en este caso, de 3 a infinito, poligonos de 1 y 2 lados no existen)
poryList :: [Int] -> [Polygon]
poryList [] = []
poryList (x:xs) = (Polygon { vertex = x, minAngle = ang, maxAngle = ang * (y - 2)}):(poryList xs)
    where y = fromIntegral x :: Float
          ang = 180 / y

{- checkPory recibe un Polygon y un angulo, y revisa si es posible hacer ese angulo con el Polygon dado
   se utilizo mod' para poder trabajar con Floats -}
checkPory :: Polygon -> Int -> Bool
checkPory p n
    | mod' ang (minAngle p) == 0 && ang <= (maxAngle p) = True
    | otherwise = False
    where ang = fromIntegral n :: Float

-- checkFor revisa cada Polygon de la lista dada y revisa si checkPory es verdadero. En caso de que el angulo dado sea mayor o igual a 180 la figura no puede hacerse y retorna -1
checkFor :: [Polygon] -> Int -> Int
checkFor (x:xs) n
    | n >= 180 = -1
    | checkPory x n = vertex x
    | otherwise = checkFor xs n

main :: IO()
main = do
    let pList = poryList [3..] -- pList es una lista infinita de Polygon
    q <- getLine
    let query = (read q :: Int)
    inputList <- (sequence (replicate query getLine))
    let angList = map (read :: String -> Int) inputList
    let porygonZ = map (checkFor pList) angList
    mapM_ print porygonZ --mapM_ se utilizo para printear en lineas separadas

import Data.Fixed (mod')

data Polygon = Polygon { vertex :: Int
                       , minAngle :: Float
                       , maxAngle :: Float
                       , intAngle :: Float
                       } deriving (Show)

poryList :: [Int] -> [Polygon]
poryList [] = []
poryList (3:xs) = (Polygon { vertex = 3, minAngle = 60.0, maxAngle = 60.0, intAngle = 60.0}):(poryList xs)
poryList (4:xs) = (Polygon { vertex = 4, minAngle = 45.0, maxAngle = 45.0, intAngle = 90.0}):(poryList xs)
poryList (x:xs) = (Polygon { vertex = x, minAngle = ang, maxAngle = ang * (y - 2), intAngle = ang * (y - 2)}):(poryList xs)
    where y = fromIntegral x :: Float
          ang = 180 / y

checkPory :: [Polygon] -> Int -> Int
checkPory [] _ = -1
checkPory (x:xs) n
    | n >= 180 = -1
    | mod' nn (minAngle x) == 0 && nn <= (maxAngle x) = vertex x
    | nn == intAngle x = vertex x
    | otherwise = checkPory xs n
    where nn = fromIntegral n :: Float

checkFor :: [Polygon] -> [Int] -> [Int]
checkFor _ [] = []
checkFor x (y:ys) = (checkPory x y):(checkFor x ys)

main :: IO()
main = do
    let h = poryList [3..]
    q <- getLine
    let query = (read q :: Int)
    angList <- (sequence (replicate query getLine))
    let pList = map (read :: String -> Int) angList
    mapM_ print (checkFor h pList)

import Control.Monad
import Data.List
import Data.Fixed
data Polygon = Polygon {angulo :: Float, vertice :: Int} deriving (Show)

instance Eq Polygon where  --Instancia pedida en el bonus
    (==) (Polygon ver1 ang1) (Polygon ver2 ang2) = (ver1 == ver2) && (ang1 == ang2)
    (==) a b = False

poly :: [Int] -> [Polygon] --Generador de poligonos
poly (x:xs) = let
    vert = x
    ang = 180.0 / (fromIntegral x) in Polygon { angulo = ang, vertice = vert}:poly xs

minVert :: [Int] -> [Polygon] -> [String] --Función encargada de entregar el angulo mínimo correspondiente a cada caso
minVert [a] b = let
    filteredList = filter (\p -> aux a p) b in if filteredList == []
        then "-1" : []
        else show (vertice (head filteredList)) : []
minVert (a:as) b = let
    filteredList = filter (\p -> aux a p) b in if filteredList == []
        then "-1" : (minVert as b)
        else show (vertice (head filteredList)) : (minVert as b)

aux :: Int -> Polygon -> Bool  --Función que ratifica que el angulo obtenido exista
aux x y
    | (fromIntegral x) < (angulo y) = False
    | (fromIntegral x) > ((angulo y) * (fromIntegral (vertice y) - 2.0)) = False
    | mod' (fromIntegral x) (angulo y) == 0.0 = True
    | otherwise = False

main :: IO ()
main = do
    casos <- getLine
    let n = read casos::Int
    angulos <- replicateM n getLine
    let poligonos = poly [3..998244353]
    let intAngulos = map (read :: String -> Int) angulos
    let output = minVert intAngulos poligonos
    putStrLn (intercalate "\n" output)

import System.Environment
import System.IO
import qualified Data.Fixed as F

data Poligon = Poligon {  vrtx :: Float
                        , ang :: Float
                        } deriving (Show)

main = do
  inputs<- getLine
  angulos <- lector (read inputs::Int)
  let lp = infiniteL 3
  mapM_ print (map round (answers angulos lp))

lector :: Int -> IO [Float]
lector 0 = return []
lector n = do
   x <- fmap read getLine
   rest <- lector (n-1)
   return $ x : rest

infiniteL :: Float -> [Poligon]
infiniteL v =
  plg:(infiniteL (v+1))
  where plg = (Poligon v ((/) 180.0 v))

minimu :: Float -> [Poligon] ->Poligon
minimu num (p:ps) =
  let (n,m) = dataPoly p in
    if((F.mod' num m) == 0 && ((n-2)*180/n) >= num )
      then p
    else
      minimu num ps

dataPoly :: Poligon -> (Float, Float)
dataPoly (Poligon n m) = (n , m)

answers :: [Float] -> [Poligon] ->[Float]
answers [] _ = []
answers (x:xs) l =
  [n] ++ (answers xs l)
  where (n,m) = dataPoly(minimu x l)

import Control.Monad (replicateM)

data Polygon = Polygon {vertices :: Int,
                        angulo_min :: Float,
                        angulos :: [Float]} deriving (Show)

divid :: Int -> Int -> Float
divid a b = (fromIntegral a) / (fromIntegral b)

poligonos :: [Polygon]
poligonos = [Polygon n (divid 180 n) (angulos_poligono n) | n <- [3..]]

angulos_poligono :: Int -> [Float]
angulos_poligono n = [(divid 180 n) * (fromIntegral x)| x <- [1..n-2]]

poligono_min :: Int -> [Polygon] -> Int
poligono_min angulo (x:xs)
    | (fromIntegral angulo) `elem` angulos_pol x    = vert x
    | otherwise                      = poligono_min angulo xs

vert :: Polygon -> Int
vert (Polygon n _ _) = n

angulos_pol :: Polygon -> [Float]
angulos_pol (Polygon _ _ l) = l

-- https://stackoverflow.com/questions/27650315/getline-x-times-haskell

getLines :: Int -> IO [String]
getLines n = replicateM n getLine

getInts :: Int -> IO [Int]
getInts n = fmap read <$> getLines n

getInt :: IO Int
getInt = fmap read getLine

main = do
    queries <- getInt
    nums <- getInts queries
    let vertex = [poligono_min angle poligonos | angle <- nums]
    mapM_ print vertex

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE TupleSections#-}
{-# LANGUAGE ExplicitForAll #-}

import Data.Bits
import Data.List
import qualified Data.ByteString.Char8 as BS
import qualified Data.ByteString.Lazy.Char8 as BSL
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as IM
import qualified Data.Array.IArray as A
import qualified Data.Array.MArray.Safe as A
-- import qualified Data.Array.MArray as A
import Data.Array (Array)
import Data.Array.Unboxed (UArray)
import Data.Array.IArray (IArray)
import Data.Array.MArray.Safe (MArray)
import Data.Array.IO.Safe (IOArray, IOUArray)
import Data.Array.ST.Safe (STArray, STUArray, runSTArray, runSTUArray)
{-
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
-}
import Control.Monad
import Control.Monad.ST.Safe
-- import Control.Monad.ST
import Control.Applicative
import Data.Maybe
import Data.Tuple
import Data.Ord
import Control.Monad.State.Strict
import Data.Int

main :: IO ()
main = do
  n <- read <$> getLine
  replicateM_ n $ getLine >>= print . query . read

query :: Int -> Int
query angle | angle >= 180 * (firstans-1) `div` firstans = firstans * 2
             | otherwise = firstans
  where
    firstans = 180 `div` gcd 180 angle

import System.IO
import Data.Fixed

data Polygon = Polygon { vertices ::Int ,minAng ::Float,interior::Float} deriving(Show)

canBeDone:: Polygon-> Float -> Bool
canBeDone p a= mod' a (minAng p) == 0.0 && a<=(interior p)
forEach ::[Polygon]->Float ->Int
forEach [] a= (-1)
forEach (p:ps) a= do
    if(canBeDone p a)
        then getVertices p
        else if(getVertices p <998244353)
            then forEach ps a
            else -1

getIterationsLines :: Int ->[Polygon] -> IO [String]
getIterationsLines n lista
    | n <= 0 = return []
    | otherwise = do
        angle <- getLine
        print $ forEach lista (read angle ::Float)
        xs <- getIterationsLines (n-1) lista
        return (angle:xs)

getVertices:: Polygon -> Int
getVertices p = vertices p

main = do
    iterations <- getLine
    let lista_infinita = [ Polygon i (180/fromIntegral i) (180*(fromIntegral i-2)/fromIntegral i) | i<-[3..]]
    let ite = read iterations::Int
    getIterationsLines ite lista_infinita
    return ()

import System.IO
import Data.Fixed

data Polygon = Polygon { vertices ::Int ,minAng ::Float,interior::Float} deriving(Show)

canBeDone:: Polygon-> Float -> Bool
canBeDone p a= mod' a (minAng p) == 0.0 && a<=(interior p)
forEach ::[Polygon]->Float ->Int
forEach [] a= (-1)
forEach (p:ps) a= do
    if(canBeDone p a)
        then getVertices p
        else if(getVertices p <2000000)
            then forEach ps a
            else -1

getIterationsLines :: Int ->[Polygon] -> IO [String]
getIterationsLines n lista
    | n <= 0 = return []
    | otherwise = do
        angle <- getLine
        print $ forEach lista (read angle ::Float)
        xs <- getIterationsLines (n-1) lista
        return (angle:xs)

getVertices:: Polygon -> Int
getVertices p = vertices p

main = do
    iterations <- getLine
    let lista_infinita = [ Polygon i (180/fromIntegral i) (180*(fromIntegral i-2)/fromIntegral i) | i<-[3..]]
    let ite = read iterations::Int
    getIterationsLines ite lista_infinita
    return ()

data Polygon = Polygon {sides :: Int}

minAngle :: Polygon -> Float
minAngle poly
    | sides poly > 2 = 180.0 / (fromIntegral (sides poly))
    | otherwise      = error "Invalid Polygon"

interiorAngle :: Polygon -> Float
interiorAngle poly
    | sides poly > 2 = fromIntegral((sides poly) - 2)*minAngle poly
    | otherwise      = error "Invalid Polygon"

possibleAngles :: Polygon -> [Float]
possibleAngles poly = [minAngle poly, 2*(minAngle poly)..(interiorAngle poly)]

findPolygon :: [Polygon] -> Float -> IO ()
findPolygon (x0:xs) n
    | elem n (possibleAngles x0) = print(sides x0)
    | otherwise                  = findPolygon xs n

main :: IO ()
main = do
    n <-getLine
    inputs <- sequence [readLn :: IO Float | i <-[1..(read n :: Integer)]]
    let polygons = [Polygon i | i<-[3..]]
    mapM_ (findPolygon polygons) inputs

import Data.List (sort)
import Control.Monad

--Data Polygon required in LP
data Polygon = Polygon {
					vertex :: Int,
					min_angle :: Float
					}

--Implement Eq type class
instance Eq Polygon where
	(==) (Polygon n ang) (Polygon n' ang') = (n==n' && ang' == ang')

--Implement Ord type class to compare polygons
instance Ord Polygon where
	compare (Polygon a _) (Polygon b _) = compare a b

--Implement Show type class to print the vortex
instance Show Polygon where
	show (Polygon a _ ) = show a
--------------------------------------

--calculate the internal angle of the side of a polygon
calcSideAngle :: Float -> Float
calcSideAngle x = 180.0*(x - 2)/(x)

--calculate the minimum angle that can contain a polygon
minAngle :: Int -> Float
minAngle n = let
				sideAngle = calcSideAngle x
				x = fromIntegral n
				in sideAngle/(x-2)

--verify if a certain angle is possible in a polygon of n vertices
is_possible :: Int -> Polygon -> Bool
is_possible ang n = let
				min_angle = minAngle (vertex n)
				ang' = fromIntegral ang
				in foldl (\acc x -> if (x*min_angle) == ang' then True else acc) False (map (fromIntegral) [1..(vertex(n)-2)])

--compute all possible polygons that satisfy the condition and take the first
--in other words, compute the amount of vertices that a polygon can have to contain an angle ang
possible_polygons :: Int -> (Polygon -> Bool) -> [Polygon]-> Polygon
possible_polygons ang fx xs =  head (filter fx xs )

--look at this
main = do
	let poligonos = [Polygon i (minAngle i)| i <- [1..]]
	n <- fmap read getLine
	angles <- forM (replicate n 1) (\a -> do
		ang <- getLine
		return ang)
	mapM (\ang -> do
		let ang' = read ang :: Int
		let result = possible_polygons ang' (is_possible ang') poligonos
		putStrLn $ show result) angles
--very impressive no?

import Data.List
import Control.Monad --para usar replicateM

data Polygon = Polygon {vertices :: Int, min_ang :: Int} deriving (Show) --Lo que se pide

main :: IO ()
main = do
    casos <- getLine
    let t = read casos::Int -- (1≤t≤180)
    angulos <- replicateM t getLine --Lista con los angulos recibidos
    let poligonos = map poligonosRegulares [3..] -- 3 porque es el numero minimo de vertices, lista infinita como se pide
    let output = map (anguloMenor poligonos) angulos
    putStrLn $ foldl (\x0 y -> x0 ++ (show y) ++ "\n") "" output

poligonosRegulares :: Int -> Polygon
poligonosRegulares num_vertices -- de la lista infinita
    | (180 `mod` num_vertices == 0) = Polygon {vertices = num_vertices, min_ang = 180 `div` num_vertices} --Triangulo
    | (360 `mod` num_vertices == 0) = Polygon {vertices = num_vertices, min_ang = 360 `div` num_vertices} --Cuadrado
    | otherwise = Polygon {vertices = num_vertices, min_ang = 181}

anguloMenor :: [Polygon] -> String -> Int
anguloMenor (x0:xs) ang_string
    | (((((vertices x0)-2)*180) `div` vertices x0) >= ang && (ang `mod` (min_ang x0) == 0)) = vertices x0
    | (vertices x0 > 360) = -1
    | otherwise = anguloMenor xs ang_string --recursividad
    where ang = read ang_string :: Int -- Se pasa a int para poder operarlo

import Control.Monad

--se crea el data Polygon con los datos angulosInt, vertices, anguloMin y anguloMax
data Polygon = Polygon {
    angulosInt ::Double,
    vertices ::Int,
    anguloMin ::Double,
    anguloMax ::Double
} deriving (Ord, Eq,Show)

--se define cada uno de los atributos de Polygon
--angulos internos = 180*(cantidad de vertices-2)
--angulo Maximo = angulos Internos / cantidad de vertices
--angulo Minimo (este fue probando) = angulo maximo / (cantidad de vertices - 2)
--Recibe un Int (cantidad de vertices) y entrega un Polygon con todos sus datos
define :: Int -> Polygon
define ver = let
    doubVer = fromIntegral ver ::Double
    angInt = 180.0 * (doubVer - 2.0)
    angMax = angInt / doubVer
    angMin = angMax/(doubVer-2.0)
    in Polygon {vertices = ver, angulosInt = angInt, anguloMin = angMin, anguloMax = angMax}

--entrega el poligono donde se puede formar el angulo
buscarPol :: Int -> Polygon -> Polygon
buscarPol ang pol = let
    ver = vertices pol
    in if (isPol (fromIntegral ang ::Double) pol) then pol else buscarPol ang (define (ver+1))

--Comprueba si es el polygono pedido
--recibe un angulo y el polygono inicial y entrega True si es el polygono que se pide y False en caso contrario
isPol :: Double-> Polygon -> Bool
isPol ang pol=let
    angMin = anguloMin pol
    angMax = anguloMax pol
    --angs1 es la división normal, angs2 es la division entera entre el angulo dado y el angulo minimo del poligono
    angs1 = (ang / angMin)
    angs2 = (fromIntegral (round (ang/angMin)) :: Double)
    --si angs1 y angs2 son iguales significa que el angulo minimo es divisor del angulos dado, por lo que es el poligono pedido
    in if (ang<=angMax && angs1-angs2==0.0) then True else False

output:: Int -> IO ()
output out = print out

main::IO()
main = do
    consultas <- getLine
    --se recibe un input multiple con replicateM
    angulos <- replicateM (read consultas ::Int) getLine
    let polInicial = define 3
    --se crea la lista de polygonos, al reves, por lo que se utiliza reverse para mantenerla segun lo dado por el usuario
    --luego se entrega en consola cada uno de los datos con mapM_ y la función output
    (mapM_ output(reverse (foldl (\x y -> (vertices (buscarPol (read y ::Int) polInicial)) : x) [] angulos)))

import Control.Monad

--prueba

data Polygon = Polygon {
    angulosInt ::Double,
    vertices ::Int,
    anguloMin ::Double,
    anguloMax ::Double
} deriving (Ord, Eq,Show)

define :: Int -> Polygon -> Polygon
define ver pol  = let
    angInt = angulosInternos ver
    intVer = fromIntegral ver ::Double
    angMax = angInt / (fromIntegral ver ::Double)
    angMin = anguloMinimo angMax intVer
    in pol {vertices = ver, angulosInt = angInt, anguloMin = angMin, anguloMax = angMax}

angulosInternos :: Int -> Double
angulosInternos ver = 180.0 * ((fromIntegral ver ::Double) - 2.0)

anguloMinimo :: Double -> Double -> Double
anguloMinimo angMax ver= angMax/(ver-2.0)

buscarPol :: Int -> Int -> Polygon -> Polygon
buscarPol ang lim pol = let
    ver = vertices pol
    in if (isPol (fromIntegral ang ::Double) pol) then pol else (if ver < lim then (buscarPol ang lim (define (ver+1) pol)) else Polygon (-1) (-1) (-1) (-1))

output:: Int -> IO ()
output out = print out

toInt :: Double -> Int
toInt x = round x

isPol :: Double-> Polygon -> Bool
isPol ang pol=let
    angMin = anguloMin pol
    angMax = anguloMax pol
    angs1 = (ang / angMin)
    angs2 = (fromIntegral (toInt(ang/angMin)) :: Double)
    in if (ang<=angMax && angs1-angs2==0.0) then True else False

main::IO()
main = do
    consultas <- getLine
    angulos <- replicateM (read consultas ::Int) getLine
    let lim = 998244353
    let polInicial = Polygon 180 3 60 60
    (mapM_ output(reverse (foldl (\x y -> (vertices (buscarPol (read y ::Int) lim polInicial)) : x) [] angulos)))

import Data.List
import Data.Fixed

--Creación del tipo Polygon que posee angulo y vertice
data Polygon = Polygon {
  angulo :: Double,
  vertice :: Int}
  deriving (Show)

--Creación de la lista de polígonos
generarpoligonos :: [Int] -> [Polygon]
generarpoligonos(x:xs) = let
    angulo2= 180.0/(fromIntegral x)
    vertice2= x
    in Polygon{angulo = angulo2, vertice= vertice2}:(generarpoligonos xs)

--Funcion utilizada para generar el numero de vertices minimos
generarvertices :: [Int] -> [Polygon] -> [String]
generarvertices[x] y = let
  listaconfiltro = filter(\p -> verificarangulos x p) y in if listaconfiltro == [] then "-1" : [] else show (vertice (head listaconfiltro)):[]
generarvertices(x:xs) y = let
  listaconfiltro = filter(\p -> verificarangulos x p) y in if listaconfiltro == [] then "-1" : (generarvertices xs y) else show (vertice (head listaconfiltro)):(generarvertices xs y)

--Funcion para verificar angulos de la funcion generarpoligonos2 y retornar True o False
verificarangulos :: Int -> Polygon -> Bool
verificarangulos x y
  |(fromIntegral x)>((angulo y)*(fromIntegral(vertice y)- 2.0)) = False
  |(fromIntegral x)<(angulo y) = False
  |mod'(fromIntegral x)(angulo y) == 0.0 = True
  |otherwise = False

--Instancia utilizada para verificar igualdad de angulos
instance Eq Polygon where
    (==)(Polygon vertice2 angulo2)(Polygon vertice1 angulo1) = (angulo1 == angulo2)&&(vertice1 == vertice2)
    (==) x y = False

main :: IO()
main = do
    numeroT <- getLine
    let listapoligonos = generarpoligonos[3,4..]  --Se recibe el numero T de consultas y se genera la lista de poligonos
    listadeangulos <- sequence(take (read numeroT :: Int)(repeat getLine))
    let angulos = map(read :: String -> Int) listadeangulos --Se genera la lista con los angulos entregados en el input
    let vertices = generarvertices angulos listapoligonos
    putStrLn (intercalate " \n" vertices) --Se genera la lista de vertices y se imprimen por pantallas con \n de por medio

import qualified Data.ByteString.Char8 as C
--type polygon que contiene el número de vértices, el ángulo más pequeño que se puede generar (mediante 3 vértices consecutivos) y una lista de TODOS los ángulos que puede generar el polígono
data Polygon = Polygon {vertexNumber :: Int, minAngle :: Double, angles :: [Double]} deriving (Show)
--notar que en mi algoritmo no uso minAngle sino que la lista angles.

--lista de polígonos infinita
polygonList = [Polygon{vertexNumber = i, minAngle = 180.0/(fromIntegral i :: Double), angles = [((180.0/(fromIntegral i :: Double)) * (fromIntegral (j - 2) :: Double)) | j <- [3..i]]} | i <- [3..]]

containsAngle :: Polygon -> Double -> Bool --indica si un polígono puede "generar" el ángulo pedido
containsAngle polygon angle = if (((mod ((round angle :: Int)*2*(vertexNumber polygon)) 360) == 0) && ((round angle :: Int)*(vertexNumber polygon) <= (180*((vertexNumber polygon) - 2)))) then True else False

--función de orden superior, toma la función para hacer el checkeo de ángulo en un polígono.
solution :: (Polygon -> Double -> Bool) -> Double -> Int --retorna el índice del polígono más pequeño con el cual se pueda "generar" el ángulo pedido
solution check angle = vertexNumber (head [ polygon | polygon <- polygonList, True == (check polygon angle)]) -- lazyness

readChar8 :: IO [Int] --computación para leer ints de forma eficiente
readChar8 = map parse . C.words <$> C.getContents where parse s = let Just (n, _) = C.readInt s in n

main :: IO()
main = do
  ints <- readChar8 --primero leo todos los ints y luego trabajo
  let (n:xs) = ints --notar que no uso n pues no es necesario haciendo uso del map de abajo
  mapM_ (\x -> print (solution containsAngle (fromIntegral x :: Double))) xs
  --para parar el procesamiento y obtener el resultado CTRL + D

import qualified Data.ByteString.Char8 as C
--type polygon que contiene el número de vértices, el ángulo más pequeño que se puede generar (mediante 3 vértices consecutivos) y una lista de TODOS los ángulos que puede generar el polígono
data Polygon = Polygon {vertexNumber :: Int, minAngle :: Double, angles :: [Double]} deriving (Show)
--notar que en mi algoritmo no uso minAngle sino que la lista angles.

--lista de polígonos infinita
polygonList = [Polygon{vertexNumber = i, minAngle = 180.0/(fromIntegral i :: Double), angles = [((180.0/(fromIntegral i :: Double)) * (fromIntegral (j - 2) :: Double)) | j <- [3..i]]} | i <- [3..]]

containsAngle :: Polygon -> Double -> Bool --indica si un polígono puede "generar" el ángulo pedido
containsAngle polygon angle = if (((mod ((round angle :: Int)*2*(vertexNumber polygon)) 360) == 0) && ((round angle :: Int)*(vertexNumber polygon) <= (180*((vertexNumber polygon) - 2)))) then True else False

solution :: Double -> Int --retorna el índice del polígono más pequeño con el cual se pueda "generar" el ángulo pedido
solution angle = vertexNumber (head [ polygon | polygon <- polygonList, True == (containsAngle polygon angle)]) -- lazyness

readChar8 :: IO [Int] --computación para leer ints de forma eficiente
readChar8 = map parse . C.words <$> C.getContents where parse s = let Just (n, _) = C.readInt s in n

main :: IO()
main = do
  ints <- readChar8 --primero leo todos los ints y luego trabajo
  let (n:xs) = ints --notar que no uso n pues no es necesario haciendo uso del map de abajo
  mapM_ (\x -> print (solution (fromIntegral x :: Double))) xs
  --para parar el procesamiento y obtener el resultado CTRL + D

import qualified Data.ByteString.Char8 as C
data Polygon = Polygon {vertexNumber :: Int, minAngle :: Double, angles :: [Double]} deriving (Show)

polygonList = [Polygon{vertexNumber = i, minAngle = 180.0/(fromIntegral i :: Double), angles = [((180.0/(fromIntegral i :: Double)) * (fromIntegral (j - 2) :: Double)) | j <- [3..i]]} | i <- [3..]]
--possibleAngle :: Double -> Bool
--possibleAngle angle = let
--    polygon = take 1 ([polygon | polygon <- (filter ((\a x -> elem a (angles x)) angle) polygonList)]) -- arreglar
--    len = length polygon
--    in if((len == 1) && ((vertexNumber (polygon !! 0) ) <= 998244353)) then True else False

containsAngle :: Polygon -> Double -> Bool
containsAngle polygon angle = if (((mod ((round angle :: Int)*2*(vertexNumber polygon)) 360) == 0) && ((round angle :: Int)*(vertexNumber polygon) <= (180*((vertexNumber polygon) - 2)))) then True else False

solution angle = vertexNumber (head [ polygon | polygon <- polygonList, True == (containsAngle polygon angle)]) -- usando lazyness

readChar8 :: IO [Int]
readChar8 = map parse . C.words <$> C.getContents where parse s = let Just (n, _) = C.readInt s in n

main :: IO()
main = do
  ints <- readChar8
  let (n:xs) = ints
  mapM_ (\x -> print (solution (fromIntegral x :: Double))) xs
  --CTRL + D

import Data.List (intercalate)
import Data.Fixed (mod')

data Polygon = Polygon {vertices :: Int, minAngle :: Double, maxAngle :: Double}

instance Show Polygon where
    show r = "-- Verts: " ++ (show (vertices r)) ++ ", minAngle: " ++ (show (minAngle r)) ++ ", maxAngle: " ++ (show (maxAngle r)) ++ " --"

instance Eq Polygon where
    (==) (Polygon v1 mina1 maxa1) (Polygon v2 mina2 maxa2) =
        (v1 == v2) && (mina1 == mina2) && (maxa1 == maxa2)
    (==) a b = False

instance Ord Polygon where
    compare (Polygon v1 mina1 maxa1) (Polygon v2 mina2 maxa2) =
        compare (v1,mina1,maxa1) (v2,mina2,maxa2)

allPolygons :: [Polygon]
allPolygons = let
    start = Polygon {vertices = 3, minAngle = 60, maxAngle = 60}
    in start:(generatePolygons start)

generatePolygons :: Polygon -> [Polygon]
generatePolygons f = let
    --You will get the result with this, but simplifying
    --you gonna get the same result in less lines
    --
    --newVerts = (vertices f) + 1
    --angleSum = (newVerts - 2) * 180
    --minAng = angleSum / (newVerts - 2)
    --
    newVerts = (vertices f) + 1
    maxAng = ((fromIntegral (newVerts - 2)) * 180.0) / (fromIntegral newVerts)
    minAng = 180.0 / (fromIntegral newVerts)

    nextPolygon = Polygon {vertices = newVerts, minAngle = minAng, maxAngle = maxAng}
    in nextPolygon:(generatePolygons nextPolygon)

--Verify if the angle is between minAngle and maxAngle, and if the minAngle can
--make the angle "a"
canGetAngle :: Int -> Polygon -> Bool
canGetAngle a p
    | fa < minAng = False
    | fa > maxAngle p = False
    | mod' fa minAng /= 0.0 = False
    | otherwise = True
    where
        fa = fromIntegral a
        minAng = minAngle p

--Get the angle and return the n-sides of the polygon in String format
getPolygon :: Int -> String
getPolygon angle = let
    filteredList = filter (\p -> canGetAngle angle p) allPolygons
    in if null filteredList
        then "-1"
        else show (vertices (head filteredList))

main :: IO ()
main = do
    q <- getLine
    let queries = read q :: Int
    queryList <- sequence (replicate queries getLine)
    let transformedList = map (read :: String -> Int) queryList
    let mapedList = map getPolygon transformedList
    putStrLn (intercalate "\n" mapedList)

import Data.List (intercalate)
import Data.Fixed (mod')

data Polygon = Polygon {vertices :: Int, minAngle :: Double, maxAngle :: Double}

instance Show Polygon where
    show r = "-- Verts: " ++ (show (vertices r)) ++ ", minAngle: " ++ (show (minAngle r)) ++ ", maxAngle: " ++ (show (maxAngle r)) ++ " --"

instance Eq Polygon where
    (==) (Polygon v1 mina1 maxa1) (Polygon v2 mina2 maxa2) =
        (v1 == v2) && (mina1 == mina2) && (maxa1 == maxa2)
    (==) a b = False

instance Ord Polygon where
    compare (Polygon v1 mina1 maxa1) (Polygon v2 mina2 maxa2) =
        compare (v1,mina1,maxa1) (v2,mina2,maxa2)

allPolygons :: [Polygon]
allPolygons = let
    start = Polygon {vertices = 3, minAngle = 60, maxAngle = 60}
    in start:(generatePolygons start)

generatePolygons :: Polygon -> [Polygon]
generatePolygons f = let
    --You will get the result with this, but simplifying
    --you gonna get the same result in less lines
    --
    --newVerts = (vertices f) + 1
    --angleSum = (newVerts - 2) * 180
    --minAng = angleSum / (newVerts - 2)
    --
    newVerts = (vertices f) + 1
    maxAng = ((fromIntegral (newVerts - 2)) * 180.0) / (fromIntegral newVerts)
    minAng = 180.0 / (fromIntegral newVerts)

    nextPolygon = Polygon {vertices = newVerts, minAngle = minAng, maxAngle = maxAng}
    in nextPolygon:(generatePolygons nextPolygon)

canGetAngle :: Int -> Polygon -> Bool
canGetAngle a p
    | fa < minAng = False
    | fa > maxAngle p = False
    | mod' fa minAng /= 0.0 = False
    | otherwise = True
    where
        fa = fromIntegral a
        minAng = minAngle p

--Get the angle and return the n-sides of the polygon in String format
getPolygon :: Int -> String
getPolygon angle = let
    filteredList = filter (\p -> canGetAngle angle p) allPolygons
    in if null filteredList
        then "-1"
        else show (vertices (head filteredList))

main :: IO ()
main = do
    q <- getLine
    let queries = read q :: Int
    queryList <- sequence (replicate queries getLine)
    let transformedList = map (read :: String -> Int) queryList
    let mapedList = map getPolygon transformedList
    putStrLn (intercalate "\n" mapedList)

{-
main :: IO ()
main = do
    ang <- getLine
    let angn = read ang :: Int
    let takedList = filter (\x -> canGetAngle angn x) allPolygons
    putStrLn (show (take 9 takedList))
-}

import Data.List
import qualified Data.Fixed as Fi

data Polygon = Polygon{angulo :: Float , vertice :: Int} deriving (Eq, Show)

obtener_poligonos::[Int] -> [Polygon]
obtener_poligonos (x:xs)= let
                angulo1 = 180.0/(fromIntegral x)
                vertice1 = x
                in Polygon{angulo=angulo1,vertice = vertice1}:obtener_poligonos(xs)

menor:: Float -> [Polygon]-> Polygon--funcion para ver si se puede lograr con ese poligono
menor angulo (x:xs) = if((Fi.mod' angulo (f x))==0 && fromIntegral (div (((g x)-2)*180) (g x)) >= angulo) then x
        else menor angulo xs

f::Polygon -> Float--Para obtener angulos
f (Polygon {angulo = a , vertice = v}) = a

g::Polygon -> Int--Para obtener vertices
g (Polygon {angulo = a , vertice = v}) = v

obtener_vertices:: [Float] -> [Polygon]-> [Int]--Entrega lista con vertices
obtener_vertices [] _ = []
obtener_vertices (x:xs) poli =
    [n] ++ (obtener_vertices xs poli)
    where n = g (menor x poli)

imprimir::[Int]-> String--Ocupado para obtener String con los vertices
imprimir [] = ""
imprimir [x] = show x
imprimir (x:xs) = show x ++"\n"++(imprimir xs)

main:: IO()
main = do
    x <- getLine
    lista_angulos <- sequence (take (read x::Int) (repeat getLine))
    let lista_angulos1 = map (read::String->Float) lista_angulos
    let lista_poligonos = obtener_poligonos [3..998244353]
    let lista_vertices = obtener_vertices lista_angulos1 lista_poligonos--Se obtienen los vertices
    let hola = imprimir lista_vertices--String con los vertices
    putStrLn hola

import System.IO
import Data.List
import Control.Monad

data Polygon = Polygon {n_vertices :: Int, angulo_minimo :: Int}

instance Eq Polygon where
    (Polygon a b) == (Polygon c d) = (a == c)

instance Ord Polygon where
    compare (Polygon a b) (Polygon c d) = compare a c

--Funcion que crea los poligonos en base a su numero de vertices y su angulo minimo
--Se consideran tambien los que tienen un angulo como 22.5, 0.5, etc, tambien
--pero su angulo minimo corresponde al doble para que sea un int
--Para cualquier otro caso, el angulo minimo es 181, que claramente es imposible
crearPoligonos :: Int -> Polygon
crearPoligonos n
    | (180 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 180 `div` n}
    | (360 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 360 `div` n}
    | otherwise = Polygon {n_vertices = n, angulo_minimo = 181}

--Funcion que verifica si el angulo pedido se puede lograr con un poligono de n
--vertices y entrega el numero de vertices en caso de poderse
calcularVertices :: [Polygon] -> String -> Int
calcularVertices (x:xs) num
    | ((n `mod` (angulo_minimo x) == 0) && ((((n_vertices x)-2)*180) `div` n_vertices x) >= n) = n_vertices x
    | (n_vertices x > 360) = -1
    | otherwise = calcularVertices xs num
    where n = read num :: Int

main = do
    q <- getLine
    inputs <- replicateM (read q) getLine
    let poligonos_infinitos = map crearPoligonos [3..]
    let final = map (calcularVertices poligonos_infinitos) inputs
    putStrLn $ foldl (\x y -> x ++ (show y) ++ "\n") "" final

import System.IO
import Data.List
import Control.Monad

data Polygon = Polygon {n_vertices :: Int, angulo_minimo :: Int} deriving (Show)

crearPoligonos :: Int -> Polygon
crearPoligonos n
    | (180 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 180 `div` n}
    | (360 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 360 `div` n}
    | otherwise = Polygon {n_vertices = n, angulo_minimo = 181}

pasarAPolygon :: [Polygon] -> String -> Int
pasarAPolygon (x:xs) num
    | ((n `mod` (angulo_minimo x) == 0) && ((((n_vertices x)-2)*180) `div` n_vertices x) >= n) = n_vertices x
    | (n_vertices x > 360) = -1
    | otherwise = pasarAPolygon xs num
    where n = read num :: Int

main = do
    input <- getLine
    inputs <- replicateM (read input) getLine
    let poligonos_infinitos = map crearPoligonos [3..]
    let final = map (pasarAPolygon poligonos_infinitos) inputs
    mapM print final

import System.IO
import Data.List
import Control.Monad

data Polygon = Polygon {n_vertices :: Int, angulo_minimo :: Int}

instance Eq Polygon where
    (Polygon a b) == (Polygon c d) = (a == c)

instance Ord Polygon where
    compare (Polygon a b) (Polygon c d) = compare a c

--Funcion que crea los poligonos en base a su numero de vertices y su angulo minimo
--Se consideran tambien los que tienen un angulo como 22.5, 0.5, etc,
--pero su angulo minimo corresponde al doble para que sea un int
--Para cualquier otro caso, el angulo minimo es 181, que claramente es imposible
crearPoligonos :: Int -> Polygon
crearPoligonos n
    | (180 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 180 `div` n}
    | (360 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 360 `div` n}
    | otherwise = Polygon {n_vertices = n, angulo_minimo = 181}

--Funcion que verifica si el angulo pedido se puede lograr con un poligono de n
--vertices y entrega el numero de vertices en caso de poderse
calcularVertices :: [Polygon] -> String -> Int
calcularVertices (x:xs) num
    | ((n `mod` (angulo_minimo x) == 0) && ((((n_vertices x)-2)*180) `div` n_vertices x) >= n) = n_vertices x
    | (n_vertices x > 360) = -1
    | otherwise = calcularVertices xs num
    where n = read num :: Int

main = do
    q <- getLine
    inputs <- replicateM (read q) getLine
    let poligonos_infinitos = map crearPoligonos [3..]
    let final = map (calcularVertices poligonos_infinitos) inputs
    putStrLn $ foldl (\x y -> x ++ (show y) ++ "\n") "" final

import System.IO
import Data.List
import Control.Monad

data Polygon = Polygon {n_vertices :: Int, angulo_minimo :: Int} deriving (Show)

crearPoligonos :: Int -> Polygon
crearPoligonos n
    | (180 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 180 `div` n}
    | (360 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 360 `div` n}
    | otherwise = Polygon {n_vertices = n, angulo_minimo = 181}

pasarAPolygon :: [Polygon] -> String -> Int
pasarAPolygon (x:xs) num
    | ((n `mod` (angulo_minimo x) == 0) && ((((n_vertices x)-2)*180) `div` n_vertices x) >= n) = n_vertices x
    | (n_vertices x > 360) = -1
    | otherwise = pasarAPolygon xs num
    where n = read num :: Int

main = do
    input <- getLine
    inputs <- replicateM (read input) getLine
    let poligonos_infinitos = map crearPoligonos [3..]
    let final = map (pasarAPolygon poligonos_infinitos) inputs
    putStrLn $ foldl (\x y -> x ++ (show y) ++ "\n") "" final

import Data.Bool

main:: IO()
main = do
    linea <- getLine
    --print (poligonoMin (read linea) polygons)
    lista <- loop (read linea)
    mapM_ print lista

loop:: Int -> IO [Int]
loop numero
  | numero == 0 = return []
  | otherwise   = do
     sn <- getLine
     let n = read sn::Int
     others <- loop (numero-1)
     return ((poligonoMin n polygons) : others)

poligonoMin:: Int -> [Polygon] -> Int
poligonoMin angulo (p:ps) =
    if (posible angulo p)
        then (nverts p)
        else  poligonoMin angulo ps

posible:: Int -> Polygon -> Bool
posible angulo poligono =
    -- trabajar los angulos como float
    -- ver si cae una cantidad de veces entera

    if (fromIntegral angulo)/(nangleMin poligono) == fromInteger(round ((fromIntegral angulo)/(nangleMin poligono)))
        then if ((fromIntegral angulo)/(nangleMin poligono)) <= fromIntegral((nverts poligono) - 2)
            then True
            else False
        else False

polygons :: [Polygon]
polygons = let
    poligono n = Polygon n (180/(fromIntegral n))
    in map poligono [3..]-- funcion lista

nverts :: Polygon ->Int
nverts (Polygon n _) = n

nangleMin :: Polygon -> Float
nangleMin (Polygon _ n) = n

data Polygon = Polygon
    {
        polygonVertex   :: Int,
        polygonAngleMin :: Float
    }
    deriving (Show)

        import Data.Bool

        main:: IO()
        main = do
            linea <- getLine
            lista <- loop (read linea)
            mapM_ print lista

        loop:: Int -> IO [Int]
        loop numero
          | numero == 0 = return []
          | otherwise   = do
             sn <- getLine
             let n = read sn::Int
             others <- loop (numero-1)
             return ((poligonoMin n polygons) : others)

        poligonoMin:: Int -> [Polygon] -> Int
        poligonoMin angulo (p:ps) =
            if (posible angulo p)
                then (nverts p)
                else  poligonoMin angulo ps

        posible:: Int -> Polygon -> Bool
        posible angulo poligono
            -- trabajar los angulos como float
            -- ver si cae una cantidad de veces entera
            | (fromIntegral angulo)/(nangleMin poligono) /= fromInteger(round ((fromIntegral angulo)/(nangleMin poligono))) = False
            | ((fromIntegral angulo)/(nangleMin poligono)) > fromIntegral((nverts poligono) - 2) = False
            | otherwise = True

        polygons :: [Polygon]
        polygons = let
            poligono n = Polygon n (180/(fromIntegral n))
            in map poligono [3..]-- funcion lista

        nverts :: Polygon ->Int
        nverts (Polygon n _) = n

        nangleMin :: Polygon -> Float
        nangleMin (Polygon _ n) = n

        data Polygon = Polygon
            {
                polygonVertex   :: Int,
                polygonAngleMin :: Float
            }
            deriving (Show)

import Data.Fixed

import Data.List

data Polygon = Polygon {vertice :: Int, angulo :: Double} deriving (Show)

instance Eq Polygon where
    (==) (Polygon ver1 ang1) (Polygon ver2 ang2) =
        (ver1 == ver2) && (ang1 == ang2)
    (==) a b = False

main = do
    let poli = poligonos [3,4..]
    n_query <- getLine
    listofquerys <- sequence (take (read n_query :: Int) (repeat getLine))
    let intquerys = map (read :: String -> Int) listofquerys
    let temp = respuesta intquerys poli
    putStrLn (intercalate "\n" temp)

poligonos :: [Int] -> [Polygon]
poligonos (a:as) = let
    ver = a
    ang = 180.0 / (fromIntegral a)
    in Polygon {vertice = ver, angulo = ang}:(poligonos as)

respuesta :: [Int] -> [Polygon] -> [String]
respuesta [a] b = let
    listafiltrada = filter (\p -> comprobar a p) b
    in if listafiltrada == []
        then "-1" : []
        else show (vertice (head listafiltrada)) : []
respuesta (a:as) b = let
    listafiltrada = filter (\p -> comprobar a p) b
    in if listafiltrada == []
        then "-1" : (respuesta as b)
        else show (vertice (head listafiltrada)) : (respuesta as b)

comprobar :: Int -> Polygon -> Bool
comprobar a b
    | (fromIntegral a) < (angulo b) = False
    | (fromIntegral a) > ((angulo b) * (fromIntegral (vertice b) - 2.0)) = False
    | mod' (fromIntegral a) (angulo b) == 0.0 = True
    | otherwise = False

import Data.Fixed

import Data.List

data Polygon = Polygon {vertice :: Int, angulo :: Double} deriving (Show)

instance Eq Polygon where
    (==) (Polygon ver1 ang1) (Polygon ver2 ang2) =
        (ver1 == ver2) && (ang1 == ang2)
    (==) a b = False

main = do
    let poli = poligonos [3,4..]
    n_query <- getLine
    listofquerys <- sequence (replicate (read n_query :: Int) getLine)
    let intquerys = map (read :: String -> Int) listofquerys
    let temp = respuesta intquerys poli
    putStrLn (intercalate "\n" temp)

poligonos :: [Int] -> [Polygon]
poligonos (a:as) = let
    ver = a
    ang = 180.0 / (fromIntegral a)
    in Polygon {vertice = ver, angulo = ang}:(poligonos as)

respuesta :: [Int] -> [Polygon] -> [String]
respuesta [a] b = let
    listafiltrada = filter (\p -> comprobar a p) b
    in if listafiltrada == []
        then "-1" : []
        else show (vertice (head listafiltrada)) : []
respuesta (a:as) b = let
    listafiltrada = filter (\p -> comprobar a p) b
    in if listafiltrada == []
        then "-1" : (respuesta as b)
        else show (vertice (head listafiltrada)) : (respuesta as b)

comprobar :: Int -> Polygon -> Bool
comprobar a b
    | (fromIntegral a) < (angulo b) = False
    | (fromIntegral a) > ((angulo b) * (fromIntegral (vertice b) - 2.0)) = False
    | mod' (fromIntegral a) (angulo b) == 0.0 = True
    | otherwise = False

calculo :: Int -> Int
calculo recibir =
    let n = 180 `div` (gcd 180 recibir)
    in if recibir <= 180 `div` n * (n - 2)
        then n
        else (2 * n)

main = do
    _ <- getLine
    contenido <- getContents
    mapM_ (print . calculo . read) $ lines contenido

import Data.List
import qualified Data.Fixed as Fi

data Polygon = Polygon{angulo :: Float , vertice :: Int} deriving (Eq, Show)

obPolygons :: [Int] -> [Polygon]
obPolygons (x:xs)= let
                anglePolygon = 180.0/(fromIntegral x)
                verticePolygon = x
                in Polygon{angulo=anglePolygon,vertice = verticePolygon}:obPolygons(xs)

--Esta funcion nos sice si se logra con el poligono
achievesPolygon :: Float -> [Polygon] -> Polygon
achievesPolygon angulo (x:xs) = if((Fi.mod' angulo (angles x))==0 && fromIntegral (div (((vertices x)-2)*180) (vertices x)) >= angulo) then x
        else achievesPolygon angulo xs

-- Nos obtines los angulos
angles :: Polygon -> Float
angles (Polygon {angulo = a , vertice = v}) = a

--Nos obtiene los vertices
vertices :: Polygon -> Int
vertices (Polygon {angulo = a , vertice = v}) = v

--Nos entrega una lista con los vertices
obVertices :: [Float] -> [Polygon] -> [Int]
obVertices [] _ = []
obVertices (x:xs) poly =
    [n] ++ (obVertices xs poly)
    where n = vertices (achievesPolygon x poly)

--Se ocupa para poder dejar todo en String y mostrarlo por pantalla
joinPrint :: [Int] -> String
joinPrint [] = ""
joinPrint [x] = show x
joinPrint (x:xs) = show x ++"\n"++(joinPrint xs)

main :: IO()
main = do
    datos <- getLine
    listAngles1 <- sequence (take (read datos::Int) (repeat getLine))
    let listAngles = map (read::String->Float) listAngles1
    let listVertices = obVertices listAngles (obPolygons [3..998244353])
    putStrLn (joinPrint listVertices)

import Control.Monad

data Polygon = Polygon {angin :: Float,angmin :: Float} deriving (Show)

lista_inf:: [Polygon]
lista_inf = [Polygon (((fromIntegral i)-2)*180/(fromIntegral i)) (180.0/(fromIntegral i)) | i <- [3..]]

main = do
  input <- getLine
  inputs <- replicateM (read input) getLine
  let x = map (read::String->Float) inputs
  let z = map auxi x
  mapM_ print (map round z)

fun2:: Float -> [Polygon] -> Polygon
fun2 ang (x:xs) =
    if ((ang == (angmin x)) || (ang == (angin x)))
        then x
    else if (ang < (angmin x))
            then (fun2 ang xs)
        else if (lograr ang x)
                then x
            else (fun2 ang xs)

lograr:: Float -> Polygon -> Bool
lograr ang pol = do
    let res = (angin pol) - ang
    if (res < 0)
        then False
    else if (floor (angmin pol) == ceiling (angmin pol))
            then if (((round res) `mod` (round (angmin pol))) == 0) then True else False
        else False

auxi:: Float -> Float
auxi n =
    if (n>180 || n<=0) then -1.0 else (nver (fun2 n lista_inf))

nver:: Polygon -> Float
nver pol = 360/(180 - (angin pol))

import Control.Monad

data Polygon = Polygon {angin :: Float,angmin :: Float} deriving (Show)

lista_inf:: [Polygon]
lista_inf = [Polygon (((fromIntegral i)-2)*180/(fromIntegral i)) (180.0/(fromIntegral i)) | i <- [3..]] -- Se crea la lista infinita de poligonos

main = do
  input <- getLine
  inputs <- replicateM (read input) getLine
  let x = map (read::String->Float) inputs --x siendo la lista de los inputs
  let z = map fun x
  mapM_ print (map round z)

fun2:: Float -> [Polygon] -> Polygon --Funcion que recorre la lista de Polygons y entrega el primer poligono que cumpla la condicion
fun2 ang (x:xs) =
    if ((ang == (angmin x)) || (ang == (angin x)))
        then x
    else if (ang < (angmin x))
            then (fun2 ang xs)
        else if (lograr ang x)
                then x
            else (fun2 ang xs)

lograr:: Float -> Polygon -> Bool --Funcion que verifica si se puede formar el angulo de entrada con los angulos dentro del poligono
lograr ang pol = do
    let res = (angin pol) - ang
    if (res < 0)
        then False
    else if (floor (angmin pol) == ceiling (angmin pol)) --Si el angulo minimo del poligono es un decimal, se entraga falso ya que las entradas son int y/o ese angulo se puede formar con algun poligono anterior
            then if (((round res) `mod` (round (angmin pol))) == 0) then True else False
        else False

fun:: Float -> Float
fun n = if (n>180 || n<=0) then -1.0 else (nver (fun2 n lista_inf)) --funcion que retorna -1 si el angulo no esta entre 1 y 180 y retorna el numero de vertices del poligono que cumpla la condicion

nver:: Polygon -> Float --Funcion que otorga el numero de vertices del poligono
nver pol = 360/(180 - (angin pol))

import Control.Monad
data Polygon = Polygon { angulo :: Float, vertice :: Int}

--Funcion principal que nos permite obtener la lista de los verticeses de todos los imput solicitados nos ayuda a formar la resp final
funcion :: [Int] -> String-> [Int]
funcion [] angulo1 = let
  in [vertices (head (filter (es_poligono (read angulo1 :: Float))  (map polygon [3 ..])))]
funcion (x:xs) angulo1 = let
  in vertices (head (filter (es_poligono (read angulo1 :: Float))  (map polygon[3 ..]))) : (x:xs)
--Funcion que nos permite en el output dar vuelta la lista de la funcion principal puesto que la funcion en la primera posicion esta el ultimo leido y asi
revertir_lista:: [numero] -> [numero]
revertir_lista [] = []
revertir_lista (x:xs) = revertir_lista (xs) ++ [x]
--Outout final
output:: Int -> IO ()
output out =
    print out

--Confirmacion si es o no posible con el angulo entregado obtener un poligono regular ocupa el angulo minimo que pueda obterner de un poligono regular cualquiera
--La formula emplea sus diag (n-2) y el angulo dado
es_poligono :: Float -> Polygon -> Bool
es_poligono angulo1
  Polygon { angulo = ang,
    vertice = vert} = let
  ang_min= ang / ((fromIntegral vert) - 2)
  angulos = [ang, (ang - ang_min) .. ang_min]
  in if (angulo1 `elem` angulos) --Ve si el angulo esta dentro de las posibilidades de formar parte de un regular idea: http://zvon.org/other/haskell/Outputprelude/elem_f.html
    then True
        else False

--Gnera los poligonos regulares solicitaodos ocupamos la formula de angulo en los vertices dada en uno de los links
polygon :: Int -> Polygon
polygon vert =
    Polygon { angulo = (180*((fromIntegral vert) - 2)) / fromIntegral vert,
        vertice = vert}

--Obtiene los vertices
vertices :: Polygon -> Int
vertices Polygon
    {vertice = vert,
        angulo = ang} =
            vert

--Consultamos al usuario las consultas y posterior ingresa uno a uno los angulos dependiendo del numero de consultas
--Iteramos la lista de los angulos mediante un foldl
--Posterior llamamos a nuestra funcion principal  y imprimimos la resp por pantalla
--
main::IO()
main = do
    numero_consulta <- getLine
    lista_angulos <- replicateM (read numero_consulta :: Int) getLine
    (mapM_ output(revertir_lista (foldl funcion [] lista_angulos)))

import System.Environment
import System.IO
import qualified Data.Fixed as F

main = do
  cant<- getLine
  angulos <- readLines (read cant::Int)
  let listaPoli = infAngles 3
      final = maker angulos listaPoli
  mapM print (map toInt final)
data Poligon = Poligon {  vertices :: Float
                        , angMenor :: Float
                        } deriving (Show)

readLines :: Int -> IO [Float]
readLines 0 = return []
readLines n = do
   x <- fmap read getLine
   rest <- readLines (n-1)
   return $ x : rest

infAngles :: Float -> [Poligon]
infAngles vert =
  let minAngle = (/) 180.0 vert
      poli = (Poligon vert minAngle)
  in poli:(infAngles (vert+1))

minAng :: Float -> [Poligon] ->Poligon
minAng num (p:ps) =
  let nVer = nVerts p in
    if ((F.mod' num (mAngle p)) == 0 && ((nVer-2)*180/nVer) >= num )

      then
        p
    else
      minAng num ps

nVerts :: Poligon -> Float
nVerts (Poligon n _ ) = n

mAngle :: Poligon -> Float
mAngle (Poligon _ a ) = a

maker :: [Float] -> [Poligon] ->[Float]
maker [] _ = []
maker (x:xs) listaPoli =
  let pol = minAng x listaPoli
  in [(nVerts pol)] ++ (maker xs listaPoli)

toInt :: Float -> Int
toInt = round

data Polygon = Polygon {ver :: Int, ang :: Int}

main = do
  queries <- getLine
  commands <- sequence (replicate (read queries) getLine)
  let min = foldl iterator [] commands
  let answers = reverse min
  mapM_ showMin answers

showMin :: Int -> IO ()
showMin x = print x

iterator :: [Int] -> String -> [Int]
iterator [] angle = let
  check = checkAngle (read angle)
  polygonList = map polygonGenerator [3 ..]
  posibleAnswers = filter check polygonList
  in [getVer (head posibleAnswers)]
iterator (a:as) angle = let
  check = checkAngle (read angle :: Float)
  polygonList = map polygonGenerator [3 ..]
  posibleAnswers = filter check polygonList
  in getVer (head posibleAnswers) : (a:as)

getVer :: Polygon -> Int
getVer Polygon {ver = x, ang = y} = x

polygonGenerator :: Int -> Polygon
polygonGenerator x = Polygon {ver = x, ang = ((x-2) * 180) `div` x}

checkAngle :: Float -> Polygon -> Bool
checkAngle angle Polygon {ver = x, ang = y} = let
  a = toFloat x
  b = toFloat y
  c = b / (a-2)
  angulos = [b, (b - c) .. c]
  in if (angle `elem` angulos) then True else False

toFloat :: Int -> Float
toFloat x = fromIntegral x

data Polygon = Polygon {ver :: Int, ang :: Int}

main = do
  queries <- getLine
  commands <- sequence (replicate (read queries) getLine)
  let min = foldl iterator [] commands
  let answers = reverse min
  mapM_ showMin answers

showMin :: Int -> IO ()
showMin x = print x

iterator :: [Int] -> String -> [Int]
iterator [] angle = let
  check = checkAngle (read angle)
  polygonList = map polygonGenerator [3 ..]
  posibleAnswers = filter check polygonList
  in [getVer (head posibleAnswers)]
iterator (a:as) angle = let
  check = checkAngle (read angle)
  polygonList = map polygonGenerator [3 ..]
  posibleAnswers = filter check polygonList
  in getVer (head posibleAnswers) : (a:as)

getVer :: Polygon -> Int
getVer Polygon {ver = x, ang = y} = x

polygonGenerator :: Int -> Polygon
polygonGenerator x = Polygon {ver = x, ang = ((x-2) * 180) `div` x}

checkAngle :: Int -> Polygon -> Bool
checkAngle angle Polygon {ver = x, ang = y} = let
  angulos = [y, (y - (y `div` (x-2))) .. (y `div` (x-2))]
  in if (angle `elem` angulos) then True else False

import Data.Fixed (mod')

data Polygon = Polygon { vertex :: Int
                       , minAngle :: Float
                       , maxAngle :: Float
                       , intAngle :: Float
                       } deriving (Show)

poryList :: [Int] -> [Polygon]
poryList [] = []
poryList (3:xs) = (Polygon { vertex = 3, minAngle = 60.0, maxAngle = 60.0, intAngle = 60.0}):(poryList xs)
poryList (4:xs) = (Polygon { vertex = 4, minAngle = 90.0, maxAngle = 90.0, intAngle = 90.0}):(poryList xs)
poryList (x:xs) = (Polygon { vertex = x, minAngle = ang, maxAngle = ang * (y - 4), intAngle = ang * (y - 2)}):(poryList xs)
    where y = fromIntegral x :: Float
          ang = 180 / y

checkPory :: [Polygon] -> Int -> Int
checkPory [] _ = -1
checkPory (x:xs) n
    | n == 180 = -1
    | mod' nn (minAngle x) == 0 && nn <= (maxAngle x) = vertex x
    | nn == intAngle x = vertex x
    | otherwise = checkPory xs n
    where nn = fromIntegral n :: Float

checkFor :: [Polygon] -> [Int] -> [Int]
checkFor _ [] = []
checkFor x (y:ys) = (checkPory x y):(checkFor x ys)

main :: IO()
main = do
    let h = poryList [3..]
    q <- getLine
    let query = (read q :: Int)
    angList <- (sequence (replicate query getLine))
    let pList = map (read :: String -> Int) angList
    mapM_ print (checkFor h pList)

import Data.Fixed (mod')

data Polygon = Polygon { vertex :: Int
                       , minAngle :: Float
                       , maxAngle :: Float
                       , intAngle :: Float
                       } deriving (Show)

poryList :: [Int] -> [Polygon]
poryList [] = []
poryList (3:xs) = (Polygon { vertex = 3, minAngle = 60.0, maxAngle = 60.0, intAngle = 60.0}):(poryList xs)
poryList (4:xs) = (Polygon { vertex = 4, minAngle = 45.0, maxAngle = 45.0, intAngle = 90.0}):(poryList xs)
poryList (x:xs) = (Polygon { vertex = x, minAngle = ang, maxAngle = ang * (y - 4), intAngle = ang * (y - 2)}):(poryList xs)
    where y = fromIntegral x :: Float
          ang = 180 / y

checkPory :: [Polygon] -> Int -> Int
checkPory [] _ = -1
checkPory (x:xs) n
    | n >= 180 = -1
    | mod' nn (minAngle x) == 0 && nn <= (maxAngle x) = vertex x
    | nn == intAngle x = vertex x
    | otherwise = checkPory xs n
    where nn = fromIntegral n :: Float

checkFor :: [Polygon] -> [Int] -> [Int]
checkFor _ [] = []
checkFor x (y:ys) = (checkPory x y):(checkFor x ys)

main :: IO()
main = do
    let h = poryList [3..]
    q <- getLine
    let query = (read q :: Int)
    angList <- (sequence (replicate query getLine))
    let pList = map (read :: String -> Int) angList
    mapM_ print (checkFor h pList)

import Control.Monad
import Data.List
import Data.Fixed
data Polygon = Polygon {angulo :: Float, vertice :: Int} deriving (Show)

instance Eq Polygon where  --Instancia pedida en el bonus
    (==) (Polygon ver1 ang1) (Polygon ver2 ang2) = (ver1 == ver2) && (ang1 == ang2)
    (==) a b = False

poly :: [Int] -> [Polygon] --Generador de poligonos
poly (x:xs) = let
    vert = x
    ang = 180.0 / (fromIntegral x) in Polygon { angulo = ang, vertice = vert}:poly xs

minVert :: [Int] -> [Polygon] -> [String] --Función encargada de entregar el angulo mínimo correspondiente a cada caso
minVert [a] b = let
    filteredList = filter (\p -> aux a p) b in if filteredList == []
        then "-1" : []
        else show (vertice (head filteredList)) : []
minVert (a:as) b = let
    filteredList = filter (\p -> aux a p) b in if filteredList == []
        then "-1" : (minVert as b)
        else show (vertice (head filteredList)) : (minVert as b)

aux :: Int -> Polygon -> Bool  --Función que ratifica que el angulo obtenido exista
aux x y
    | mod' (fromIntegral x) (angulo y) == 0.0 = True
    | (fromIntegral x) < (angulo y) = False
    | (fromIntegral x) > ((angulo y) * (fromIntegral (vertice y) - 2.0)) = False
    | otherwise = False

main :: IO ()
main = do
    casos <- getLine
    let n = read casos::Int
    angulos <- replicateM n getLine
    let poligonos = poly [3..998244353]
    let intAngulos = map (read :: String -> Int) angulos
    let output = minVert intAngulos poligonos
    putStrLn (intercalate "\n" output)

import System.IO

data Polygon = Polygon { vertices ::Int ,minAng ::Float} deriving(Show)

toInt:: Float->Int
toInt = round

canBeDone:: Polygon-> Int -> Bool
canBeDone p a=  a `mod` toInt (minAng p) == 0

forEach ::[Polygon]->Int ->Int
forEach [] a= (-1)
forEach (p:ps) a= do
    if(canBeDone p a)
        then getVertices p
        else if(getVertices p <2000000)
            then forEach ps a
            else -1

getIterationsLines :: Int ->[Polygon] -> IO [String]
getIterationsLines n lista
    | n <= 0 = return []
    | otherwise = do
        angle <- getLine
        print $ forEach lista (read angle ::Int)
        xs <- getIterationsLines (n-1) lista
        return (angle:xs)

forLoop ::Int->[Polygon]->Int
forLoop 0 _ = (-1)
forLoop n list=
    if (n>0)
    then do
        -- let min= forEach list readLine
        forLoop (n-1) list
    else
        0

getVertices:: Polygon -> Int
getVertices p = vertices p

main = do
    iterations <- getLine
    let lista_infinita = [ Polygon i (180/fromIntegral i) | i<-[3..]]
    let ite = read iterations::Int
    getIterationsLines ite lista_infinita
    return ()

import System.IO
import Data.Fixed

data Polygon = Polygon { vertices ::Int ,minAng ::Float} deriving(Show)

canBeDone:: Polygon-> Float -> Bool
canBeDone p a= mod' a (minAng p) == 0.0
forEach ::[Polygon]->Float ->Int
forEach [] a= (-1)
forEach (p:ps) a= do
    if(canBeDone p a)
        then getVertices p
        else if(getVertices p <2000000)
            then forEach ps a
            else -1

getIterationsLines :: Int ->[Polygon] -> IO [String]
getIterationsLines n lista
    | n <= 0 = return []
    | otherwise = do
        angle <- getLine
        print $ forEach lista (read angle ::Float)
        xs <- getIterationsLines (n-1) lista
        return (angle:xs)

getVertices:: Polygon -> Int
getVertices p = vertices p

main = do
    iterations <- getLine
    let lista_infinita = [ Polygon i (180/fromIntegral i) | i<-[3..]]
    let ite = read iterations::Int
    getIterationsLines ite lista_infinita
    return ()

import Control.Monad
import Data.List
--se crea el data Polygon con los datos angulosInt, vertices, anguloMin y anguloMax
data Polygon = Polygon {
    angulosInt ::Double,
    vertices ::Int,
    anguloMin ::Double,
    anguloMax ::Double
} deriving (Ord, Eq,Show)

--se define cada uno de los atributos de Polygon
--angulos internos = 180*(cantidad de vertices-2)
--angulo Maximo = angulos Internos / cantidad de vertices
--angulo Minimo (este fue probando) = angulo maximo / (cantidad de vertices - 2)
--Recibe un Int (cantidad de vertices) y entrega un Polygon con todos sus datos
define :: Int -> Polygon
define ver = let
    doubVer = fromIntegral ver ::Double
    angInt = 180.0 * (doubVer - 2.0)
    angMax = angInt / doubVer
    angMin = angMax/(doubVer-2.0)
    in Polygon {vertices = ver, angulosInt = angInt, anguloMin = angMin, anguloMax = angMax}

--entrega el poligono donde se puede formar el angulo
buscarPol :: Int -> Polygon -> Polygon
buscarPol ang pol = let
    ver = vertices pol
    in if (isPol (fromIntegral ang ::Double) pol) then pol else buscarPol ang (define (ver+1))

--Comprueba si es el polygono pedido
--recibe un angulo y el polygono inicial y entrega True si es el polygono que se pide y False en caso contrario
isPol :: Double-> Polygon -> Bool
isPol ang pol=let
    angMin = anguloMin pol
    angMax = anguloMax pol
    --angs1 es la división normal, angs2 es la division entera entre el angulo dado y el angulo minimo del poligono
    angs1 = (ang / angMin)
    angs2 = (fromIntegral (round (ang/angMin)) :: Double)
    --si angs1 y angs2 son iguales significa que el angulo minimo es divisor del angulos dado, por lo que es el poligono pedido
    in if (ang<=angMax && angs1-angs2==0.0) then True else False

output:: String -> IO ()
output out = print (out)

main::IO()
main = do
    consultas <- getLine
    --se recibe un input multiple con replicateM
    angulos <- replicateM (read consultas ::Int) getLine
    let polInicial = define 3
    --se crea la lista de polygonos, al reves, por lo que se utiliza reverse para mantenerla segun lo dado por el usuario
    --luego se entrega en consola cada uno de los datos con intercalate y la función output
    output (intercalate " " (reverse (foldl (\x y -> (show (vertices (buscarPol (read y ::Int) polInicial))) : x) [] angulos)))

import qualified Data.ByteString.Char8 as C
data Polygon = Polygon {vertexNumber :: Int, minAngle :: Double, angles :: [Double]} deriving (Show)
isInt x = x == fromInteger (round x)

polygonList = [Polygon{vertexNumber = i, minAngle = 180.0/(fromIntegral i :: Double), angles = [((180.0/(fromIntegral i :: Double)) * (fromIntegral (j - 2) :: Double)) | j <- [3..i]]} | i <- [3..]]
possibleAngle :: Double -> Bool
possibleAngle angle = let
    polygon = take 1 ([polygon | polygon <- (filter ((\a x -> elem a (angles x)) angle) polygonList)]) -- arreglar
    len = length polygon
    in if((len == 1) && ((vertexNumber (polygon !! 0) ) <= 998244353)) then True else False

containsAngle :: Polygon -> Double -> Bool
containsAngle polygon angle = if ((mod ((round angle :: Int)*2*(vertexNumber polygon)) 360) == 0) then True else False

solution angle = vertexNumber (head [ polygon | polygon <- polygonList, True == containsAngle polygon angle]) -- usando lazyness

readChar8 :: IO [Int]
readChar8 = map parse . C.words <$> C.getContents where parse s = let Just (n, _) = C.readInt s in n

main :: IO()
main = do
  ints <- readChar8
  let (n:xs) = ints
  mapM_ (\x -> print (solution (fromIntegral x :: Double))) xs
  --CTRL + D

import System.IO
import Data.List
import Control.Monad

data Polygon = Polygon {n_vertices :: Int, angulo_minimo :: Int} deriving (Show)

crearPoligonos :: Int -> Polygon
crearPoligonos n
    | (180 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 180 `div` n}
    | otherwise = Polygon {n_vertices = n, angulo_minimo = 180}

pasarAPolygon :: [Polygon] -> String -> Int
pasarAPolygon (x:xs) num
    | ((read num :: Int) `mod` (angulo_minimo x) == 0) = n_vertices x
    | otherwise = pasarAPolygon xs num

main = do
    input <- getLine
    inputs <- replicateM (read input) getLine
    let poligonos_infinitos = map crearPoligonos [3..]
    let final = map (pasarAPolygon poligonos_infinitos) inputs
    mapM print final

import System.IO
import Data.List
import Control.Monad

data Polygon = Polygon {n_vertices :: Int, angulo_minimo :: Int} deriving (Show)

crearPoligonos :: Int -> Polygon
crearPoligonos n
    | (180 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 180 `div` n}
    | otherwise = Polygon {n_vertices = n, angulo_minimo = 181}

pasarAPolygon :: [Polygon] -> String -> Int
pasarAPolygon (x:xs) num
    | ((n `mod` (angulo_minimo x) == 0) && ((((n_vertices x)-2)*180) `div` n_vertices x) >= n) = n_vertices x
    | (n_vertices x > 180) = -1
    | otherwise = pasarAPolygon xs num
    where n = read num :: Int

main = do
    input <- getLine
    inputs <- replicateM (read input) getLine
    let poligonos_infinitos = map crearPoligonos [3..]
    let final = map (pasarAPolygon poligonos_infinitos) inputs
    mapM print final

import System.IO
import Data.List
import Control.Monad

data Polygon = Polygon {n_vertices :: Int, angulo_minimo :: Int} deriving (Show)

crearPoligonos :: Int -> Polygon
crearPoligonos n
    | (180 `mod` n == 0) = Polygon {n_vertices = n, angulo_minimo = 180 `div` n}
    | (n == 360) = Polygon {n_vertices = n, angulo_minimo = 1}
    | otherwise = Polygon {n_vertices = n, angulo_minimo = 181}

pasarAPolygon :: [Polygon] -> String -> Int
pasarAPolygon (x:xs) num
    | ((n `mod` (angulo_minimo x) == 0) && ((((n_vertices x)-2)*180) `div` n_vertices x) >= n) = n_vertices x
    | (n_vertices x > 360) = -1
    | otherwise = pasarAPolygon xs num
    where n = read num :: Int

main = do
    input <- getLine
    inputs <- replicateM (read input) getLine
    let poligonos_infinitos = map crearPoligonos [3..]
    let final = map (pasarAPolygon poligonos_infinitos) inputs
    mapM print final

import System.Environment
import System.IO

main = do
  cant<- getLine
  angulos <- readLines (read cant::Int)
  let listaPoli = foldl infAngles [] [3..]
  print angulos
  print (nVerts (head listaPoli))

data Poligon = Poligon {  vertices :: Int
                        , angMenor :: Int
                        } deriving (Show)

readLines :: Int -> IO [Int]
readLines 0 = return []
readLines n = do
   x <- fmap read getLine
   rest <- readLines (n-1)
   return $ x : rest

infAngles :: [Poligon] -> Int -> [Poligon]
infAngles list vert =
  let minAngle = 180 `div` vert
      poli = (Poligon vert minAngle)
  in poli:list

nVerts :: Poligon -> Int
nVerts (Poligon n _ ) = n


After returning from the army Makes received a gift — an array a consisting of n positive integer numbers. He hadn't been solving problems for a long time, so he became interested to answer a particular question: how many triples of indices (i,  j,  k) (i < j < k), such that ai·aj·ak is minimum possible, are there in the array? Help him with it!

The first line of input contains a positive integer number n (3 ≤ n ≤ 105) — the number of elements in array a. The second line contains n positive integer numbers ai (1 ≤ ai ≤ 109) — the elements of a given array.

Print one number — the quantity of triples (i,  j,  k) such that i,  j and k are pairwise distinct and ai·aj·ak is minimum possible.

NoteIn the first example Makes always chooses three ones out of four, and the number of ways to choose them is 4.In the second example a triple of numbers (1, 2, 3) is chosen (numbers, not indices). Since there are two ways to choose an element 3, then the answer is 2.In the third example a triple of numbers (1, 1, 2) is chosen, and there's only one way to choose indices.

{-# LANGUAGE TupleSections #-}
import           Control.Applicative
import           Control.Monad
import qualified Data.ByteString.Char8 as BS
import           Data.List

getInts::IO [Integer]
getInts = go <$> BS.getLine where
  go s = case  BS.readInteger s of
      Nothing      -> []
      Just (x, s') -> x : go (BS.drop 1 s')

minCnt::(Integer, Integer)->(Integer, Integer)->(Integer, Integer)
minCnt (x, v) (y, w) = case compare x y of
                          EQ -> (x, v + w)
                          LT -> (x, v)
                          GT -> (y, w)

minProds::[Integer]->[(Integer, Integer)]->[(Integer, Integer)]
minProds xs us = let vs = reverse $ scanl1 minCnt $ reverse us
                     prod x (y, v) = (x * y, v)
                 in  zipWith prod xs $ tail vs

solution::[Integer]->Integer
solution xs = let mps1   = minProds  xs $ fmap (, 1) xs
                  mps2   = minProds  xs mps1
                  mm     = foldl1' minCnt mps2
              in snd mm

main :: IO ()
main = do
  void getLine
  xs <- getInts
  print $ solution xs

{-# LANGUAGE BangPatterns #-}
module Main where
import qualified Data.ByteString.Char8 as B
import Data.List
import Data.Int

readInt = maybe undefined fst . B.readInt
readInts = fmap readInt . B.words

solve xs = foldl (\(!c) ((lm, lc), x, (rm, rc)) -> if sort [lm, x, rm] == min3 then c + lc * rc else c) 0 $ zip3 lmc (tail xs) (tail $ tail rmc)
  where
    min3 = take 3 $ sort xs
    iv = (10^(9 :: Int), 0 :: Int64)
    lmc = tail $ scanl go iv xs
    rmc = reverse $ tail $ scanl go iv $ reverse xs
    go (!m, !c) x
      | m < x = (m, c)
      | m == x = (m, c + 1)
      | otherwise = (x, 1)

main = do
  B.getLine
  xs <- fmap readInts B.getLine
  print $ solve xs

{-# LANGUAGE BangPatterns #-}
module Main where
import qualified Data.ByteString.Char8 as B
import Data.List
import Data.Int

readInt = maybe undefined fst . B.readInt
readInts = fmap readInt . B.words

solve xs = foldl (\(!c) ((lm, lc), x, (rm, rc)) -> if sort [lm, x, rm] == min3 then c + lc * rc else c) 0 $ zip3 lmc (tail xs) (tail $ tail rmc)
  where
    min3 = take 3 $ sort xs
    iv = (10^(9 :: Int), 0 :: Integer)
    lmc = tail $ scanl go iv xs
    rmc = reverse $ tail $ scanl go iv $ reverse xs
    go (!m, !c) x
      | m < x = (m, 1)
      | m == x = (m, c + 1)
      | otherwise = (x, 1)

main = do
  B.getLine
  xs <- fmap readInts B.getLine
  print $ solve xs

{-# LANGUAGE BangPatterns #-}
module Main where
import qualified Data.ByteString.Char8 as B
import Data.List
import Data.Int

readInt = maybe undefined fst . B.readInt
readInts = fmap readInt . B.words

solve xs = foldl (\(!c) ((lm, lc), x, (rm, rc)) -> if sort [lm, x, rm] == min3 then c + lc * rc else c) 0 $ zip3 lmc (tail xs) (tail $ tail rmc)
  where
    min3 = take 3 $ sort xs
    iv = (10^(9 :: Int), 0 :: Int64)
    lmc = tail $ scanl go iv xs
    rmc = reverse $ tail $ scanl go iv $ reverse xs
    go (!m, !c) x
      | m < x = (m, 1)
      | m == x = (m, c + 1)
      | otherwise = (x, 1)

main = do
  B.getLine
  xs <- fmap readInts B.getLine
  print $ solve xs

{-# LANGUAGE BangPatterns #-}
module Main where
import qualified Data.ByteString.Char8 as B
import Data.List

readInt = maybe undefined fst . B.readInt
readInts = fmap readInt . B.words

solve xs = foldl (\(!c) ((lm, lc), x, (rm, rc)) -> if sort [lm, x, rm] == min3 then c + lc * rc else c) 0 $ zip3 lmc (tail xs) (tail $ tail rmc)
  where
    min3 = take 3 $ sort xs
    iv = (10^(9 :: Int), 0 :: Int)
    lmc = tail $ scanl go iv xs
    rmc = reverse $ tail $ scanl go iv $ reverse xs
    go (!m, !c) x
      | m < x = (m, 1)
      | m == x = (m, c + 1)
      | otherwise = (x, 1)

main = do
  B.getLine
  xs <- fmap readInts B.getLine
  print $ solve xs


Mike has n strings s1, s2, ..., sn each consisting of lowercase English letters. In one move he can choose a string si, erase the first character and append it to the end of the string. For example, if he has the string "coolmike", in one move he can transform it into the string "oolmikec".Now Mike asks himself: what is minimal number of moves that he needs to do in order to make all the strings equal?

The first line contains integer n (1 ≤ n ≤ 50) — the number of strings. This is followed by n lines which contain a string each. The i-th line corresponding to string si. Lengths of strings are equal. Lengths of each string is positive and don't exceed 50.

Print the minimal number of moves Mike needs in order to make all the strings equal or print  - 1 if there is no solution.

NoteIn the first sample testcase the optimal scenario is to perform operations in such a way as to transform all strings into "zwoxz".

module Main where

import Control.Applicative
import Data.List
import Control.Monad

rotates :: [a] -> [[a]]
rotates xs = init $ zipWith (++) ts is
    where is = inits xs
          ts = tails xs

solve :: [String] -> Int
solve ss | null candidates = -1
         | otherwise = minimum candidates
    where candidates = filter (/= (-1)) $ map numSteps ss
          rs = map rotates ss
          numSteps gs = case liftM sum . sequence $ map (findIndex (== gs)) rs of
                          Just s -> s
                          Nothing -> -1

test0 = ["xzzwo", "zwoxz", "zzwox", "xzzwo"]
test1 = ["molzv", "lzvmo"]
test2 = ["kc", "kc", "kc"]
test3 = ["aa", "aa", "ab"]

main :: IO ()
main = do
  n <- read <$> getLine
  ss <- replicateM n getLine
  print $ solve ss

import           Control.Applicative
import           Control.Arrow
import           Control.Monad
import           Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as BS
import           Data.Char
import           Data.Foldable
import           Data.Monoid
import           Data.Traversable

getInt::IO Int
getInt = do
  line <- BS.getLine
  let Just (x, _ ) = BS.readInt line
  return x

shift::Int->ByteString->ByteString
shift i = BS.append <$> BS.drop i <*> BS.take i

newtype Min = Min{getMin::Int} deriving (Eq, Ord, Show)
instance Monoid Min where
  Min a `mappend` Min b = Min (min a b)
  mempty = Min maxBound

main = do
  n <- getInt
  l1:ls <- replicateM n readLine
  let shifts l = (,) . Min <*> (`shift` l) <$>  [0..BS.length l - 1]
      lastRes = foldM minRevAll (shifts l1) ls
      minRevAll prev l = (fmap . flip (,) . snd <*>  minRev prev) `traverse` shifts l
      minRev prev (i, l) = (+~i)  <$> foldMap (check l) prev
      check l (j, p) = if p == l then Just j else Nothing
      result = maybe (-1) (getMin . foldMap fst) lastRes
      Min a +~ Min b = Min (a + b)
  print result where readLine = BS.takeWhile isAlpha <$> BS.getLine

import           Control.Applicative
import           Control.Arrow
import           Control.Monad
import           Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as BS
import           Data.Char
import           Data.Foldable
import           Data.Monoid
import           Data.Traversable

getInt::IO Int
getInt = do
  line <- BS.getLine
  let Just (x, _ ) = BS.readInt line
  return x

shift::Int->ByteString->ByteString
shift i = BS.append <$> BS.drop i <*> BS.take i

newtype Min a= Min{getMin::a} deriving (Eq, Ord, Show)
instance (Bounded a, Ord a) => Monoid (Min a) where
  Min a `mappend` Min b = Min (min a b)
  mempty = Min maxBound

main = do
  n <- getInt
  l1:ls <- replicateM n readLine
  let shifts l = (,) . Min <*> (`shift` l) <$>  [0..BS.length l - 1]
      lastRes = foldM minRevAll (shifts l1) ls
      minRevAll prev l = (fmap . flip (,) . snd <*>  minRev prev) `traverse` shifts l
      minRev prev (i, l) = (+~i)  <$> foldMap (check l) prev
      check l (j, p) = if p == l then Just j else Nothing
      result = maybe (-1) (getMin . foldMap fst) lastRes
      Min a +~ Min b = Min (a + b)
  print result where readLine = BS.takeWhile isAlpha <$> BS.getLine

import Data.List
import Data.Array
import Data.Ord
import Data.Char

fnd [] _ _ = (-1)
fnd (x:xs) e i
	|isPrefixOf e x = i
	|otherwise = fnd xs e (i+1)

f x y
	|f==0 = 0
	|otherwise = (length x) - f where
		f=fnd (tails(concat (replicate 2 x))) y 0
toL (x:xs) = 0:map (f x) xs

extract (x:xs)=take (read x::Int) xs

dist x y m
	|x<y = m+x-y
	|otherwise = x-y

solve x point m=sum $ map (\y->dist y point m) x

allSolution x m= minimum $ map (\point->solve x point m) [0..m-1]

build x=[take l ((drop n cx))|n<-[0..l-1]] where
	cx=cycle x
	l=length x

res x
	|any (>l) tl = -1
	|otherwise = allSolution tl l where
		tl=toL x
		l=length (head x)

allall x=minimum [res xx|xx<-build x]

main=interact$show.allall.extract.lines

import Control.Monad
import Control.Applicative
import Data.Functor

shiftFirst :: Int -> Int -> [[Int]] -> [[Int]]
shiftFirst l sh = map $ map $ \x -> (x + sh) `mod` l

best :: Int -> [[Int]] -> Int
best l xs = foldl1 min $ do
  sh <- [0 .. pred l]
  pure $ (sh +) $ sum $ map (foldl1 min) $ shiftFirst l sh xs

possibleShifts :: [String] -> [[Int]]
possibleShifts (x:xs) = map f xs where
  l = length x
  f s = do
    sh <- [0 .. pred l]
    if drop sh s ++ take sh s == x then pure sh else []

main = do
  n <- read <$> getLine
  xs <- sequence $ replicate n getLine
  let ys = possibleShifts xs
  putStrLn $ show $
    if and $ map ((/= 0) . length) ys then
      best (length $ head xs) ys
    else
      -1

{-# OPTIONS_GHC -O3 #-}
{-# LANGUAGE ViewPatterns, ScopedTypeVariables #-}

import Control.Monad (forM)
import qualified Data.ByteString as B (getLine)
import qualified Data.ByteString.Char8 as C (readInt, words, reverse, dropWhile, unpack)
import qualified Data.Maybe as M (fromJust, isNothing)
import Data.Char (isSpace)

readInt = fst . M.fromJust . C.readInt
rstrip = C.reverse . C.dropWhile isSpace . C.reverse

adj std x@(xx:xs) i | i == length std = Nothing
                    | x == std = Just i
                    | otherwise = adj std (xs ++ [xx]) (i + 1)

run xs x | any M.isNothing g = -1
         | otherwise = sum $ map M.fromJust g where
    g = [ adj x xi 0 | xi <- xs ]

runx xs | length g == 0 = -1
        | otherwise = minimum g where
    g = filter (/= -1) [run xs x | x <- xs]

main = do
    (readInt -> n) <- B.getLine
    xs <- forM [1..n] $ \_ -> do
        (C.unpack . rstrip -> x) <- B.getLine
        return x
    putStrLn $ show $ runx xs

import Data.List
import Data.Array
import Data.Ord
import Data.Char

fnd [] _ _ = (-1)
fnd (x:xs) e i
	|isPrefixOf e x = i
	|otherwise = fnd xs e (i+1)

f x a
	| ff==0 = 0
	|otherwise = (length x)-ff
	where
		ckl=tails $ concat $ replicate ((length x)) x
		ff=fnd ckl a 0

solve (x:xs)=sum [f x a|a<-xs]

res x=minimum [solve y|y<-b] where
	l=length x
	a=concat $ replicate l x
	b=[take l(drop n a)|n<-[0..l-1]]

answer x
	|r > length (head x) = (-1)
	|otherwise = r
	where r = res x

extract (x:xs)=take (read x::Int) xs

main=interact$show.answer.extract.lines

import Data.List
import Data.Array
import Data.Ord
import Data.Char

fnd [] _ _ = (-1)
fnd (x:xs) e i
	|isPrefixOf e x = i
	|otherwise = fnd xs e (i+1)

f x y
	|f==0 = 0
	|otherwise = (length x) - f where
		f=fnd (tails(concat (replicate 2 x))) y 0
toL (x:xs) = 0:map (f x) xs

extract (x:xs)=take (read x::Int) xs

dist x y m
	|x<y = m+x-y
	|otherwise = x-y

solve x point m=sum $ map (\y->dist y point m) x

allSolution x m= minimum $ map (\point->solve x point m) [0..m-1]

res x
	|any (>l) tl = -1
	|otherwise = allSolution tl l where
		tl=toL x
		l=length (head x)
main=interact$show.res.extract.lines


One day as Petya and his friend Vasya were having one of their numerous trips, they decided to visit a museum castle. The museum has a specific shape: it consists of n rooms connected with m corridors so that one can access any room from any other one.After the two friends had a little walk around the museum, they decided to split and watch the pieces of art each of them found interesting. They agreed to meet in one of the rooms at six p.m. However, they forgot one quite essential thing: they didn't specify the place to meet and when the time came, they started to rush about the museum looking for each other (they couldn't call each other as roaming made a call's cost skyrocket).Yet, even despite the whole rush, they couldn't get enough of the pieces of art, that's why each of them has the following strategy: each minute he make a decision where to go — with probability pi he doesn't move to any other place during this minute (i.e. he stays in the room). With probability 1 - pi he equiprobably choose one of the adjacent rooms and went there along the corridor. Here i is the ordinal number of the current room. Building was expensive in ancient times, that's why each corridor connected two different rooms, and any two rooms had no more than one corridor between them. The boys act simultaneously. As the corridors are dark, it is impossible to meet there; however, one can walk along the corridors in both directions (besides, the two boys can be going through the same corridor simultaneously without meeting). The boys act like that until they meet each other. More formally, the two friends meet when at some moment of time both of them decided to appear in the same room.For each room find the probability that the boys will meet there considering that at 6 p.m. they are positioned in rooms a and b correspondingly.

The first line contains four integers: n (1 ≤ n ≤ 22), representing the numbers of rooms; m , representing the number of corridors; a, b (1 ≤ a, b ≤ n), representing the numbers of Petya's and Vasya's starting rooms correspondingly. Next m lines contain pairs of numbers — the numbers of rooms connected by a corridor. Next n lines contain probabilities pi (0.01 ≤ pi ≤ 0.99) with the accuracy of up to four digits after the decimal point — the probability to stay in room i. It is guaranteed that every room can be reached from every other room by corridors.

In the only line print n space-separated numbers, the i-th number should represent the probability that the friends meet in the i-th room with absolute or relative error of no more than 10 - 6.

NoteIn the first sample the museum is symmetric. That means the probabilities to meet in rooms 1 and 2 are equal. And their sum equals to one. So, each probability equals 0.5.

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
{-# OPTIONS_GHC -O2 #-}

import Data.List
import Data.Maybe
import Data.Char
import Data.Array.IArray
import Data.Array.Unboxed (UArray)
import Data.Int
import Data.Ratio
import Data.Bits
import Data.Function
import Data.Ord
--import Control.Monad.State
import Control.Monad
import Control.Applicative
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as BS
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Map (Map)
import qualified Data.Map as Map
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Data.Sequence (Seq, (<|), (|>), (><), ViewL(..), ViewR(..))
import qualified Data.Sequence as Seq
import qualified Data.Foldable as F
import Data.Graph

import Debug.Trace

parseInput = do
    n <- readInt
    m <- readInt
    a <- readInt
    b <- readInt
    edges <- replicateM m ((,) <$> readInt <*> readInt)
    prob <- replicateM n readDouble
    return (n, m, a, b, edges, prob)
  where
    readDouble = read . BS.unpack <$> readString :: State ByteString Double
    readInt = state $ fromJust . BS.readInt . BS.dropWhile isSpace
    readInteger = state $ fromJust . BS.readInteger . BS.dropWhile isSpace
    readString = state $ BS.span (not . isSpace) . BS.dropWhile isSpace
    readLine = state $ BS.span (not . isEoln) . BS.dropWhile isEoln
    isEoln ch = ch == '\r' || ch == '\n'

main = BS.putStr =<< solve . evalState parseInput <$> BS.getContents

swap :: (a, b) -> (b, a)
swap (a, b) = (b, a)

solve (n, m, a, b, edges, prob) = BS.unlines $ map (BS.pack . show) answer
  where
    graph = accumArray (flip (:)) [] (1, n) $ edges ++ map swap edges :: Array Int [Int]
    p = listArray (1, n) prob :: UArray Int Double
    degree = fmap length graph

    source = stateToInt (max a b, min a b)

    states = [(i, j) | i <- [1..n], j <- [1..i]]
    stateToInt (a, b) = a * (a - 1) `div` 2 + (b - 1)

    numStates = length states

    oneOne n k = [if i == k then 1 else 0 | i <- [0..n-1]]

    matrix = map move states

    answer = gauss matrix !! source

    move (a, b)
        | a == b    = oneOne numStates id ++ oneOne n (a - 1)
        | otherwise = elems row ++ replicate n 0
      where
        id = stateToInt (a, b)
        row = accumArray (+) 0 (0, numStates - 1) ((id,-1):lst) :: UArray Int Double

        lst = [ (stateToInt (max i j, min i j), pi * pj)
              | let (stayA, moveA) = (p ! a, (1 - p ! a) / fromIntegral (degree ! a))
              , let (stayB, moveB) = (p ! b, (1 - p ! b) / fromIntegral (degree ! b))
              , (i, pi) <- (a, stayA) : zip (graph ! a) (repeat moveA)
              , (j, pj) <- (b, stayB) : zip (graph ! b) (repeat moveB)
              ]

-- can't handle free variables or extra equations
gauss :: (Ord a, Fractional a) => [[a]] -> [[a]]
gauss ma = go [] ma
  where
    go xs [] = reverse xs
    go xs ys = go (row' : map handle xs) (map handle (prefix ++ suffix))
      where
        pivot = fst $ maximumBy (comparing (abs.head.snd)) $ zip [0..] ys
        (prefix, (value:row):suffix) = splitAt pivot ys
        row' = map (/value) row
        handle (r:rs) = zipWith (\x y -> x - y * r) rs row'

----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------

class (Monad m) => MonadState s m | m -> s where
	get :: m s
	put :: s -> m ()

modify :: (MonadState s m) => (s -> s) -> m ()
modify f = do
	s <- get
	put (f s)

gets :: (MonadState s m) => (s -> a) -> m a
gets f = do
	s <- get
	return (f s)

newtype State s a = State { runState :: s -> (a, s) }

instance Functor (State s) where
	fmap f m = State $ \s -> let
		(a, s') = runState m s
		in (f a, s')

instance Applicative (State s) where
    pure = return
    (<*>) = ap

instance Monad (State s) where
	return a = State $ \s -> (a, s)
	m >>= k  = State $ \s -> let
		(a, s') = runState m s
		in runState (k a) s'

instance MonadState s (State s) where
	get   = State $ \s -> (s, s)
	put s = State $ \_ -> ((), s)

evalState :: State s a -> s -> a
evalState m s = fst (runState m s)

execState :: State s a -> s -> s
execState m s = snd (runState m s)

mapState :: ((a, s) -> (b, s)) -> State s a -> State s b
mapState f m = State $ f . runState m

withState :: (s -> s) -> State s a -> State s a
withState f m = State $ runState m . f

state = State


You are given an array a1, a2, ..., an consisting of n integers, and an integer k. You have to split the array into exactly k non-empty subsegments. You'll then compute the minimum integer on each subsegment, and take the maximum integer over the k obtained minimums. What is the maximum possible integer you can get?Definitions of subsegment and array splitting are given in notes.

The first line contains two integers n and k (1 ≤ k ≤ n ≤  105) — the size of the array a and the number of subsegments you have to split the array to. The second line contains n integers a1,  a2,  ...,  an ( - 109  ≤  ai ≤  109).

Print single integer — the maximum possible integer you can get if you split the array into k non-empty subsegments and take maximum of minimums on the subsegments.

NoteA subsegment [l,  r] (l ≤ r) of array a is the sequence al,  al + 1,  ...,  ar.Splitting of array a of n elements into k subsegments [l1, r1], [l2, r2], ..., [lk, rk] (l1 = 1, rk = n, li = ri - 1 + 1 for all i > 1) is k sequences (al1, ..., ar1), ..., (alk, ..., ark).In the first example you should split the array into subsegments [1, 4] and [5, 5] that results in sequences (1, 2, 3, 4) and (5). The minimums are min(1, 2, 3, 4) = 1 and min(5) = 5. The resulting maximum is max(1, 5) = 5. It is obvious that you can't reach greater result.In the second example the only option you have is to split the array into one subsegment [1, 5], that results in one sequence ( - 4,  - 5,  - 3,  - 2,  - 1). The only minimum is min( - 4,  - 5,  - 3,  - 2,  - 1) =  - 5. The resulting maximum is  - 5.

main = interact (show . solve . map read . words)
solve (_:1:xs) = minimum xs :: Int
solve (_:2:xs) = maximum $ zipWith max (scanl1 min xs) (tail $ scanr1 min xs)
solve (_:_:xs) = maximum xs

solve2 (x:xs) =
  max x (minimum xs)

solve :: Int -> [Int] -> Int
solve k a
  | k == 1 = minimum a
  | k >= 3 = maximum a
  | otherwise = max (solve2 a) (solve2 (reverse a))

readInts :: IO [Int]
readInts = fmap (map read.words) getLine

main = do
  (n:k:_) <- readInts
  (a) <- readInts
  putStrLn (show $ solve k (take n a))

import Data.List
import Data.Int
import qualified Data.Array as A
import Data.Array((!))
import Numeric

fastRead :: String -> Int64
fastRead ('-':s) = case readDec s of [(n, "")] -> (-n)
fastRead s = case readDec s of [(n, "")] -> n

main = interact solve

solve input =
    let (n:k:numbers) = (map fastRead) $ (words input)
    in show $ doSolve n k numbers

doSolve:: Int64 -> Int64 -> [Int64] -> Int64

doSolve n 1 numbers = minimum numbers

doSolve 2 2 numbers =
    let firstN = head numbers
        lastN = last numbers
    in max firstN lastN

doSolve n 2 numbers =
    let first = head numbers
        lastN = last numbers
        middle = take (fromIntegral n-2) $ drop (fromIntegral 1) numbers
        minMiddle = minimum middle
        p1 = max first (minimum (lastN:middle))
        p2 = max lastN (minimum (first:middle))
    in max p1 p2

doSolve n m numbers = maximum numbers

listLast :: [Int] -> Int
listLast [x] = x
listLast (_:xs) = listLast xs

f :: Int -> Int -> [Int] -> Int
f _ 1 xs = foldr1 min xs
f _ 2 (x:xs) = max x (listLast xs)
f _ _ xs = foldr1 max xs

readInts :: IO [Int]
readInts = fmap (map read.words) getLine

main=do
    (n:k:_) <- readInts
    (a) <- readInts
    print (f n k a)

readInts :: IO [Int]
readInts = fmap (map read.words) getLine

listLast :: [Int] -> Int
listLast [x] = x
listLast (_:xs) = listLast xs

f :: Int -> [Int] -> Int
f 1 xs = foldl1 min xs
f 2 (x:xs) = max x (listLast xs)
f _ xs = foldl1 max xs

main = do
  (_:k:_) <- readInts
  (a) <- readInts
  print(f k a)

import Data.List
import Data.Array
import Data.Ord
import Data.Char

extract (x:y:_)=(map (\n->read n::Integer) (words y),read (last (words x))::Integer)
solve (x,k)
	|k==1 		= minimum x
	|k>2		= maximum x
	|otherwise 	= max (head x) (last x)

main=interact$show.solve.extract.lines

import Data.Char

-- Read a token from standard input
getToken :: IO String
getToken = do t <- go
              if t == "" then getToken else return t
                where go = do c <- getChar
                              if isSpace c then return "" else
                                 go >>= (\s -> return (c:s))

-- Read an integer from standard input
getInteger :: IO Integer
getInteger = getToken >>= (\t -> return (read t :: Integer))

-- Repeat a monadic function n times
repeatM_ :: Monad m => Integer -> m a -> m ()
repeatM_ 0 f = return ()
repeatM_ n f = f >> repeatM_ (n - 1) f

readListMax :: Integer -> IO Integer
readListMax len
  | len > 1 = do
      x <- getInteger
      y <- readListMax $ len - 1
      return $ max x y
  | otherwise = getInteger

readListMin :: Integer -> IO Integer
readListMin len
  | len > 1 = do
      x <- getInteger
      y <- readListMin $ len - 1
      return $ min x y
  | otherwise = getInteger

readListFirstLastMax :: Integer -> IO Integer
readListFirstLastMax len = do
  first <- getInteger
  last <- readListLast $ len - 1
  return $ max first last
    where readListLast :: Integer -> IO Integer
          readListLast len
            | len > 1 = getInteger >> (readListLast $ len - 1)
            | otherwise = getInteger

main = do
  len <- getInteger
  k <- getInteger
  if k == 1 then readListMin len >>= \x -> print x else
    if k == 2 then readListFirstLastMax len >>= \x -> print x else
      readListMax len >>= \x -> print x

import Data.List
import Data.Int
import qualified Data.Array as A
import Data.Array((!))
import Numeric

fastRead :: String -> Int64
fastRead ('-':s) = case readDec s of [(n, "")] -> (-n)
fastRead s = case readDec s of [(n, "")] -> n

main = interact solve

solve input =
    let (n:k:numbers) = (map fastRead) $ (words input)
    in show $ doSolve n k numbers

doSolve:: Int64 -> Int64 -> [Int64] -> Int64

doSolve n 1 numbers = minimum numbers

doSolve 2 2 numbers =
    let firstN = head numbers
        lastN = last numbers
    in max firstN lastN

doSolve n 2 numbers =
    let first = head numbers
        lastN = last numbers
        middle = take (fromIntegral n-2) $ drop (fromIntegral 1) numbers
        minMiddle = minimum middle
    in maximum [first,lastN,minMiddle]

doSolve n m numbers = maximum numbers


You are given three strings $$$s$$$, $$$t$$$ and $$$p$$$ consisting of lowercase Latin letters. You may perform any number (possibly, zero) operations on these strings.During each operation you choose any character from $$$p$$$, erase it from $$$p$$$ and insert it into string $$$s$$$ (you may insert this character anywhere you want: in the beginning of $$$s$$$, in the end or between any two consecutive characters). For example, if $$$p$$$ is aba, and $$$s$$$ is de, then the following outcomes are possible (the character we erase from $$$p$$$ and insert into $$$s$$$ is highlighted):  aba $$$\rightarrow$$$ ba, de $$$\rightarrow$$$ ade;  aba $$$\rightarrow$$$ ba, de $$$\rightarrow$$$ dae;  aba $$$\rightarrow$$$ ba, de $$$\rightarrow$$$ dea;  aba $$$\rightarrow$$$ aa, de $$$\rightarrow$$$ bde;  aba $$$\rightarrow$$$ aa, de $$$\rightarrow$$$ dbe;  aba $$$\rightarrow$$$ aa, de $$$\rightarrow$$$ deb;  aba $$$\rightarrow$$$ ab, de $$$\rightarrow$$$ ade;  aba $$$\rightarrow$$$ ab, de $$$\rightarrow$$$ dae;  aba $$$\rightarrow$$$ ab, de $$$\rightarrow$$$ dea; Your goal is to perform several (maybe zero) operations so that $$$s$$$ becomes equal to $$$t$$$. Please determine whether it is possible.Note that you have to answer $$$q$$$ independent queries.

The first line contains one integer $$$q$$$ ($$$1 \le q \le 100$$$) — the number of queries. Each query is represented by three consecutive lines. The first line of each query contains the string $$$s$$$ ($$$1 \le |s| \le 100$$$) consisting of lowercase Latin letters. The second line of each query contains the string $$$t$$$ ($$$1 \le |t| \le 100$$$) consisting of lowercase Latin letters. The third line of each query contains the string $$$p$$$ ($$$1 \le |p| \le 100$$$) consisting of lowercase Latin letters.

For each query print YES if it is possible to make $$$s$$$ equal to $$$t$$$, and NO otherwise. You may print every letter in any case you want (so, for example, the strings yEs, yes, Yes and YES will all be recognized as positive answer).

4
ab
acxb
cax
a
aaaa
aaabbcc
a
aaaa
aabbcc
ab
baaa
aaaaa

NoteIn the first test case there is the following sequence of operation:   $$$s = $$$ ab, $$$t = $$$ acxb, $$$p = $$$ cax;  $$$s = $$$ acb, $$$t = $$$ acxb, $$$p = $$$ ax;  $$$s = $$$ acxb, $$$t = $$$ acxb, $$$p = $$$ a. In the second test case there is the following sequence of operation:   $$$s = $$$ a, $$$t = $$$ aaaa, $$$p = $$$ aaabbcc;  $$$s = $$$ aa, $$$t = $$$ aaaa, $$$p = $$$ aabbcc;  $$$s = $$$ aaa, $$$t = $$$ aaaa, $$$p = $$$ abbcc;  $$$s = $$$ aaaa, $$$t = $$$ aaaa, $$$p = $$$ bbcc.

import Data.Char (ord)
import Data.Bool (bool)
import Data.Map (fromListWith, toList, (!?))
import Control.Monad (replicateM_)

parseInt :: String -> Int
parseInt = foldl (\acc c -> acc * 10 + ord c - 48) 0

predicate :: Bool -> Maybe ()
predicate False = Nothing
predicate True = Just ()

contains a b c = foldl (>>) (Just ()) . fmap enough . toList $ q
  where
    enough (k, v) = p !? k >>= predicate . (>= v)
    p = fromListWith (+) [(k, 1) | k <- a ++ b]
    q = fromListWith (+) [(k, 1) | k <- c]

subseq a b = predicate (mem !! m)
  where
    n = length a
    m = length b
    initial = replicate (m + 1) True
    next mem c = scanl (||) False . zipWith (&&) mem . fmap (== c) $ b
    mem = foldl next initial a

solve :: IO ()
solve = do
  s <- getLine
  t <- getLine
  p <- getLine
  putStrLn (maybe "NO" (const "YES") (contains s p t >> subseq s t))

main :: IO ()
main = do
  testNum <- fmap parseInt getLine
  replicateM_ testNum solve

import Control.Monad (replicateM_)
import Data.Bool (bool)
import Data.Char (ord)
import Data.Map ((!?), fromListWith, toList)

parseInt :: String -> Int
parseInt = foldl (\acc c -> acc * 10 + ord c - 48) 0

predicate :: Bool -> Maybe ()
predicate False = Nothing
predicate True = Just ()

contains a b c = mapM_ enough . toList $ q
  where
    enough (k, v) = p !? k >>= predicate . (>= v)
    p = fromListWith (+) [(k, 1) | k <- a ++ b]
    q = fromListWith (+) [(k, 1) | k <- c]

subseq a b = foldl (\mb c -> mb >>= next c) (Just b) a
  where
    next c b =
      case dropWhile (/= c) b of
        [] -> Nothing
        _:bs -> Just bs

solve :: IO ()
solve = do
  s <- getLine
  t <- getLine
  p <- getLine
  putStrLn (maybe "NO" (const "YES") (contains s p t >> subseq s t))

main :: IO ()
main = do
  testNum <- fmap parseInt getLine
  replicateM_ testNum solve