import Data.Foldable
import System.Environment

floorSqrt :: Integer -> Integer
floorSqrt n = floor $ sqrt $ fromIntegral n 

isPerfectSquare :: Integer -> Bool
isPerfectSquare n = 
    let floorSqrtN = floorSqrt n
    in floorSqrtN * floorSqrtN == n

data DigitState = DigitState Integer Integer Integer Integer deriving Show

instance Monoid DigitState where
    mempty = DigitState 0 0 0 0
    DigitState _ _ xa _ `mappend` DigitState _ _ xb _ = DigitState 0 0 (xa + xb) 0

getNewX :: Integer -> Integer -> Integer
getNewX c p = (fromIntegral $ length $ takeWhile (<= c) $ map (\x -> x * (20 * p + x)) [0..9]) - 1

getNewY :: Integer -> Integer -> Integer
getNewY p x = x * (20 * p + x)

getInitialState :: Integer -> DigitState
getInitialState c =
    let newX = getNewX c 0
        newY = newX * newX 
    in DigitState c 0 newX newY

nextState :: DigitState -> DigitState
nextState (DigitState c p x y) = 
    let newC = 100 * (c - y)
        newP = 10 * p + x
        newX = getNewX newC newP
        newY = getNewY newP newX
    in DigitState newC newP newX newY

sqrtDigitSum :: Int -> Integer -> Integer
sqrtDigitSum d n = 
    let initialState = getInitialState n
        stateList = initialState : map nextState stateList
        DigitState _ _ sum _ = fold $ take d stateList 
    in sum

sumSqrtDigitSums :: Integer -> Int -> Integer
sumSqrtDigitSums bound count = sum $ map (sqrtDigitSum count) $ filter (not . isPerfectSquare) [2..bound]

main = do 
    args <- getArgs
    print $ sumSqrtDigitSums 100 100 -- (read $ head args) (read $ last args)