diff --git a/Makefile b/Makefile
index 772fc2c33e25be28119b86269816862d6f0e86ce..a1430e1b1f689df8a3c048523e8c888246c03f3b 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,6 @@
 default: groupConnectivity.so clean_obj
 
-groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py compileTimeOptions.h generateCompileTimeOptions.sh rings.h fast-array.h twoCuts.h parmap.py
+groupConnectivity.so: groupConnectivity.pyx group-connectivity.h setup.py compileTimeOptions.h generateCompileTimeOptions.sh rings.h fast-array.h twoCuts.h parmap.py groupConnectivityNaive.py
 	./generateCompileTimeOptions.sh > options.h
 	python setup.py build_ext
 	cp build/lib*/groupConnectivity.so .
diff --git a/groupConnectivity.pyx b/groupConnectivity.pyx
index edcf2a1a2557971398e295f4eb44267429a0b9de..f0f0eae5d2b60ba2f3bfb371d59597de3fb04ff5 100644
--- a/groupConnectivity.pyx
+++ b/groupConnectivity.pyx
@@ -1,8 +1,11 @@
 from libcpp.vector cimport vector
 from libcpp cimport bool
 from libcpp.utility cimport pair
-from sage.graphs.graph import Graph
+from sage.graphs.graph import Graph, DiGraph
+
+# include because we don't want it to became external dependecy
 include "parmap.py"
+include "groupConnectivityNaive.py"
 
 cdef extern from "group-connectivity.h" namespace "Ring":
   cdef cppclass Z4[T]:
@@ -28,6 +31,7 @@ cdef extern from "group-connectivity.h":
 
 
 def pathToEdges(G, path):
+  """Transform list of vertices into list of edges."""
   ret = []
   u = path[0]
   for v in path[1:]:
@@ -39,10 +43,7 @@ def pathToEdges(G, path):
 
 
 def theOtherNeighbour(G, v, w):
-  """
-  Given vertex v of degree 2 returns neighbour
-  of v not equal to w.
-  """
+  """Return neighbour of v in G not equal to w given v has degree 2."""
   N = G.neighbors(v)
   if N[0] == w:
     return N[1]
diff --git a/groupConnectivityNaive.py b/groupConnectivityNaive.py
new file mode 100644
index 0000000000000000000000000000000000000000..e72f7c3387fb6fdf6ad95c31d46e4e33538844d7
--- /dev/null
+++ b/groupConnectivityNaive.py
@@ -0,0 +1,100 @@
+def flowEnumerator(G, group):
+  """Enumerate all flows of given graph.
+
+  Graph G must be directed and it edges labeled with numbers 0 to |E(G)|.
+  """
+
+  m = G.num_edges()
+
+  assert(G.is_directed())
+  assert(set(x for _, _, x in G.edges()) == set(range(m)))
+
+  def to_elem_vector(cycle):
+    vec = [ group.zero() ] * m
+    for (u, v, x) in cycle:
+      if u > v:
+        vec[x] = -group.one()
+      else:
+        vec[x] = group.one()
+    return vec
+
+  elemVecs = map(to_elem_vector, Graph(G).cycle_basis(output = "edge"))
+
+  def combine(vec, i):
+    if i >= len(elemVecs):
+      yield vec
+      return
+
+    for e in group:
+      for v in combine(map(lambda x: x[0] + e * x[1], zip(vec, elemVecs[i])), i + 1):
+        yield v
+
+  for v in combine([group.zero()] * m, 0):
+    yield v
+
+
+def testGroupConnectivityNaive(G_, group, forb_spanning_tree = False, list_all = False):
+  E = [ (u, v, i) for i, (u, v, _) in enumerate(G_.edges()) ]
+  G = DiGraph([G_.vertices(), E], format='vertices_and_edges')
+  m = G.num_edges()
+  info = { 'graph': G, 'edges': E }
+
+  if forb_spanning_tree:
+    T = G.min_spanning_tree()
+  else:
+    T = G.edges()
+
+  info['span_tree'] = T
+
+  T = [ x for _, _, x in T ]
+
+  flows = list(flowEnumerator(G, group))
+  info['all_flows'] = flows
+
+  mask = [group.zero()] * m
+  for e in T:
+    mask[e] = None
+
+  def is_compatible(f, x):
+    for i in range(m):
+      if f[i] == x[i]:
+        return False
+    return True
+
+  flows = [ f for f in flows if is_compatible(f, mask) ]
+  info['compatible_flows'] = flows
+
+  Elems = [ x for x in group ]
+  forb = [ group.zero() ] * m
+
+  def forb_iter(e):
+    if e >= len(T):
+      yield True
+      return
+
+    for v in Elems:
+      forb[T[e]] = v
+      for r in forb_iter(e + 1):
+        yield r
+
+  def find_flow():
+    for f in flows:
+      if is_compatible(f, forb):
+        return True
+    return False
+
+  ret = []
+
+  for _ in forb_iter(0):
+    if not find_flow():
+      if not list_all:
+        return (False, info, [forb])
+      ret.append(list(forb))
+
+  return (len(ret) == 0, info, ret)
+
+def labelsFromArray(G, E, labels):
+  for (u, v, i) in E:
+    G.set_edge_label(u, v, labels[i])
+
+