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

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

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

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


{-# 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 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 :: 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


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

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

{-# 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


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

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)

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


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

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


{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE OverloadedStrings #-}
import           Control.Applicative
import           Control.Monad
import           Data.List
import           Data.Tuple
import           Data.Int
import           Data.Char
import           Data.Function
-- import           Data.Array
-- import           Data.ByteString (ByteString)
-- import qualified Data.ByteString.Char8 as C
-- import           Data.ByteString.Char8 ()
-- import           Data.Vector.Unboxed ((//), (++), (!), (!?))
-- import qualified Data.Vector.Unboxed as U
-- import           Data.IntMap.Strict (IntMap)
-- import qualified Data.IntMap.Strict as IntMap
-- import           Data.Sequence ((|>), (<|), (><),ViewR((:>)), ViewL((:<)))
-- import qualified Data.Sequence as S

myread = read :: String -> Int
main = do
  n <- readLn
  nss <- replicateM n getLine
  print $ solve nss (transpose nss)

solve :: [String] -> [String] -> Int
solve nss mss = (sum (map count nss)) + (sum (map count mss)) where
  count :: String -> Int
  count = comb2 . length . filter (=='C')

comb2 :: Int -> Int
comb2 1 = 0
comb2 0 = 0
comb2 n = n*(n-1)`div`2

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

main = loop

loop = do done <- isEOF
          if done
              then do putStrLn ""
              else do size <- getLine
                      input <- replicateM (read size) getLine
                      print (calculate input)
                      loop

calculate :: [String] -> Int
calculate [] = 0
calculate (x:xs) = (sum(foldr g [] (x:xs))) + (sum (foldr g [] (transpose (x:xs))))
    where
        g :: [Char] -> [Int] -> [Int]
        g (x:xs) y = (combinations (sum (map f (x:xs)))):y
        f :: Char -> Int
        f 'C' = 1
        f '.' = 0

combinations :: Int -> Int
combinations x = quot (x * (x - 1)) 2

{-# LANGUAGE TupleSections, MultiParamTypeClasses, ExistentialQuantification,
             RankNTypes, FlexibleContexts, DeriveFunctor #-}

import Control.Monad
import Control.Applicative
--import Control.Lens
--import Control.Zipper
import Control.Arrow
import qualified Data.Map as M
--import qualified Data.Vector as V
import qualified Data.Set as S
import Data.List
--import Debug.Trace
--import Control.Comonad
import Data.Monoid
--import Data.Functor.Foldable
--import Test.QuickCheck
import Data.Tree
--import Data.Machine
--import Data.Traversable
--import Data.Distributive
--import Linear
import Control.Monad.Cont

main = do
  n <- fmap read getLine
  inp <- forM [1..n] $ \_ -> getLine
  print (solve inp)

solve :: [String] -> Int
solve inp = sum (map g rows) + sum (map g cols)
    where
      rows = map (foldl f 0) inp
      cols = map (foldl f 0) (transpose inp)
      f s 'C' = s + 1
      f s _ = s
      g x = x*(x-1)`div`2

import Data.Maybe
import qualified Data.ByteString as B
import qualified Data.ByteString.Char8 as C
import Control.Monad
import Control.Applicative
import Data.List
readInt :: C.ByteString -> Int

readInt = fst . fromJust . C.readInt

getInts = map readInt . C.words <$> C.getLine

countLetters :: String -> Char -> Int
countLetters str c = length $ filter (== c) str

main :: IO ()
main = do
    (n:_) <- getInts
    input <- replicateM n getLine
    let counts = getCounts input
    let input2 = transpose input
    let counts2 = getCounts input2
    let counts3 = counts2 ++ counts
    let result = foldl getResult 0 counts3
    print result
    where
        getCounts = map (flip countLetters 'C')
        getResult acc count = acc + count * (count - 1) `div` 2

import Control.Applicative
import Data.List

cou x = div (a*(a-1)) 2
	where a = length $ filter (=='C') x

process s = sum $ map cou s
main= do
	getLine
	s<- lines <$> getContents::IO [String]
	let t = transpose s
	print $ sum $ map process [s,t]

import Data.List (transpose)

combination :: Int -> Int -> Integer
combination n r
    | r == 0 = 1
    | n >= r && r > 0 = (product [(n'-r'+1)..n']) `div` (product [1..r'])
    | otherwise = 0
    where
        n' = fromIntegral n
        r' = fromIntegral r

process :: [[Char]] -> Integer
process ss = sum (map f ss) + sum (map f (transpose ss))
    where
        n = length ss
        f x = combination (length $ filter ('C'==) x) 2

readInt :: String -> Int
readInt = read

main :: IO ()
main = do
    n <- fmap readInt getLine
    ss <- fmap lines getContents
    print $ process ss

{-# LANGUAGE FlexibleInstances #-}
module Main (printShit, printShitV, readShit, main, yN, iif) where
import Data.ByteString.Builder
import qualified Data.ByteString.Lazy.Char8 as BS
import Data.Maybe
import Data.List

-- Meat
solve :: [String] -> Integer
solve ss = subsolve ss + (subsolve . transpose) ss

subsolve :: [String] -> Integer
subsolve = sum . fmap ((\x -> toInteger $ x * (x-1) `div` 2). length . filter (=='C'))

-- Shit
main :: IO ()
main = do
        (_:ss)  <- readShit
        printShit $ solve ss

class Shit a where
    printShit :: a -> IO ()
    printShitV :: a -> IO ()
    readShit :: IO a
    printShitV = printShit

yN :: Bool -> String
yN True = "YES"
yN False = "NO"

iif :: x -> x -> Bool-> x
iif a b c = if c then a else b

instance  Shit Int where
    printShit = print
    readShit = fmap read getLine

instance  Shit Integer where
    printShit = print
    readShit = fmap read getLine

instance  Shit [Int] where
    printShit = putStrLn . unwords . fmap show
    printShitV = putStrLn . unlines . fmap show
    readShit = fmap (fmap read . words) getLine

instance  Shit [Integer] where
    printShit = putStrLn . unwords . fmap show
    printShitV = putStrLn . unlines . fmap show
    readShit = fmap (fmap read . words) getLine

instance Shit [[Int]] where
    printShit = printShit . (fmap.fmap)  (toLazyByteString . integerDec .toInteger)
    readShit = fmap (fmap.fmap $ fromInteger.fst.fromJust. BS.readInteger) readShit

instance Shit [[Double]] where
    printShit = printShit . (fmap.fmap) show
    readShit = fmap (fmap.fmap $ read) readShit

instance Shit [[Integer]] where
    printShit  = printShit . (fmap.fmap)  (toLazyByteString . integerDec)
    readShit = fmap (fmap.fmap $ fromInteger.fst.fromJust. BS.readInteger) readShit

instance Shit String where
    printShit = putStrLn
    printShitV = putStrLn
    readShit = getLine

instance Shit [String] where
    printShit = putStrLn. unwords
    printShitV = putStrLn . unlines
    readShit = fmap lines getContents

instance Shit [[String]] where
    printShit = putStrLn . unlines . fmap unwords
    readShit = fmap (fmap (fmap words) lines) getContents

instance Shit [BS.ByteString] where
    printShit = BS.putStrLn. BS.unwords
    printShitV = BS.putStrLn . BS.unlines
    readShit = fmap BS.lines BS.getContents

instance Shit [[BS.ByteString]] where
    printShit = BS.putStrLn . BS.unlines . fmap BS.unwords
    readShit = fmap (fmap (fmap BS.words) BS.lines) BS.getContents

{-
instructions go here...
-}

module Main where
import Data.List(transpose)

solve :: [String] -> Int
solve cake = countPairs cake + countPairs (transpose cake)

countPairs lines = sum $ map countPairs' lines
  where countPairs' line = sum $ map snd $ zip (filter (== 'C') line) [0..]

getLines :: Int -> IO [String]
getLines n = sequence $ replicate n getLine

main :: IO ()
main = do
  line <- getLine
  let n = read line :: Int
  cake <- getLines n
  let pairs = solve cake
  putStrLn $ show pairs

import Control.Monad

sol :: [[Int]] -> Int
sol a = sum(map (\x -> (x * (x-1)) `div` 2) (map sum a))

transpose:: [[a]]->[[a]]
transpose ([]:_) = []
transpose x = (map head x) : transpose (map tail x)

main :: IO ()
main = do
  n_s <- getLine
  let n = read n_s :: Int
  inputs <- replicateM n getLine :: IO [[Char]]
  let inputs_b = map (\x -> (map (\y -> if y == 'C' then 1 else 0) x)) inputs
  let inputs_t = transpose inputs_b
  print ((sol inputs_b) + (sol inputs_t))

import Control.Monad
import Control.Arrow
import Data.List
import Control.Applicative
import Data.Maybe

import qualified Data.ByteString.Char8 as C

tr x =
    if (x == 'C') then 1 else 0

main :: IO ()
main = do
    a <- (fst.fromJust.C.readInt) <$> C.getLine
    b <- sequence $ replicate a $ (map tr) <$> getLine
    print $ sum (((\x->x*(x-1)`div`2).sum) <$> b) + sum (((\x->x*(x-1)`div`2).sum) <$> transpose b)


{-# LANGUAGE ScopedTypeVariables #-}

import Control.Monad
import Data.List

main :: IO ()
main = do
  cases::Int <- read <$> getLine
  forM_ [1..cases] (\cn -> do
      n::Int <- read <$> getLine
      gang::[Int] <- (map read) <$> words <$> getLine
      let gangs2 = zip [1..] gang
      let gangs = groupBy (\(_, a) (_, b) -> a == b) $ sortBy (\(_, a) (_, b) -> compare a b) gangs2
      if (length $ gangs) == 1 then
        putStrLn "NO"
      else do
        let ganged = map (\x -> (head x, length x, x)) $ gangs
        let sorted = sortBy (\(_, a, _) (_, b, _) -> compare a b) ganged
        -- putStrLn "--------------"
        -- print gang
        -- print gangs
        -- print sorted
        -- putStrLn "--------------"
        let (a, b, p) = head sorted
        let start_point = head p
        let rest_ganged = tail sorted ++ [(a, b - 1, tail p)]
        putStrLn "YES"
        go start_point rest_ganged
        pure ()
      pure ()
    )
  pure ()
       where go _ [] = pure ()
             go s k@((_, _, ls):xs) = do
               forM_ ls $ (\a -> putStrLn $ (show $ fst $ s) ++ " " ++ (show $ fst $ a))
               go (head ls) xs

import Control.Monad
import Data.Maybe
import Data.List
import Text.Printf
import qualified Data.ByteString.Char8 as C

getInts :: IO [Int]
getInts = map (fst . fromJust . C.readInt) . C.words <$> C.getLine

main :: IO ()
main = do
  [t] <- getInts
  replicateM_ t $ do
    _ <- getInts
    as <- getInts
    let (xs, ys) = partition (\(a, _) -> a == head as) $ zip as [(1 :: Int) .. ]
        put i ps = mapM_ (\(_, j) -> printf "%d %d\n" i j :: IO ()) ps
    if null ys then printf "NO\n"
               else do
                 let (_, i) = head xs
                     (_, j) = head ys
                 printf "YES\n"
                 printf "%d %d\n" i j
                 put i (tail ys)
                 put j (tail xs)

import Control.Monad

readInts :: IO [Int]
readInts = map read . words <$> getLine

main :: IO ()
main = do
  t <- read <$> getLine
  replicateM_ t $ do
    _n <- getLine
    a <- readInts
    let  x = maximum a
    case  all (== x) a  of
      True -> putStrLn "NO"
      False -> do
        putStrLn "YES"
        let
          ps@(p:_) = [i | (i, y) <- zip [1..] a, y == x] :: [Int]
          (q : qs) = [i | (i, y) <- zip [1..] a, y /= x] :: [Int]
        forM_ ps $ \cp -> putStrLn . unwords $ map show [q, cp]
        forM_ qs $ \cq -> putStrLn . unwords $ map show [p, cq]

import Control.Monad
import qualified Data.Map as Map
import Data.List (sort, group)

readInt :: IO Int
readInt =  read <$> getLine

readInts :: IO [Int]
readInts = map read . words <$> getLine

main :: IO ()
main = do
    t <- readInt
    replicateM_ t $ do
        n <- readInt
        a <- readInts
        putStr $ formatOutput $ solve a

getPos :: [Int] -> (Map.Map Int Int)
getPos a = mp
          where n = length a
                mp = Map.fromList [(x, i) | i <- [0..(n - 1)], let x = a !! i]

getNext :: [Int] -> (Map.Map Int Int)
getNext a = mp
          where a' = map head $ group $ sort a
                n = length a'
                mp = Map.fromList [(a' !! i, a' !! j) | i <- [0..(n - 1)], let j = if i == n - 1 then 0 else (i + 1)]

solve :: [Int] -> (Bool, [(Int, Int)])
solve a = if length next <= 1 then (False, []) else (True, [(i, y) | i <- [0..(n-2)], let x = a !! i, let y = pos Map.! (next Map.! x)])
      where
            n = length a
            next = getNext a
            pos  = getPos a

formatOutput :: (Bool, [(Int, Int)]) -> String
formatOutput (False, _) = "NO\n"
formatOutput (True, a) = unlines $ "YES":[show (x + 1) ++ " " ++ show (y + 1) | (x, y) <- a]

import Control.Monad (forM_)
import Data.List (group, sortBy)

solve :: String -> ([Int], [Int], Bool)
solve s = (fl, nfl, length nfl /= 0)
  where s' = zip [1..] ws
	fl = map fst . filter (\x -> snd x == h) $ s'
	nfl = map fst . filter (\x -> snd x /= h) $ s'
	h = head ws
	ws = words s

combine :: [Int] -> [Int] -> [(Int, Int)]
combine fl nfl = tp ++ tp'
  where h = head fl
	t = tail fl
	l = last nfl
	tp = [(h, x) | x <- nfl]
	tp' = [(x, l) | x <- t]

ts :: (Int, Int) -> String
ts (x, y) = show x ++ " " ++ show y

main :: IO ()
main = do
  t <- pure . read =<< getLine
  forM_ [1..t] . const $ getLine >> getLine >>=  \x -> do
	(fl, nfl, b) <- pure . solve $ x
	if b then do
	  putStrLn "Yes"
	  mapM_ (putStrLn . ts) . combine fl $ nfl
	else putStrLn "No"

{-# LANGUAGE Safe #-}

import safe Control.Arrow ((>>>))
import safe Data.Bool (bool)
import safe Data.List (intercalate)

main :: IO ()
main = interact $ lines >>> drop 1 >>> map (words >>> map read) >>> process >>> unlines

process :: [[Int]] -> [String]
process [] = []
process (_ : xs : xss) = solve xs : process xss

solve :: [Int] -> String
solve xs
  | all (== a) xs = "NO"
  | otherwise = intercalate "\n" ("YES" : map (unwords . map show) edges)
  where
    a = head xs
    ys = zip xs [1 ..]
    i = snd . head $ filter ((/= a) . fst) ys
    edges = map (\(b, j) -> [bool 1 i (a == b), j]) (tail ys)

{-# LANGUAGE ScopedTypeVariables #-}

import Control.Monad
import Data.List

main :: IO ()
main = do
  cases::Int <- read <$> getLine
  forM_ [1..cases] (\cn -> do
      n::Int <- read <$> getLine
      gang::[Int] <- (map read) <$> words <$> getLine
      let gangs2 = zip [1..] gang
      let gangs = groupBy (\(_, a) (_, b) -> a == b) $ sortBy (\(_, a) (_, b) -> compare a b) gangs2
      if (length $ gangs) == 1 then
        putStrLn "NO"
      else do
        let ganged = map (\x -> (head x, length x, x)) $ gangs
        let sorted = sortBy (\(_, a, _) (_, b, _) -> compare a b) ganged
        -- putStrLn "--------------"
        -- print gang
        -- print gangs
        -- print sorted
        -- putStrLn "--------------"
        let (a, b, p) = head sorted
        let start_point = head p
        let rest_ganged = tail sorted ++ [(a, b - 1, tail p)]
        putStrLn "YES"
        go start_point rest_ganged
        pure ()
      pure ()
    )
  pure ()
       where go _ [] = pure ()
             go s k@((_, _, ls):xs) = do
               forM_ ls $ (\a -> putStrLn $ (show $ fst $ s) ++ " " ++ (show $ fst $ a))
               go s xs

{-# LANGUAGE ScopedTypeVariables #-}

import Control.Monad
import Data.List

main :: IO ()
main = do
  cases::Int <- read <$> getLine
  forM_ [1..cases] (\cn -> do
      n::Int <- read <$> getLine
      gang::[Int] <- (map read) <$> words <$> getLine
      let gangs = zip [1..] gang
      if (length $ groupBy (\(_, a) (_, b) -> a == b) $ sortBy (\(_, a) (_, b) -> compare a b) gangs) == 1 then
        putStrLn "NO"
      else do
        let ganged = map (\x -> (head x, length x, x)) $ group $ sort gangs
        let sorted = sortBy (\(_, a, _) (_, b, _) -> compare a b) ganged
        let (a, b, p) = head sorted
        let start_point = head p
        let rest_ganged = tail ganged ++ [(a, b, tail p)]
        putStrLn "YES"
        go start_point rest_ganged
        pure ()
      pure ()
    )
  pure ()
       where go _ [] = pure ()
             go s ((_, _, ls):xs) = do
               forM_ ls $ (\a -> putStrLn $ (show $ fst $ s) ++ " " ++ (show $ fst $ a))
               go s xs