diff --git a/edges.cabal b/edges.cabal
--- a/edges.cabal
+++ b/edges.cabal
@@ -1,7 +1,7 @@
 name:
   edges
 version:
-  0.6
+  0.8
 category:
   Graphs
 synopsis:
@@ -15,7 +15,7 @@
 author:
   Nikita Volkov <nikita.y.volkov@mail.ru>
 maintainer:
-  Metrix Ninjas <ninjas@metrix.ai>
+  Metrix Tech Team <tech@metrix.ai>
 copyright:
   (c) 2018, Metrix.AI
 license:
diff --git a/library/Edges/NodeCounting.hs b/library/Edges/NodeCounting.hs
--- a/library/Edges/NodeCounting.hs
+++ b/library/Edges/NodeCounting.hs
@@ -40,11 +40,37 @@
 
 {-|
 Count the occurrences of targets based on the occurrences of sources.
-
-Utilizes concurrency.
 -}
 targets :: Edges source target -> NodeCounts source -> NodeCounts target
-targets (Edges targetAmount edgesPma) (NodeCounts sourceCountsPa) =
+targets = targetsWithMinSourceAmount 1
+
+{-|
+Count the occurrences of targets based on the occurrences of sources.
+
+This function can be used to reduce the amount of computation by excluding the nodes,
+which don't make much difference.
+-}
+targetsWithMinSourceAmount :: Word32 -> Edges source target -> NodeCounts source -> NodeCounts target
+targetsWithMinSourceAmount minSourceCount (Edges targetAmount edgesPma) (NodeCounts sourceCountsPa) =
+  unsafePerformIO $ do
+    targetCountsMpa <- newPrimArray targetAmount
+    forMInAscendingRange_ 0 (sizeofPrimArray sourceCountsPa) $ \ sourceIndex -> let
+      sourceCount = indexPrimArray sourceCountsPa sourceIndex
+      in if sourceCount >= minSourceCount
+        then UnfoldM.forM_ (fmap fromIntegral $ PrimMultiArray.toUnfoldAtM edgesPma sourceIndex) $ \ targetIndex -> do
+          targetCount <- readPrimArray targetCountsMpa targetIndex
+          writePrimArray targetCountsMpa targetIndex (targetCount + sourceCount)
+        else return ()
+    targetCountsPa <- unsafeFreezePrimArray targetCountsMpa
+    return (NodeCounts targetCountsPa)
+
+{-|
+Count the occurrences of targets based on the occurrences of sources.
+
+Utilizes parallellism.
+-}
+targetsParallelly :: Edges source target -> NodeCounts source -> NodeCounts target
+targetsParallelly (Edges targetAmount edgesPma) (NodeCounts sourceCountsPa) =
   unsafePerformIO $ Par.runParIO $ do
     targetCountVarTable <- liftIO (TVarArray.new 0 targetAmount)
     Par.parFor (Par.InclusiveRange 0 (pred (sizeofPrimArray sourceCountsPa))) $ \ sourceIndex ->
diff --git a/library/Edges/Potoki/Produces.hs b/library/Edges/Potoki/Produces.hs
--- a/library/Edges/Potoki/Produces.hs
+++ b/library/Edges/Potoki/Produces.hs
@@ -12,15 +12,15 @@
 {-|
 Enumerate nodes.
 -}
-sourceNodes :: Amount a -> Produce (Node a)
-sourceNodes (Amount amountInt) = coerce (enumInRange 0 (pred amountInt))
+nodes :: Amount a -> Produce (Node a)
+nodes (Amount amountInt) = coerce (enumInRange 0 (pred amountInt))
 
 {-|
 Node counts paired with the source nodes.
 -}
 nodeCounts :: Amount a -> (Node a -> NodeCounts b) -> Produce (Node a, NodeCounts b)
 nodeCounts amount nodeCounts =
-  transform (Transforms.executeNodeCountQuery nodeCounts) (sourceNodes amount)
+  transform (Transforms.executeNodeCountQuery nodeCounts) (nodes amount)
 
 readNodeCountsFromFile :: FilePath -> Produce (Either IOException (Either Text (Node a, NodeCounts b)))
 readNodeCountsFromFile file =
diff --git a/library/Edges/Prelude.hs b/library/Edges/Prelude.hs
--- a/library/Edges/Prelude.hs
+++ b/library/Edges/Prelude.hs
@@ -3,8 +3,8 @@
   module Exports,
   UnboxedVector,
   modifyTVar',
-  forMToZero_,
-  forMFromZero_,
+  forMInAscendingRange_,
+  forMInDescendingRange_,
   (.),
 )
 where
@@ -136,15 +136,15 @@
     x <- readTVar var
     writeTVar var $! f x
 
-{-# INLINE forMToZero_ #-}
-forMToZero_ :: Applicative m => Int -> (Int -> m a) -> m ()
-forMToZero_ !startN f =
-  ($ pred startN) $ fix $ \loop !n -> if n >= 0 then f n *> loop (pred n) else pure ()
-
-{-# INLINE forMFromZero_ #-}
-forMFromZero_ :: Applicative m => Int -> (Int -> m a) -> m ()
-forMFromZero_ !endN f =
-  ($ 0) $ fix $ \loop !n -> if n < endN then f n *> loop (succ n) else pure ()
-
 (.) :: Semigroupoid s => s b c -> s a b -> s a c
 (.) = o
+
+{-# INLINE forMInAscendingRange_ #-}
+forMInAscendingRange_ :: Applicative m => Int -> Int -> (Int -> m a) -> m ()
+forMInAscendingRange_ !startN !endN f =
+  ($ startN) $ fix $ \loop !n -> if n < endN then f n *> loop (succ n) else pure ()
+
+{-# INLINE forMInDescendingRange_ #-}
+forMInDescendingRange_ :: Applicative m => Int -> Int -> (Int -> m a) -> m ()
+forMInDescendingRange_ !startN !endN f =
+  ($ pred startN) $ fix $ \loop !n -> if n >= endN then f n *> loop (pred n) else pure ()
