diff --git a/align.cabal b/align.cabal
--- a/align.cabal
+++ b/align.cabal
@@ -1,5 +1,5 @@
 name:                align
-version:             0.1.1.1
+version:             0.1.1.2
 synopsis:            Sequence alignment algorithms.
 description:         Global or local sequence alignment, not exclusively for text.
 license:             BSD3
@@ -17,7 +17,8 @@
   exposed-modules:     Data.Align,
                        Data.Align.Demo
   build-depends:       base >=4.6 && <5,
-                       uglymemo >= 0.1,
+                       containers,
+                       transformers,
                        vector >=0.10
   hs-source-dirs:      src
   default-language:    Haskell98
diff --git a/src/Data/Align.hs b/src/Data/Align.hs
--- a/src/Data/Align.hs
+++ b/src/Data/Align.hs
@@ -19,10 +19,11 @@
   , debugMultiAlign
   ) where
 
+import Control.Monad.Trans.State.Strict
 import Data.Function (fix, on)
 import qualified Data.List as L
+import qualified Data.Map.Strict as M
 import Data.Maybe (fromMaybe)
-import Data.MemoUgly
 import Data.Ord
 import qualified Data.Vector as V
 import qualified Data.Vector.Generic as G
@@ -77,7 +78,8 @@
 instance (Show a, Show s) => Show (Trace a s) where
   show (Trace s t) = "Trace(score = " ++ show s ++ ", steps = " ++ show t ++ ")"
 
-(Trace s ts) `tappend` (Trace z (t:_)) = Trace (s+z) (t:ts)
+mt `tappend` (Trace z (t:_)) =
+    fmap (\(Trace s ts) -> Trace (s+z) (t:ts)) mt
 
 -- | Utility for displaying a Char-based alignment.
 debugAlign :: [Step Char] -> String
@@ -110,24 +112,34 @@
   -> v a  -- ^ Right sequence.
   -> Trace a s
 align AlignConfig{..} as bs =
-  revTrace . fix (memo . go) $ (lastIndex as, lastIndex bs)
+  let p = (lastIndex as, lastIndex bs)
+  in revTrace $ evalState (go p) M.empty
   where
   revTrace (Trace s t) = Trace s (reverse t)
   lastIndex v = G.length v - 1
   --
-  go k (i,j)
-    | i == (-1) || j == (-1) =
+  go p = do
+    res <- gets $ M.lookup p
+    case res of
+        Just r -> return r
+        Nothing -> do
+            newRes <- pgo p
+            modify (M.insert p newRes)
+            return newRes
+  --
+  pgo (i,j)
+    | i == (-1) || j == (-1) = return $
       if i == j then Trace 0 []
       else if i == (-1)
            then skipInit j stepRight bs
            else skipInit i stepLeft as
-    | otherwise =
+    | otherwise = do
       let a = as G.! i
           b = bs G.! j
-          diag  = k (i-1,j-1) `tappend` Trace (acPairScore a b) [stepBoth a b]
-          a_gap = k (i-1,  j) `tappend` Trace ac_gap_penalty [stepLeft a]
-          b_gap = k (  i,j-1) `tappend` Trace ac_gap_penalty [stepRight b]
-      in L.maximumBy (comparing traceScore) [diag, a_gap, b_gap]
+      diag  <- go (i-1,j-1) `tappend` Trace (acPairScore a b) [stepBoth a b]
+      a_gap <- go (i-1,  j) `tappend` Trace ac_gap_penalty [stepLeft a]
+      b_gap <- go (  i,j-1) `tappend` Trace ac_gap_penalty [stepRight b]
+      return $ L.maximumBy (comparing traceScore) [diag, a_gap, b_gap]
   --
   skipInit idx stepFun xs =
     let score = ac_initial_gap_penalty * fromIntegral (idx+1)
@@ -201,7 +213,7 @@
 -- | Align multiple sequences using the Center Star heuristic method by
 -- Chin, Ho, Lam, Wong and Chan (2003).
 -- <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.90.7448&rep=rep1&type=pdf>. 
--- Assumes the list of sequences to be non-empty, and the indices to be unique.
+-- Assumes the list of sequences to have length > 1, and the indices to be unique.
 centerStar :: (G.Vector v a, Num s, Ord s, Ord i)
   => AlignConfig a s
   -> [(i, v a)]  -- TODO use internal indices rather to make uniqueness sure
