# yukicoder 661, 662, 663, 664, 665

### 661 ハローキティはりんご3個分

import Control.Monad

main = getLine >> getContents >>= mapM_ (putStrLn . solve . read) .  lines

solve n
| n mod 40 == 0 = "ikisugi"
| n mod 8 == 0 = "iki"
| n mod 10 == 0 = "sugi"
| otherwise = show (n div 3)


### 662 スロットマシーン

import Data.List
import Data.Maybe

main = do
(n1, a) <- readReel (map fst dic)
(n2, b) <- readReel (map fst dic)
(n3, c) <- readReel (map fst dic)

-- [0] [1] [2] [3] [4]
-- 000         0     0
--     000      0   0
--         000   0 0

let cnt = map (\k -> let x = a!!k; y = b!!k; z = c!!k in 5*x*y*z) $[0..4] let ans = sum$ zipWith (*) cnt (map snd dic)

print $fromIntegral ans / fromIntegral (n1 * n2 * n3) mapM_ print cnt readKV :: IO (String, Int) readKV = do [k, v] <- words <$> getLine

readReel :: [String] -> IO (Int, [Int])
n <- readLn :: IO Int
x <- replicateM n (fromJust . flip elemIndex dic <$> getLine) return (n, [length . filter (==i)$ x | i <- [0..4]])


### 663 セルオートマトンの逆操作

リストモナドの bind を連鎖させれば全列挙できるけど、それだと指数時間になってしまう。bind 後に重複除去をすると計算量が落ちる（いまさらなんだけど、groupBy する前にソートしないと危険）。dp[i] から dp[i+1] が作れる系の DP はたいていこう書けると思う。

import Data.List

main = do
n <- readLn :: IO Int
a <- replicateM n readLn :: IO [Int]
print $solve a md :: Int md = 10^9 + 7 type Stat = (Int, Int, Int, Int) solve :: [Int] -> Int solve a = let b = foldl' g [((i, j, i, j), 1) | i <- [0,1], j <- [0,1]] a in modsum . map snd . filter (\((h1, h2, x, y), _) -> h1 == x && h2 == y)$ b
where
g :: [(Stat, Int)] -> Int -> [(Stat, Int)]
g acc a = compress (acc >>= f a)

f :: Int -> (Stat, Int) -> [(Stat, Int)]
f a ((h1, h2, x, y), cnt) = [((h1, h2, y, z), cnt) | z <- [0, 1], rule x y z == a]

compress :: [(Stat, Int)] -> [(Stat, Int)]
compress a = map f . groupBy (\x y -> fst x == fst y) $a where f :: [(Stat, Int)] -> (Stat, Int) f x = let key = fst (head x); val = modsum . map snd$ x
in (key, val)

modsum :: [Int] -> Int
modsum = foldl' (\x y -> (x + y) mod md) 0

rule :: Int -> Int -> Int -> Int
rule 0 0 0 = 0
rule 0 0 1 = 1
rule 0 1 0 = 1
rule 0 1 1 = 1
rule 1 0 0 = 0
rule 1 0 1 = 1
rule 1 1 0 = 1
rule 1 1 1 = 0


### 665 Bernoulli Bernoulli

import Data.List (foldl', scanl)

md :: Int
md = 10^9 + 7

-- sometimes ambigious
infixl 6 +++
(+++) :: Int -> Int -> Int
(+++) a b = (a + b) mod md

infixl 7 ***
(***) :: Int -> Int -> Int
(***) a b = a * b mod md

infixr 8 ^^^
(^^^) :: Int -> Int -> Int
(^^^) a b
| b == 0 = 1
| odd b = a *** a ^^^ (b - 1)
| otherwise = (a *** a) ^^^ (b div 2)

modinv :: Int -> Int
modinv a = a ^^^ (md - 2)

infixl 7 ///
(///) :: Int -> Int -> Int
(///) a b = a *** modinv b

prodmod :: [Int] -> Int
prodmod = foldl' (***) 1

--         p/(x-0)                                 p/(x-1)
--  vvvvvvvvvvvvvvvvvvvv                    vvvvvvvvvvvvvvvvvvvv
--  (x-1)(x-2)...(x-n+1)            (x-0)   (x-2)(x-3)...(x-n+1)
-- --------------------- a[0] + ... ---------------------------- a[1] + ...
--  (0-1)(0-2)...(0-n+1)            (1-0)   (1-2)(1-3)...(1-n+1)
--                                  ^^^^^   ^^^^^^^^^^^^^^^^^^^^
--                                   [L]            [R]

lagrange :: [Int] -> Int -> Int
lagrange a x
| x < n = a !! x
| otherwise = let (sm, _, _, _) = foldl' f (0, 0, 1, q) a
in sm
where
n = length a
p = prodmod [(x - i) | i <- [0..n-1]]
q = prodmod [-i | i <- [1..n-1]]
f :: (Int, Int, Int, Int) -> Int -> (Int, Int, Int, Int)
f (sm, k, l, r) ak = (nextSm, k + 1, nextL, nextR)
where
nextSm = sm +++ ak *** p /// (l *** r *** (x-k))
nextL = l *** (k + 1)
nextR = r /// negate (n - 1 - k)

computeSmall :: Int -> [Int]
computeSmall k = scanl f 0 [1..k + 1]
where
f s x = s +++ (x ^^^ k)

solve :: Int -> Int -> Int
solve n k = lagrange (computeSmall k) (n mod md)

main = do
[n, k] <- map read . words <$> getLine :: IO [Int] print$ solve n k