diff --git a/element.cxx b/element.cxx
index cf85b8d53663dc0bfee08ecd28d2052bfd392964..75d52737b4f1bf4c7cd462013894935dbf37e4af 100644
--- a/element.cxx
+++ b/element.cxx
@@ -1,5 +1,6 @@
 #include <algorithm>
 #include <cassert>
+#include <iostream>
 
 #include "element.hxx"
 
@@ -42,3 +43,17 @@ bool Element::nextState()
      dir = Direction::Ordered;
      return false;
 }
+
+bool Element::contains(Symbol smybol) const
+{
+    return std::find(symbols_.begin(), symbols_.end(), smybol) != symbols_.end();
+}
+
+void Element::print() const
+{
+    for(auto symbol : symbols_)
+    {
+        std::cout << symbol << ", ";
+    }
+    std::cout << std::endl;
+}
diff --git a/element.hxx b/element.hxx
index 3c87d72ee6954c00021590ac3074c001d1f423b9..28d3af74366f73adb09ad4dbf852c8a5da990588 100644
--- a/element.hxx
+++ b/element.hxx
@@ -12,7 +12,6 @@ private:
     Alignment align = Alignment::Horizontal;
     Direction dir = Direction::Ordered;
     std::vector<Symbol> symbols_;
-    bool used_ = false;
 public:
     Element(std::vector<Symbol> symbols);
     Element(const Element&);
@@ -24,6 +23,10 @@ public:
     Alignment getAlign() const { return align; }
     Direction getDir() const { return dir; }
 
