diff --git a/reco/L1/CMakeLists.txt b/reco/L1/CMakeLists.txt
index 53f1bba9bd17544a717924199bc5e70bea5dc7c2..3def910df0366de12129af0657227a66871b7f0e 100644
--- a/reco/L1/CMakeLists.txt
+++ b/reco/L1/CMakeLists.txt
@@ -148,6 +148,8 @@ L1Algo/L1CAIteration.cxx
 L1Algo/L1BaseStationInfo.cxx
 L1Algo/L1InitManager.cxx
 L1Algo/L1Parameters.cxx
+L1Algo/L1InputData.cxx
+L1Algo/L1IODataManager.cxx
 L1Algo/L1ClonesMerger.cxx
 L1Algo/L1ConfigRW.cxx
 L1Algo/utils/L1AlgoDraw.cxx
@@ -286,6 +288,8 @@ Install(FILES CbmL1Counters.h
               L1Algo/L1InitManager.h
               L1Algo/L1CAIteration.h
               L1Algo/L1Parameters.h
+              L1Algo/L1InputData.h
+              L1Algo/L1IODataManager.h
               L1Algo/L1ClonesMerger.h
               L1Algo/L1ConfigRW.h
               L1Algo/L1Constants.h
diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx
index 00220d4a86b21743721d76fa15254cb6ef0c64e1..9be1b80d694dd4b23247549f6c3fc654e1b1ee2e 100644
--- a/reco/L1/CbmL1.cxx
+++ b/reco/L1/CbmL1.cxx
@@ -76,7 +76,7 @@ using std::ios;
 
 ClassImp(CbmL1);
 
-static L1Algo gAlgo _fvecalignment;  // TODO: gAlgo
+static L1Algo gAlgo _fvecalignment;  // TODO: Change coupling logic between L1Algo and CbmL1
 
 //L1AlgoInputData* fData_static _fvecalignment;
 
@@ -92,6 +92,7 @@ CbmL1::CbmL1() : CbmL1("L1") {}
 CbmL1::CbmL1(const char* name, Int_t verbose, Int_t performance, int dataMode, const TString& dataDir,
              int findParticleMode)
   : FairTask(name, verbose)
+  , fIODataManager(L1IODataManager(gAlgo.GetParameters()))
   , fPerformance(performance)
   , fSTAPDataMode(dataMode)
   , fSTAPDataDir(dataDir)
@@ -966,6 +967,8 @@ void CbmL1::Reconstruct(CbmEvent* event)
       ReadEvent(fpData, TsStart, TsLength, TsOverlap, FstHitinTs, areDataLeft, event);
     }
 
+    // Send data from IODataManager to L1Algo
+    fIODataManager.SendInputData(fpAlgo);
 
     // ********************************************************************************************
     if constexpr (0) {  // correct hits on MC // dbg
diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h
index 6c31a012a190db405a9a6270c2f83092d74be3ec..c97afc589c5e0bf4a744dc35614ee9da30c1fccc 100644
--- a/reco/L1/CbmL1.h
+++ b/reco/L1/CbmL1.h
@@ -51,6 +51,7 @@
 #include "L1Algo/L1Algo.h"
 #include "L1Algo/L1Vector.h"
 #include "L1EventEfficiencies.h"
+#include "L1IODataManager.h"
 
 struct L1AlgoInputData;
 class L1Algo;
@@ -397,6 +398,9 @@ public:
   L1Algo* fpAlgo               = nullptr;  ///< Pointer to the L1 track finder algorithm
   L1InitManager* fpInitManager = nullptr;  ///< Pointer to the initialization manager for the L1 algorithm
 
+  L1IODataManager fIODataManager;  ///< Input-output data manager
+
+
   bool fUseHitErrors = true;   ///<
   bool fMissingHits  = false;  ///< Turns on several ad-hock settings for "mcbm_beam_2021_07_surveyed.100ev" setup
 
diff --git a/reco/L1/CbmL1ReadEvent.cxx b/reco/L1/CbmL1ReadEvent.cxx
index b9d8f9a575ece5edce9fb60a6aa430e09388c7a3..89d3ab69160a7ee7b74838eb3082f3fc39aea944 100644
--- a/reco/L1/CbmL1ReadEvent.cxx
+++ b/reco/L1/CbmL1ReadEvent.cxx
@@ -221,7 +221,6 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength,
   // -- produce Sts hits from space points --
 
   for (int i = 0; i < fNStations; i++) {
-
     fData_->HitsStartIndex[i] = static_cast<L1HitIndex_t>(-1);
     fData_->HitsStopIndex[i]  = 0;
   }
@@ -1144,6 +1143,9 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength,
   fvHitStore.reserve(nHits);
   fvHitPointIndexes.reserve(nHits);
 
+  fIODataManager.ResetInputData();
+  fIODataManager.ReserveNhits(nHits);
+  fIODataManager.SetNhitKeys(NStrips);
 
   // ----- Fill
   for (int i = 0; i < nHits; i++) {
@@ -1166,27 +1168,17 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength,
     assert(th.iStripB >= 0 || th.iStripB < NStrips);
 
     L1Hit h;
-    h.f = th.iStripF;
-    h.b = th.iStripB;
-
-    h.ID = th.id;
-
-    h.t  = th.time;
-    h.dt = th.dt;
-
-    //  h.track = th.track;
-    //    h.dx  = th.dx;
-    //    h.dy  = th.dy;
-    h.du = th.du;
-    h.dv = th.dv;
-    h.u  = th.u;
-    h.v  = th.v;
-    //    h.dxy = th.dxy;
-    //     h.p = th.p;
-    //     h.q = th.q;
-    // h.ista = th.iStation;
-
-    h.z = th.z;
+    h.f   = th.iStripF;
+    h.b   = th.iStripB;
+    h.ID  = th.id;
+    h.t   = th.time;
+    h.dt  = th.dt;
+    h.du  = th.du;
+    h.dv  = th.dv;
+    h.u   = th.u;
+    h.v   = th.v;
+    h.z   = th.z;
+    h.iSt = th.iStation;
 
 
     // save hit
@@ -1203,10 +1195,12 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength,
 
 
     fData_->vHits.push_back(h);
+    fIODataManager.PushBackHit(h);
 
     int iSt = th.iStation;
 
-    if (fData_->HitsStartIndex[iSt] == static_cast<L1HitIndex_t>(-1)) fData_->HitsStartIndex[iSt] = nEffHits;
+    if (fData_->HitsStartIndex[iSt] == static_cast<L1HitIndex_t>(-1)) { fData_->HitsStartIndex[iSt] = nEffHits; }
+    assert(nEffHits == i);
     nEffHits++;
 
     fData_->HitsStopIndex[iSt] = nEffHits;
@@ -1230,6 +1224,7 @@ void CbmL1::ReadEvent(L1AlgoInputData* fData_, float& TsStart, float& TsLength,
   fpAlgo->SetData(fData_->GetHits(), fData_->GetNstrips(), fData_->GetSFlag(), fData_->GetHitsStartIndex(),
                   fData_->GetHitsStopIndex());
 
+
   if (fPerformance) {
     if (fVerbose >= 10) cout << "HitMatch is done." << endl;
     if (fVerbose >= 10) cout << "MCPoints and MCTracks are saved." << endl;
diff --git a/reco/L1/L1Algo/L1Algo.cxx b/reco/L1/L1Algo/L1Algo.cxx
index 36b9d066f2340b078c58898dafbac0645a9eec50..667b28ea4522fe74f65a08b9da37fee4a553f337 100644
--- a/reco/L1/L1Algo/L1Algo.cxx
+++ b/reco/L1/L1Algo/L1Algo.cxx
@@ -100,6 +100,15 @@ void L1Algo::Init(const bool UseHitErrors, const TrackingMode mode, const bool M
   fMomentumCutOff   = fInitManager.GetMomentumCutOff();
 }
 
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void L1Algo::ReceiveInputData(L1InputData&& inputData)
+{
+  fInputData = std::move(inputData);
+  // TODO: Reset here internal data (probably, we should have additional class for internal data)
+}
+
+
 ///
 void L1Algo::SetData(L1Vector<L1Hit>& Hits_, int nStrips_, L1Vector<unsigned char>& SFlag_,
                      const L1HitIndex_t* HitsStartIndex_, const L1HitIndex_t* HitsStopIndex_)
diff --git a/reco/L1/L1Algo/L1Algo.h b/reco/L1/L1Algo/L1Algo.h
index 4cd34ad21aaa0e77986beccc355654acd4c340df..fcbf372edeae273f99887e39c8fef2c2bbd97729 100644
--- a/reco/L1/L1Algo/L1Algo.h
+++ b/reco/L1/L1Algo/L1Algo.h
@@ -50,6 +50,7 @@ class L1AlgoDraw;
 #include "L1HitPoint.h"
 #include "L1HitsSortHelper.h"
 #include "L1InitManager.h"
+#include "L1InputData.h"
 #include "L1Parameters.h"
 #include "L1Portion.h"
 #include "L1Station.h"
@@ -171,6 +172,10 @@ public:
   /// Gets a pointer to the L1Algo initialization object
   L1InitManager* GetInitManager() { return &fInitManager; }
 
+  /// Receives input data
+  void ReceiveInputData(L1InputData&& inputData);
+
+
   /// ----- Hit-point-strips conversion routines ------
 
   void GetHitCoor(const L1Hit& _h, fscal& _x, fscal& _y, fscal& _z, const L1Station& sta);
@@ -455,11 +460,14 @@ private:
     "L1Algo::fvHitKeyFlags"};  ///< List of key flags: has been this hit or cluster already used
 
 public:
-  int fNstrips {0};                                    ///< number of strips
-  L1Vector<L1Hit>* vHits {nullptr};                    ///< hits as a combination of front-, backstrips and z-position
-  L1Grid vGrid[L1Constants::size::kMaxNstations];      ///<
+  L1InputData fInputData;  ///< Tracking input data
+
+  int fNstrips {0};                                ///< number of strips
+  L1Vector<L1Hit>* vHits {nullptr};                ///< hits as a combination of front and back strips and z-position
+  L1Grid vGrid[L1Constants::size::kMaxNstations];  ///<
   L1Grid vGridTime[L1Constants::size::kMaxNstations];  ///<
 
+
   L1Vector<unsigned char>* fStripFlag {nullptr};  // information of hits station & using hits in tracks;
 
   double fCATime {0.};  // time of track finding
diff --git a/reco/L1/L1Algo/L1CATrackFinder.cxx b/reco/L1/L1Algo/L1CATrackFinder.cxx
index 163e293691c260270b515b4809e26ec59192958a..34ee0329006fdce6be96e0fa87f4896674f86479 100644
--- a/reco/L1/L1Algo/L1CATrackFinder.cxx
+++ b/reco/L1/L1Algo/L1CATrackFinder.cxx
@@ -2252,10 +2252,10 @@ void L1Algo::CATrackFinder()
               if (isec != TRACKS_FROM_TRIPLETS_ITERATION)
 #endif
               {  // ghost supression !!!
-                // TODO: Primary => 3 hits tracks are saved, other whise 3 hit tracks are thrown away
+                // TODO: Primary => 3 hits tracks are saved, otherwise 3 hit tracks are thrown away
                 if (isec != kFastPrimIter && isec != kAllPrimIter && isec != kAllPrimEIter && isec != kAllSecEIter)
                   if (first_trip.GetLevel() == 0)
-                    continue;  // ghost suppression // find track with 3 hits only if it was created from a chain of triplets, but not from only one triplet
+                    continue;  //ghost suppression//find track with 3 hits only if it was created from a chain of triplets, but not from only one triplet
 
                 if (kGlobal != fTrackingMode && kMcbm != fTrackingMode) {
                   if ((firstTripletLevel == 0)
diff --git a/reco/L1/L1Algo/L1Constants.h b/reco/L1/L1Algo/L1Constants.h
index a174a0e8c0c8813767ee1b7968fa7a66b9efe4d4..b436d95c9b1da6c6db8b834d47374610354aca5b 100644
--- a/reco/L1/L1Algo/L1Constants.h
+++ b/reco/L1/L1Algo/L1Constants.h
@@ -61,6 +61,15 @@ namespace L1Constants
     /// Flag: hit errors
     /// true  - hit errors will be saved in the track extender algorithm
     constexpr bool kIfSaveHitErrorsInTrackExtender {false};
+
+    /// Flag: input data QA level
+    ///  - 0: no checks will be done
+    ///  - 1: only number of hits and strips as well as validity of hits first and last indexes will be checked
+    ///  - 2: hits sorting is checked
+    ///  - 3: every hit is checked for consistency
+    /// \note The larger Level corresponds to more precise checks, but is followed by larger time penalty
+    constexpr int kInputDataQaLevel = 3;
+
   }  // namespace control
 
   /// Physics constants
@@ -74,9 +83,9 @@ namespace L1Constants
   /// Miscellaneous constants
   namespace misc
   {
-    constexpr int kAssertionLevel {0};  ///< Assertion level
-    constexpr int kAlignment {16};
-  }  // namespace misc
+    constexpr int kAssertionLevel = 0;   ///< Assertion level
+    constexpr int kAlignment      = 16;  ///< Default alignment of data (bytes)
+  }                                      // namespace misc
 
   /// NoInit constants (aliases)
   namespace noin
diff --git a/reco/L1/L1Algo/L1Hit.h b/reco/L1/L1Algo/L1Hit.h
index 5a16305ed763a54003fcade555850d8709810297..4568b1eda8502680fe704d9bf2dbf43fd4c7a92a 100644
--- a/reco/L1/L1Algo/L1Hit.h
+++ b/reco/L1/L1Algo/L1Hit.h
@@ -12,6 +12,8 @@
 #ifndef L1Hit_h
 #define L1Hit_h
 
+#include "L1Constants.h"
+
 using L1HitIndex_t   = unsigned /*short*/ int;  ///< Index of L1Hit
 using L1StripIndex_t = unsigned /*short*/ int;  ///< Index of the station strip
 
@@ -20,18 +22,24 @@ using L1StripIndex_t = unsigned /*short*/ int;  ///< Index of the station strip
 /// Note: U is a transverse coordinate of the hit in the axis perpendicular to the front strip
 /// Note: V is a transverse coordinate of the hit in the axis perpendicular to the back strip
 ///
-class L1Hit {
+class /*alignas(L1Constants::misc::kAlignment)*/ L1Hit {
 public:
-  L1StripIndex_t f {0};  ///< front strip index
-  L1StripIndex_t b {0};  ///< back strip index
-  float u {0.f};         ///< measured U coordinate [cm]
-  float v {0.f};         ///< measured V coordinate [cm]
-  float t {0.f};         ///< measured time
-  float z {0.f};         ///< fixed Z coordinate
-  float du {0.f};        ///< measured uncertainty of U coordinate [cm]
-  float dv {0.f};        ///< measured uncertainty of V coordinate [cm]
-  float dt {0.f};        ///< measured uncertainty of time [ns]
-  int ID {0};            ///< TODO: check if this ID is redundant
+  L1StripIndex_t f {0};  ///< front hit key index
+  L1StripIndex_t b {0};  ///< back hit key index
+  /// NOTE: For STS f and b correspond to the indexes of the front and back clusters of the hit in a dataset. For other
+  ///       tracking detectors (MVD, MuCh, TRD, TOF) f == b and corresponds to the index of the hit. Indexes f and b
+  ///       do not intersect between different detector stations.
+
+  float u  = 0.f;  ///< measured U coordinate [cm]
+  float v  = 0.f;  ///< measured V coordinate [cm]
+  float t  = 0.f;  ///< measured time [ns]
+  float z  = 0.f;  ///< fixed Z coordinate [cm]
+  float du = 0.f;  ///< measured uncertainty of U coordinate [cm]
+  float dv = 0.f;  ///< measured uncertainty of V coordinate [cm]
+  float dt = 0.f;  ///< measured uncertainty of time [ns]
+  int ID   = 0;    ///< index of hit before hits sorting
+  int iSt  = 0;    ///< index of station in the active stations array
+  // TODO: Test speed penalty of using iSt index
 };
 
 #endif
diff --git a/reco/L1/L1Algo/L1IODataManager.cxx b/reco/L1/L1Algo/L1IODataManager.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..2b7f7d56823ee9231dd85b9133ad8629335f2d64
--- /dev/null
+++ b/reco/L1/L1Algo/L1IODataManager.cxx
@@ -0,0 +1,68 @@
+/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergey Gorbunov, Sergei Zharko [committer] */
+
+/// \file L1IODataManager.h
+/// \brief Input-output data manager for L1 tracking algorithm
+/// \since 08.08.2022
+/// \author S.Zharko <s.zharko@gsi.de>
+
+#include "L1IODataManager.h"
+
+#include "L1Algo.h"
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+L1IODataManager::L1IODataManager(const L1Parameters* pParameters) : fpParameters(pParameters) {}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+bool L1IODataManager::SendInputData(L1Algo* pAlgo)
+{
+  // Set boundary hit indexes
+  SetStartStopHitIndexes();
+
+  // Check data before input
+  if (CheckInputData<L1Constants::control::kInputDataQaLevel>()) {
+    assert(pAlgo);
+    pAlgo->ReceiveInputData(std::move(fInputData));
+    return true;
+  }
+  LOG(error) << "L1: Attempt to set up inconsistent input data";
+  return false;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void L1IODataManager::ResetInputData() noexcept
+{
+  L1InputData tmp;
+  fInputData.Swap(tmp);
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+void L1IODataManager::SetStartStopHitIndexes()
+{
+  // TODO: probably, it is better to loop before the actual number of stations
+  for (int iStation = 0; iStation < fpParameters->GetNstationsActive(); ++iStation) {
+    fInputData.fvStartHitIndexes[iStation] =
+      std::lower_bound(fInputData.fvHits.begin(), fInputData.fvHits.end(), iStation,
+                       [](const L1Hit& hit, int ist) { return hit.iSt < ist; })
+      - fInputData.fvHits.begin();
+
+    fInputData.fvStopHitIndexes[iStation] =
+      std::upper_bound(fInputData.fvHits.begin(), fInputData.fvHits.end(), iStation,
+                       [](int ist, const L1Hit& hit) { return hit.iSt > ist; })
+      - fInputData.fvHits.begin();
+
+    // Account for stations with no hits
+    if (fInputData.fvStartHitIndexes[iStation] == fInputData.fvStopHitIndexes[iStation]) {
+      fInputData.fvStartHitIndexes[iStation] = 0;
+      fInputData.fvStopHitIndexes[iStation]  = 0;
+    }
+  }
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
diff --git a/reco/L1/L1Algo/L1IODataManager.h b/reco/L1/L1Algo/L1IODataManager.h
new file mode 100644
index 0000000000000000000000000000000000000000..98fa07793792cab4e95c38c2ad76631ec60e0ef1
--- /dev/null
+++ b/reco/L1/L1Algo/L1IODataManager.h
@@ -0,0 +1,141 @@
+/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergey Gorbunov, Sergei Zharko [committer] */
+
+/// \file L1IODataManager.h
+/// \brief Input-output data manager for L1 tracking algorithm
+/// \since 05.08.2022
+/// \author S.Zharko <s.zharko@gsi.de>
+
+#ifndef L1IODataManager_h
+#define L1IODataManager_h 1
+
+#include "L1Constants.h"
+#include "L1InputData.h"
+
+class L1Parameters;
+class L1Algo;
+//class L1OutputData;
+
+/// Class L1IODataManager defines the interface for input and output data flow in the L1 tracking algorithm
+///
+class alignas(L1Constants::misc::kAlignment) L1IODataManager {
+public:
+  // ***************************
+  // ** Member functions list **
+  // ***************************
+
+  // ** Constructors and destructor **
+
+  /// Default constructor
+  L1IODataManager() = delete;
+
+  /// Constructor
+  /// \param fpParameters  Pointer to the L1 tracking algorithm parameters instance
+  L1IODataManager(const L1Parameters* pParameters);
+
+  /// Destructor
+  ~L1IODataManager() = default;
+
+  /// Copy constructor
+  L1IODataManager(const L1IODataManager& other) = delete;
+
+  /// Move constructor
+  L1IODataManager(L1IODataManager&& other) = delete;
+
+  /// Copy assignment operator
+  L1IODataManager& operator=(const L1IODataManager& other) = delete;
+
+  /// Move assignment operator
+  L1IODataManager& operator=(L1IODataManager&& other) = delete;
+
+  /// Reserve number of hits
+  /// \param  nHits  Number of hits to be stored
+  /// \note   If one does not call this method, the underlying vector of hits will be filled with the time penalty
+  void ReserveNhits(L1HitIndex_t nHits) { fInputData.fvHits.reserve(nHits); }
+
+  /// Resets the input data block
+  void ResetInputData() noexcept;
+
+  /// Pushes back a hit
+  /// \param  hit  An L1Hit object
+  void PushBackHit(const L1Hit& hit) { fInputData.fvHits.push_back(hit); }
+
+  /// Sets the number of hit keys
+  /// \param  nKeys  Number of hit keys
+  void SetNhitKeys(int nKeys) { fInputData.fNhitKeys = nKeys; }
+
+  /// Sends (moves) input data to the destination reference
+  /// \param  pAlgo  Pointer to the L1 tracking algorithm main class
+  /// \return Success flag
+  bool SendInputData(L1Algo* pAlgo);
+
+private:
+  /// Sets the start and stop indexes vs. station index
+  void SetStartStopHitIndexes();
+
+  /// Provides quick QA for input data
+  /// \tparam  Level  The level of the checks. The values of the parameter:
+  ///                 - 0: no checks will be done
+  ///                 - 1: only number of hits and strips as well as validity of hits first and last indexes will be checked
+  ///                 - 2: hits sorting is checked
+  ///                 - 3: every hit is checked for consistency
+  /// \note    The larger Level corresponds to more precise checks, but is followed by larger time penalty
+  template<int Level>
+  bool CheckInputData() const;
+
+
+  // ***************************
+  // ** Member variables list **
+  // ***************************
+
+  L1InputData fInputData {};  ///< Object of input data
+
+  const L1Parameters* fpParameters = nullptr;  ///< Pointer to the tracking parameters object
+};
+
+
+// *************************************
+// ** Inline functions implementation **
+// *************************************
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+
+// TODO: Complete this function
+template<int Level>
+inline bool L1IODataManager::CheckInputData() const
+{
+  if constexpr (Level == 0) { return true; }  // Level = 0 -> do nothing
+  else if constexpr (Level > 0) {             // Level = 1 and higher
+    // ----- Check if the hits container is not empty ------------------------------------------------------------------
+    if (fInputData.fvHits.size() == 0) {
+      LOG(warn) << "L1IODataManager [check input]: Sample contains empty hits, tracking will not be executed";
+      return false;
+    }
+
+    // ----- Checks if the number of hit keys is valid -----------------------------------------------------------------
+    if (fInputData.fNhitKeys < 1) {
+      LOG(error) << "L1IODataManager [check input]: Incorrect number of keys passed (" << fInputData.fNhitKeys
+                 << "), tracking will not be executed";
+      return false;
+    }
+
+    // ----- Checks the indexes of first and last hits in stations
+    // TODO: Add one of the two following checks for fvStartHitIn
+
+    if constexpr (Level > 1) {  // Level = 2 and higher
+      // ----- Checks for hits sorting ---------------------------------------------------------------------------------
+      // TODO...
+      if constexpr (Level > 2) {  // Level = 3 and higher
+        // ----- Checks for consistency of the particular hit ----------------------------------------------------------
+        // TODO...
+      }
+    }
+    return true;
+  }
+  return true;
+}
+
+
+#endif  // L1IODataManager_h
diff --git a/reco/L1/L1Algo/L1InitManager.cxx b/reco/L1/L1Algo/L1InitManager.cxx
index 78f230a6737d1eba1e5e095adb9a680dc0f2d608..718d5037a4837db35199688ac2a9a283425fc3db 100644
--- a/reco/L1/L1Algo/L1InitManager.cxx
+++ b/reco/L1/L1Algo/L1InitManager.cxx
@@ -2,11 +2,9 @@
    SPDX-License-Identifier: GPL-3.0-only
    Authors: Sergey Gorbunov, Sergei Zharko [committer] */
 
-/************************************************************************************************************
- * @file L1InitManager.cxx
- * @brief Input data management class for L1Algo
- * @since 19.01.2022
- ***********************************************************************************************************/
+/// \file L1InitManager.cxx
+/// \brief Input parameters management class for L1Algo
+/// \since 19.01.2022
 
 #include "L1InitManager.h"
 
diff --git a/reco/L1/L1Algo/L1InputData.cxx b/reco/L1/L1Algo/L1InputData.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..35dfe5bdc122071e7caf2c07397ef90384158a37
--- /dev/null
+++ b/reco/L1/L1Algo/L1InputData.cxx
@@ -0,0 +1,55 @@
+/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergey Gorbunov, Sergei Zharko [committer] */
+
+/// \file   L1InputData.cxx
+/// \brief  Structure for input data to the L1 tracking algorithm (implementation)
+/// \since  08.08.2022
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#include "L1InputData.h"
+
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+L1InputData::L1InputData()
+{
+  // Init first hit indexes
+  //for (int iStation = 0; iStation < L1Constants::size::kMaxNstations; ++iStation) {
+  //  fvFirstHitIndexes[iStation] = static_cast<L1HitIndex_t>(-1);
+  //}
+  // NOTE: the last hit indexes should be initialized with 0. It is done in the variable declaration
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+L1InputData::L1InputData(const L1InputData& other)
+  : fvHits(other.fvHits)
+  , fvStartHitIndexes(other.fvStartHitIndexes)
+  , fvStopHitIndexes(other.fvStopHitIndexes)
+  , fNhitKeys(other.fNhitKeys)
+{
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+L1InputData::L1InputData(L1InputData&& other) noexcept { this->Swap(other); }
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+L1InputData& L1InputData::operator=(const L1InputData& other)
+{
+  if (this != &other) { L1InputData(other).Swap(*this); }
+  return *this;
+}
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+L1InputData& L1InputData::operator=(L1InputData&& other) noexcept
+{
+  if (this != &other) {
+    L1InputData tmp(std::move(other));
+    this->Swap(tmp);
+  }
+  return *this;
+}
diff --git a/reco/L1/L1Algo/L1InputData.h b/reco/L1/L1Algo/L1InputData.h
new file mode 100644
index 0000000000000000000000000000000000000000..945bee3e237fef7aa697deeb7e133e2762c075bd
--- /dev/null
+++ b/reco/L1/L1Algo/L1InputData.h
@@ -0,0 +1,122 @@
+/* Copyright (C) 2022 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt
+   SPDX-License-Identifier: GPL-3.0-only
+   Authors: Sergey Gorbunov, Sergei Zharko [committer] */
+
+/// \file   L1InputData.h
+/// \brief  Structure for input data to the L1 tracking algorithm (declaration)
+/// \since  08.08.2022
+/// \author Sergei Zharko <s.zharko@gsi.de>
+
+#ifndef L1InputData_h
+#define L1InputData_h 1
+
+#include <array>
+
+#include "L1Constants.h"
+#include "L1Hit.h"
+#include "L1Vector.h"
+
+
+/// Class L1InputData represents a block of the input data to the L1 tracking algorithm per event or time slice.
+/// Filling of the L1InputData is carried out with L1IODataManager class
+///
+class alignas(L1Constants::misc::kAlignment) L1InputData {
+public:
+  // **************************
+  // ** Friend classes list  **
+  // **************************
+
+  friend class L1IODataManager;  ///< Class which fills the L1InputData object for each event or time slice
+
+
+  // ***************************
+  // ** Member functions list **
+  // ***************************
+
+  // ** Constructors and destructor **
+
+  /// Default constructor
+  L1InputData();
+
+  /// Destructor
+  ~L1InputData() = default;
+
+  /// Copy constructor
+  L1InputData(const L1InputData& other);
+
+  /// Move constructor
+  L1InputData(L1InputData&&) noexcept;
+
+  /// Copy assignment operator
+  L1InputData& operator=(const L1InputData& other);
+
+  /// Move assignment operator
+  L1InputData& operator=(L1InputData&& other) noexcept;
+
+  /// Gets hits sample size
+  L1HitIndex_t GetSampleSize() const { return fvHits.size(); }
+
+
+  // ** Accessors **
+
+  /// Gets reference to hit by its index
+  /// \param  index  Index of hit in the hits sample
+  const L1Hit& GetHit(L1HitIndex_t index) const { return fvHits[index]; }
+
+  /// Get reference to hits vector
+  const L1Vector<L1Hit>& GetHits() const { return fvHits; }
+
+  /// Gets total number of stored keys
+  int GetNhitKeys() const { return fNhitKeys; }
+
+  /// Gets index of the first hit in the sorted hits vector
+  /// \param iStation  Index of the tracking station in the active stations array
+  L1HitIndex_t GetStartHitIndex(int iStation) const { return fvStartHitIndexes[iStation]; }
+
+  /// Gets index of (the last + 1) hit in the sorted hits vector
+  /// \param iStation  Index of the tracking station in the active stations array
+  L1HitIndex_t GetStopHitIndex(int iStation) const { return fvStopHitIndexes[iStation]; }
+
+
+private:
+  /// Swap method
+  void Swap(L1InputData& other) noexcept;
+
+
+  // ***************************
+  // ** Member variables list **
+  // ***************************
+
+  L1Vector<L1Hit> fvHits = {"L1InputData::fvHits"};  ///< Sorted sample of input hits
+                                                     ///< \note Hits in the vector are sorted as follows. Among two hits
+                                                     ///<       the largest has the largest station index in the active
+    ///<       stations array. If both indexes were measured withing one
+    ///<       station, the largest hit has the largest y component of
+    ///<       the coordinates
+
+  /// Index of the first hit in the sorted hits vector for a given station
+  std::array<L1HitIndex_t, L1Constants::size::kMaxNstations> fvStartHitIndexes = {0};
+
+  /// Index of the last hit in the sorted hits vector for a given station
+  std::array<L1HitIndex_t, L1Constants::size::kMaxNstations> fvStopHitIndexes = {0};
+
+  /// Number of hit keys used for rejecting fake STS hits
+  int fNhitKeys = -1;
+};
+
+
+// ********************************************
+// ** Inline member functions initialization **
+// *********************************************
+
+// ---------------------------------------------------------------------------------------------------------------------
+//
+[[gnu::always_inline]] inline void L1InputData::Swap(L1InputData& other) noexcept
+{
+  std::swap(fvHits, other.fvHits);
+  std::swap(fvStartHitIndexes, other.fvStartHitIndexes);
+  std::swap(fvStopHitIndexes, other.fvStopHitIndexes);
+  std::swap(fNhitKeys, other.fNhitKeys);
+}
+
+#endif  // L1InputData_h
diff --git a/reco/L1/L1Algo/L1Parameters.cxx b/reco/L1/L1Algo/L1Parameters.cxx
index 29bdaddc15363d2fefdd2ab34edde0bde8295695..1ec8e92e60f62c2f2f65e35cd197986886e89834 100644
--- a/reco/L1/L1Algo/L1Parameters.cxx
+++ b/reco/L1/L1Algo/L1Parameters.cxx
@@ -11,18 +11,18 @@
 
 #include <FairLogger.h>
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 L1Parameters::L1Parameters()
 {
   fActiveStationGlobalIDs.fill(-1);  // by default, all stations are inactive, thus all the IDs must be -1
 }
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 L1Parameters::~L1Parameters() noexcept {}
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 L1Parameters::L1Parameters(const L1Parameters& other) noexcept
   : fMaxDoubletsPerSinglet(other.fMaxDoubletsPerSinglet)
@@ -43,7 +43,7 @@ L1Parameters::L1Parameters(const L1Parameters& other) noexcept
 {
 }
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 L1Parameters& L1Parameters::operator=(const L1Parameters& other) noexcept
 {
@@ -51,11 +51,11 @@ L1Parameters& L1Parameters::operator=(const L1Parameters& other) noexcept
   return *this;
 }
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 L1Parameters::L1Parameters(L1Parameters&& other) noexcept { this->Swap(other); }
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 L1Parameters& L1Parameters::operator=(L1Parameters&& other) noexcept
 {
@@ -66,7 +66,7 @@ L1Parameters& L1Parameters::operator=(L1Parameters&& other) noexcept
   return *this;
 }
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 void L1Parameters::Swap(L1Parameters& other) noexcept
 {
@@ -87,7 +87,7 @@ void L1Parameters::Swap(L1Parameters& other) noexcept
   std::swap(fDevIsMatchTripletsViaMc, other.fDevIsMatchTripletsViaMc);
 }
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 void L1Parameters::CheckConsistency() const
 {
@@ -202,7 +202,7 @@ void L1Parameters::CheckConsistency() const
 }
 
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 void L1Parameters::Print(int /*verbosityLevel*/) const
 {
@@ -210,7 +210,7 @@ void L1Parameters::Print(int /*verbosityLevel*/) const
   LOG(info) << ToString();
 }
 
-//------------------------------------------------------------------------------------------------------------------------------------
+//----------------------------------------------------------------------------------------------------------------------
 //
 std::string L1Parameters::ToString(int verbosity, int indentLevel) const
 {