rearrange :: (Ord a,Ord b,Integral c,Num c) => RearrangeM a b c s
rearrange = do
  readdata <- ask
  state <- get
  unless (current state == VM.length (indexA readdata)) $ do
    currentIndexA <- VM.read (indexA readdata) (fromIntegral $ current state)
    let currentIndexB = indexB readdata V.! fromIntegral (current state)
        currentA = readVetorA readdata V.! fromIntegral currentIndexA
        currentB = readVetorB readdata V.! fromIntegral currentIndexB
    currentMaybeB <- VM.read (resulVector readdata) (fromIntegral currentIndexA)
    if M.isNothing currentMaybeB then
      VM.write (resulVector readdata) (fromIntegral currentIndexA) (Just currentB)
    else
      unless (currentB == M.fromJust currentMaybeB) $ do
        let search = Map.lookup (currentA,currentB) $ locator state
        case search of
          Just x -> VM.write (indexA readdata) (fromIntegral $ current state) x
          Nothing -> do
            let newIndex = fromIntegral $ V.length (readVetorA readdata) + Seq.length (extraA state)
            VM.write (indexA readdata) (fromIntegral $ current state) newIndex
            modify' (\s-> s{
                  extraA=extraA s Seq.|> currentA,
                  extraB=extraB s Seq.|> currentB,
                  locator=Map.insert (currentA,currentB) newIndex (locator s)
                }
              )
    modify' (\s->s{current=current state + 1})
    rearrange
rearrange :: (Ord a,Ord b,Integral c,Num c) => RearrangeM a b c s
rearrange = do
  readdata <- ask
  state <- get
  unless (current state == VM.length (indexA readdata)) $ do
    currentIndexA <- VM.read (indexA readdata) (fromIntegral $ current state)
    let currentIndexB = indexB readdata V.! fromIntegral (current state)
        currentA = readVetorA readdata V.! fromIntegral currentIndexA
        currentB = readVetorB readdata V.! fromIntegral currentIndexB
    currentMaybeB <- VM.read (resulVector readdata) (fromIntegral currentIndexA)
    if M.isNothing currentMaybeB then
      VM.write (resulVector readdata) (fromIntegral currentIndexA) (Just currentB)
    else
      unless (currentB == M.fromJust currentMaybeB) $ do
        let search = Map.lookup (currentA,currentB) $ locator state
        case search of
          Just x -> VM.write (indexA readdata) (fromIntegral $ current state) x
          Nothing -> do
            let newIndex = fromIntegral $ V.length (readVetorA readdata) + Seq.length (extraA state)
            VM.write (indexA readdata) (fromIntegral $ current state) newIndex
            modify' (\s-> s{
                  extraA=extraA s Seq.|> currentA,
                  extraB=extraB s Seq.|> currentB,
                  locator=Map.insert (currentA,currentB) newIndex (locator s)
                }
              )
    modify' (\s->s{current=current state + 1})
    rearrange
rearrange = do
  readdata <- ask
  state <- get
  unless (current state == VM.length (indexA readdata)) $ do
    currentIndexA <- VM.read (indexA readdata) (fromIntegral $ current state)
    let currentIndexB = indexB readdata V.! fromIntegral (current state)
        currentA = readVetorA readdata V.! fromIntegral currentIndexA
        currentB = readVetorB readdata V.! fromIntegral currentIndexB
    currentMaybeB <- VM.read (resulVector readdata) (fromIntegral currentIndexA)
    if M.isNothing currentMaybeB then
      VM.write (resulVector readdata) (fromIntegral currentIndexA) (Just currentB)
    else
      unless (currentB == M.fromJust currentMaybeB) $ do
        let search = Map.lookup (currentA,currentB) $ locator state
        case search of
          Just x -> VM.write (indexA readdata) (fromIntegral $ current state) x
          Nothing -> do
            let newIndex = fromIntegral $ V.length (readVetorA readdata) + Seq.length (extraA state)
            VM.write (indexA readdata) (fromIntegral $ current state) newIndex
            modify' (\s-> s{
                  extraA=extraA s Seq.|> currentA,
                  extraB=extraB s Seq.|> currentB,
                  locator=Map.insert (currentA,currentB) newIndex (locator s)
                }
              )
    modify' (\s->s{current=current state + 1})
    rearrange