+    bool contains(Symbol symbol) const;
+
+    void print() const;
+
     /**
      * Sets the Element into a new state. State is determined by the alignment
      * and direction of the Element.
diff --git a/matrix.cxx b/matrix.cxx
index 929ccb237e0bcaf40e92939ca4a3f4e1b7a7bacb..8ac21380e3241ef45ca1910d7b6f873f2e9c71bd 100644
--- a/matrix.cxx
+++ b/matrix.cxx
@@ -2,6 +2,7 @@
 #include "utils.hxx"
 #include "element.hxx"
 #include <cassert>
+#include <iostream>
 
 Matrix::Matrix(std::size_t dim)
     : board_{dim, std::vector<int>(dim, 0)}
@@ -12,24 +13,70 @@ bool Matrix::put(const Element& element, const Position& pos)
     Direction dir = element.getDir();
     Alignment align = element.getAlign();
 
-    // check if free
+    // check out of bound
+    if((align == Alignment::Horizontal && pos.y + element.size() > size())
+            || ( align == Alignment::Vertical && pos.x + element.size() > size()))
+        return false;
+
+    // check if position not free
     for(std::size_t i=0; i< element.size(); ++i)
     {
         if(align == Alignment::Horizontal)
         {
-            if(pos.y+i >= size() )
-                return false;
             if(board_.at(pos.x).at(pos.y+i) > 0)
                 return false;
         }
         else // Alignment::Vertical
         {
-            if(pos.x+i >= size() )
-                return false;
             if(board_.at(pos.x+i).at(pos.y) > 0)
                 return false;
         }
     } 
+
+    // check symbol collision
+    if(align == Alignment::Horizontal)
+    {
+        std::size_t x = pos.x;
+        for(std::size_t i=0; i< size(); ++i)
+            if(element.contains(at(Position{x, i})))
+                    return false;
+        if(dir == Direction::Ordered)
+        {
+            for(std::size_t i=0; i<size(); ++i)
+                for(std::size_t j=0; j<element.size(); j++)
+                    if(element.get(j) == at(Position{i,j+pos.y}))
+                            return false;
+        }
+        else
+        {
+            for(std::size_t i=0; i<size(); ++i)
+                for(std::size_t j=0; j<element.size(); j++)
+                    if(element.getReversed(j) == at(Position{i,j+pos.y}))
+                            return false;
+
+        }
+    }
+    else if(align == Alignment::Vertical)
+    {
+        std::size_t y = pos.y;
+        for(std::size_t i=0; i< size(); ++i)
+            if(element.contains(at(Position{i, y})))
+                    return false;
+        if(dir == Direction::Ordered)
+        {
+            for(std::size_t i=0; i<size(); ++i)
+                for(std::size_t j=0; j<element.size(); j++)
+                    if(element.get(j) == at(Position{j+pos.x,i}))
+                            return false;
+        }
+        else
+        {
+            for(std::size_t i=0; i<size(); ++i)
+                for(std::size_t j=0; j<element.size(); j++)
+                    if(element.getReversed(j) == at(Position{j+pos.x,i}))
+                            return false;
+        }
+    }
     
     // fill in
     for(std::size_t i=0; i< element.size(); ++i)
@@ -53,19 +100,44 @@ bool Matrix::put(const Element& element, const Position& pos)
     return true;
 }
 
-bool Matrix::putFirst(const Element& elem)
+bool Matrix::putFirst(const Element& elem, Position& posIn)
 {
     for( std::size_t i=0; i< board_.size(); ++i)
         for( std::size_t j=0; j<board_.size(); ++j)
         {
             Position pos{i,j};
             if( isFree(pos) )
+            {
+                posIn = pos;
                 return put(elem, pos);
+            }
         }
     assert(false); // matrix is full (solved)
     return false;
 }
 
+void Matrix::free(const Element& elem, const Position& pos)
+{
+    Alignment align = elem.getAlign();
+
+    if(align == Alignment::Horizontal)
+        assert(pos.y + elem.size() <= size());
+    else
+        assert(pos.x + elem.size() <= size());
+
+    for(std::size_t i=0; i< elem.size(); ++i)
+    {
+        if(align == Alignment::Horizontal)
+        {
+            board_[pos.x][pos.y+i] = 0;
+        }
+        else // Alignment::Vertical
+        {
+            board_[pos.x + i][pos.y] = 0;
+        }
+    } 
+}
+
 Symbol Matrix::at(const Position& pos) const
 {
     return board_.at(pos.x).at(pos.y);
@@ -75,3 +147,14 @@ bool Matrix::isFree(const Position& pos)
 {
     return at(pos) <= 0;
 }
+
+void Matrix::print() const
+{
+    for(auto& row : board_)
+    {
+        for(auto symbol : row )
+            std::cout << symbol << " ";
+        std::cout << std::endl;
+    }
+    std::cout << "--------------------" << std::endl;
+}
diff --git a/matrix.hxx b/matrix.hxx
index 29083179dcd8adf701c832dfc31806b9cb5c7fae..abc013951feda058c392a526e79b63a72e92ab73 100644
--- a/matrix.hxx
+++ b/matrix.hxx
@@ -16,11 +16,14 @@ protected:
 public:
     Matrix(std::size_t dim);
     bool put(const Element& elem, const Position& pos);
-    bool putFirst(const Element& elem);
+    bool putFirst(const Element& elem, Position& posIn);
+    void free(const Element& elem, const Position& pos);
     bool isFree(const Position& pos);
     std::size_t size() const { return board_.size(); }
 
     bool isSolved() const { return solved; }
+
+    void print() const;
 };
 
 
diff --git a/processor.cxx b/processor.cxx
index e21d91b18321eac9f12868f8ad8ef75897f9a3f2..5f81d596046f91a597ea4acf08576d71fddfb0c2 100644
--- a/processor.cxx
+++ b/processor.cxx
@@ -18,8 +18,8 @@ void Processor::process(std::list<Element> list)
     
     if(list.size() == 0)
     {
-        // TODO do something with the matrix
-        std::cout << "kesz" << std::endl;
+        rMatrix_.print();
+        ready_ = true;
         return;
     }
 
@@ -29,20 +29,24 @@ void Processor::process(std::list<Element> list)
     auto it = list.begin();
     while( hasMoreState || it!= list.end() )
     {
-        success = rMatrix_.putFirst(*it);
+        Position pos{0,0};
+        success = rMatrix_.putFirst(*it, pos);
         if(success)
         {
+            // rMatrix_.print();
             // copy everything except current
             std::list<Element> copy;
             std::copy(list.begin(), it, std::back_inserter(copy));
             copy.insert(copy.end(), std::next(it), list.end());
             process(std::move(copy));
+            if(ready_)
+                it->print();
+                
+            rMatrix_.free(*it, pos);
         }
-        else
-        {
-            hasMoreState = it->nextState();
-            if(!hasMoreState)
-                it++;
-        }
+
+        hasMoreState = it->nextState();
+        if(!hasMoreState)
+            it++;
     }
 }
diff --git a/processor.hxx b/processor.hxx
index 911ae084ec2eb1548de275c35d8845c815263567..8005531f655c0004bb5e1a3aa671754c39b54496 100644
--- a/processor.hxx
+++ b/processor.hxx
@@ -9,7 +9,8 @@
 
 class Processor
 {
-    private:    
+    private:
+        bool ready_ = false;
         Matrix& rMatrix_;
 
     public: