diff --git a/source/Lib/CommonLib/CodingStructure.cpp b/source/Lib/CommonLib/CodingStructure.cpp
index 81e1e9ed9ed8c73e9d998ae9d89b983a8e1425d2..9cf659f95a3be631fd4b3815d988c2dea75a90a4 100644
--- a/source/Lib/CommonLib/CodingStructure.cpp
+++ b/source/Lib/CommonLib/CodingStructure.cpp
@@ -1746,7 +1746,13 @@ TransformUnit& CodingStructure::addTU( const UnitArea &unit, const ChannelType c
 void CodingStructure::addEmptyTUs( Partitioner &partitioner )
 {
   const UnitArea& area    = partitioner.currArea();
-  bool            split   = partitioner.canSplit(TU_MAX_TR_SPLIT, *this);
+  bool            split   = partitioner.canSplit(TU_MAX_TR_SPLIT, *this
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif  
+  );
+
+
   const unsigned  trDepth = partitioner.currTrDepth;
 
   if( split )
diff --git a/source/Lib/CommonLib/CodingStructure.h b/source/Lib/CommonLib/CodingStructure.h
index a75e9e6b1df08fe6549c0083844408f4964abf4b..3385f27468227b89d1c1fe6ca07ba3fccf8ea88e 100644
--- a/source/Lib/CommonLib/CodingStructure.h
+++ b/source/Lib/CommonLib/CodingStructure.h
@@ -87,7 +87,9 @@ public:
   Slice           *slice;
 
   UnitScale        unitScale[MAX_NUM_COMPONENT];
-
+#if JVET_AI0087_BTCUS_RESTRICTION 
+  int         btFirstPartDecs[4];
+#endif
   int         baseQP;
   int         prevQP[MAX_NUM_CHANNEL_TYPE];
   int         currQP[MAX_NUM_CHANNEL_TYPE];
diff --git a/source/Lib/CommonLib/ContextModelling.cpp b/source/Lib/CommonLib/ContextModelling.cpp
index e22ef789058ead2278b4833862a9eeb2b3160bd8..cd14376d4e78989092f12946d212faf41521da41 100644
--- a/source/Lib/CommonLib/ContextModelling.cpp
+++ b/source/Lib/CommonLib/ContextModelling.cpp
@@ -237,7 +237,12 @@ unsigned DeriveCtx::CtxModeConsFlag( const CodingStructure& cs, Partitioner& par
 }
 #endif
 
-void DeriveCtx::CtxSplit( const CodingStructure& cs, Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, bool* _canSplit /*= nullptr */ )
+void DeriveCtx::CtxSplit( const CodingStructure& cs, Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, bool* _canSplit 
+#if JVET_AI0087_BTCUS_RESTRICTION
+  , bool disableBTV, bool disableBTH
+#endif
+
+/*= nullptr */ )
 {
   const Position pos         = partitioner.currArea().blocks[partitioner.chType];
   const unsigned curSliceIdx = cs.slice->getIndependentSliceIdx();
@@ -255,9 +260,17 @@ void DeriveCtx::CtxSplit( const CodingStructure& cs, Partitioner& partitioner, u
   {
 #if JVET_AH0135_TEMPORAL_PARTITIONING
     unsigned maxMtt;
-    partitioner.canSplit(cs, canSplit[0], canSplit[1], canSplit[2], canSplit[3], canSplit[4], canSplit[5], maxMtt);
+    partitioner.canSplit(cs, canSplit[0], canSplit[1], canSplit[2], canSplit[3], canSplit[4], canSplit[5], maxMtt
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
 #else
-    partitioner.canSplit( cs, canSplit[0], canSplit[1], canSplit[2], canSplit[3], canSplit[4], canSplit[5] );
+    partitioner.canSplit( cs, canSplit[0], canSplit[1], canSplit[2], canSplit[3], canSplit[4], canSplit[5]
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
 #endif
   }
   else
@@ -313,6 +326,13 @@ void DeriveCtx::CtxSplit( const CodingStructure& cs, Partitioner& partitioner, u
 
   ctxSpl += 3 * ( numSplit >> 1 );
 
+#if JVET_AI0087_BTCUS_RESTRICTION
+  if ((disableBTV || disableBTH) && partitioner.chType == CHANNEL_TYPE_LUMA)
+  {
+    ctxSpl = 9;
+  }
+#endif
+
   //////////////////////////
   // CTX is qt split (0-5)
   //////////////////////////
diff --git a/source/Lib/CommonLib/ContextModelling.h b/source/Lib/CommonLib/ContextModelling.h
index aca51b88109442903abeefe29b14e51e643e4697..a2ebe676d87bce93ba74ff861b478a399ba237a9 100644
--- a/source/Lib/CommonLib/ContextModelling.h
+++ b/source/Lib/CommonLib/ContextModelling.h
@@ -1194,7 +1194,11 @@ public:
 
 namespace DeriveCtx
 {
-void     CtxSplit     ( const CodingStructure& cs, Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, bool* canSplit = nullptr );
+void     CtxSplit     ( const CodingStructure& cs, Partitioner& partitioner, unsigned& ctxSpl, unsigned& ctxQt, unsigned& ctxHv, unsigned& ctxHorBt, unsigned& ctxVerBt, bool* canSplit = nullptr 
+#if JVET_AI0087_BTCUS_RESTRICTION
+  ,bool disableBTV = false, bool disableBTH = false
+#endif
+);
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
 unsigned CtxModeConsFlag( const CodingStructure& cs, Partitioner& partitioner );
 #endif
diff --git a/source/Lib/CommonLib/Contexts_ecm13.inl b/source/Lib/CommonLib/Contexts_ecm13.inl
index 40bcca860d181fdcb946754bb116bd5202773946..e2158e8eb1b92eb48493dd8467a3a9d3818eddcf 100644
--- a/source/Lib/CommonLib/Contexts_ecm13.inl
+++ b/source/Lib/CommonLib/Contexts_ecm13.inl
@@ -4,6 +4,29 @@
 // CONTEXTS WSA START
 const CtxSet ContextSetCfg::SplitFlag = ContextSetCfg::addCtxSet({
 // ctx 0 8
+#if JVET_AI0087_BTCUS_RESTRICTION
+ {  11,  20,  52,  19,  14,  30,  35,  30,  31, 14},
+ {  11,  20,  52,  12,  21,  30,  13,  15,  31, 21 },
+ {  27,  36,  38,  20,  29,  30,  28,  38,  31, 29},
+ {  11,  20,  52,   4,  14,  38,  28,  30,  31, 14 },
+ {   5,   6,   5,   5,  10,  13,   9,   7,  10, 10},
+ {   6,  10,  10,   5,  10,  13,  10,   7,  13, 10 },
+ {   9,   9,   9,   9,   9,  13,   6,   6,   9, 9},
+ {   5,   6,   6,   5,  10,  13,  10,   7,  13, 10 },
+ {   4,   4,  18,   4,   4,  11,  11,   4,  11, 4 },
+ {   4,  11,  25,   4,   4,  11,  11,   4,  11, 4 },
+ {  11,   4,  18,  11,   4,  18,  18,   4,  11, 4 },
+ {   4,   4,  18,   4,   4,  11,  11,   4,  11, 4 },
+ { 196, 152, 134, 246, 234, 234, 102, 130, 137, 234 },
+ { 140, 155, 107, 170, 250, 178, 230, 115,  85, 250},
+ { 195, 244, 131, 153, 250, 234, 106, 116, 148, 250},
+ { 169, 250, 106, 252, 250, 121, 234, 121,  83, 250},
+ { 163, 138, 150, 243, 187, 234, 107, 162, 181, 187},
+ { 251, 251,  84, 251, 251,  87, 117, 123,  84, 251},
+ { 196, 152, 133, 247, 250, 234, 106, 115, 164, 250},
+ { 137, 187, 118, 171, 250, 119, 216, 115,  82, 250},
+    });
+#else
  {  11,  20,  52,  19,  14,  30,  35,  30,  31 },
  {  11,  20,  52,  12,  21,  30,  13,  15,  31 },
  {  27,  36,  38,  20,  29,  30,  28,  38,  31 },
@@ -25,7 +48,7 @@ const CtxSet ContextSetCfg::SplitFlag = ContextSetCfg::addCtxSet({
  { 196, 152, 133, 247, 250, 234, 106, 115, 164 },
  { 137, 187, 118, 171, 250, 119, 216, 115,  82 },
 });
-
+#endif
 const CtxSet ContextSetCfg::SplitQtFlag = ContextSetCfg::addCtxSet({
 // ctx 9 14
  {  27,  22,  23,  11,  12,   6 },
diff --git a/source/Lib/CommonLib/Contexts_ecm14.0.inl b/source/Lib/CommonLib/Contexts_ecm14.0.inl
index 5e3bc38da798f973b4cfb8ccca13cee02c58e371..5b9830d97cad61ebe1ad25b29361f7e41a52ba98 100644
--- a/source/Lib/CommonLib/Contexts_ecm14.0.inl
+++ b/source/Lib/CommonLib/Contexts_ecm14.0.inl
@@ -4,6 +4,29 @@
 // CONTEXTS WSA START
 const CtxSet ContextSetCfg::SplitFlag = ContextSetCfg::addCtxSet({
 // ctx 0 8
+#if JVET_AI0087_BTCUS_RESTRICTION
+ {  18,  20,  52,  19,  21,  30,  42,  37,  31,  21 },
+ {  11,  20,  52,  19,   6,  30,   5,  22,  23,   6 },
+ {  27,  36,  38,  20,  29,  30,  28,  38,  31,  29 },
+ {  11,  20,  52,   4,   6,  30,  20,  30,  31,   6 },
+ {   5,   6,   7,   5,  10,  13,   8,   7,  13,  10 },
+ {   6,  10,  10,   5,  10,  13,  10,   7,  13,  10 },
+ {   9,   9,   9,   9,   9,   9,   6,   9,   9,   9 },
+ {   5,   6,   6,   5,  10,  13,   9,   7,  13,  10 },
+ {   4,  11,  25,  11,  11,  18,  11,  11,  11,  11 },
+ {   4,  11,  32,   4,   4,  11,  11,   4,  18,   4 },
+ {  11,   4,  18,  11,   4,   4,  18,  11,  11,   4 },
+ {   4,   4,  18,   4,  11,  18,  11,   4,  11,  11 },
+ { 212, 150, 133, 230, 245, 217, 101, 145, 194, 245 },
+ { 140, 133, 114, 172, 250, 117, 181, 120, 132, 250 },
+ { 211, 230, 209, 188, 250, 234, 101, 115, 115, 250 },
+ { 170, 234, 113, 203, 250, 229, 244, 118, 105, 250 },
+ { 163, 166, 151, 243, 186, 251, 101, 130, 165, 186 },
+ { 251, 251,  84, 251, 251,  91, 116, 147,  84, 251 },
+ { 212, 165, 133, 247, 183, 150, 115, 114, 131, 183 },
+ { 140, 155, 107, 171, 250, 216, 216, 115,  98, 250 },
+});
+#else
  {  18,  20,  52,  19,  21,  30,  42,  37,  31 },
  {  11,  20,  52,  19,   6,  30,   5,  22,  23 },
  {  27,  36,  38,  20,  29,  30,  28,  38,  31 },
@@ -25,6 +48,7 @@ const CtxSet ContextSetCfg::SplitFlag = ContextSetCfg::addCtxSet({
  { 212, 165, 133, 247, 183, 150, 115, 114, 131 },
  { 140, 155, 107, 171, 250, 216, 216, 115,  98 },
 });
+#endif
 
 const CtxSet ContextSetCfg::SplitQtFlag = ContextSetCfg::addCtxSet({
 // ctx 9 14
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index 79068fc9d56b8a563895506160b2090d1ab6ab0f..672c6de2331a460fc2757abffaeab1707725d0b9 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -94,6 +94,7 @@
 #if TU_256
 #define LMCS_CHROMA_CALC_CU                               1 // Derive chroma LMCS parameter based on neighbor CUs. Needed by VPDU removal and 128x128 transform.
 #endif
+#define JVET_AI0087_BTCUS_RESTRICTION                     1 // JVET-AI0087: Restriction on BT CUs from applying QT like partitioning structure
 
 //-- intra
 #define INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS             1 // Enable 2xN and Nx2 block by removing SCIPU constraints
diff --git a/source/Lib/CommonLib/UnitPartitioner.cpp b/source/Lib/CommonLib/UnitPartitioner.cpp
index 0df8d83b5463068d6df006f470bdfdd60aa028be..880c2f3a010987f09d394b458ddf3f792db03316 100644
--- a/source/Lib/CommonLib/UnitPartitioner.cpp
+++ b/source/Lib/CommonLib/UnitPartitioner.cpp
@@ -290,10 +290,19 @@ void QTBTPartitioner::initCtu( const UnitArea& ctuArea, const ChannelType _chTyp
 
 void QTBTPartitioner::splitCurrArea( const PartSplit split, const CodingStructure& cs )
 {
-  CHECKD( !canSplit( split, cs ), "Trying to apply a prohibited split!" );
+
+#if JVET_AI0087_BTCUS_RESTRICTION
+  CHECKD(!canSplit(split, cs, false, false), "Trying to apply a prohibited split!");
+#else
+  CHECKD(!canSplit(split, cs), "Trying to apply a prohibited split!");
+#endif
 
   bool isImplicit = isSplitImplicit( split, cs );
-  bool canQtSplit = canSplit( CU_QUAD_SPLIT, cs );
+  bool canQtSplit = canSplit( CU_QUAD_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
   bool qgEnable = currQgEnable();
   bool qgChromaEnable = currQgChromaEnable();
 
@@ -393,6 +402,9 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca
 #if JVET_AH0135_TEMPORAL_PARTITIONING
   , unsigned& maxMtt
 #endif
+#if JVET_AI0087_BTCUS_RESTRICTION
+  , bool disableBTV, bool disableBTH
+#endif
 )
 {
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
@@ -614,6 +626,18 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca
     canBh = canBv = false;
   }
 
+#if JVET_AI0087_BTCUS_RESTRICTION
+  if (disableBTV && (chType == CHANNEL_TYPE_LUMA))
+  {
+    canBv = false;
+  }
+
+  if (disableBTH && (chType == CHANNEL_TYPE_LUMA))
+  {
+    canBh = false;
+  }
+#endif
+
   // specific check for BT splits
   if( area.height <= minBtSize )                            canBh = false;
 #if !REMOVE_VPDU || CTU_256
@@ -666,7 +690,11 @@ void QTBTPartitioner::canSplit( const CodingStructure &cs, bool& canNo, bool& ca
 #endif
 }
 
-bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs )
+bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+  ,bool disableBTV, bool disableBTH
+#endif
+)
 {
   const CompArea area       = currArea().Y();
   const unsigned maxTrSize  = cs.sps->getMaxTbSize();
@@ -675,9 +703,17 @@ bool QTBTPartitioner::canSplit( const PartSplit split, const CodingStructure &cs
 
 #if JVET_AH0135_TEMPORAL_PARTITIONING
   unsigned maxMtt;
-  canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxMtt );
+  canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxMtt 
+#if JVET_AI0087_BTCUS_RESTRICTION
+   , disableBTV, disableBTH
+#endif
+  );
 #else
-  canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
+  canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  );
 #endif
   switch( split )
   {
@@ -964,7 +1000,11 @@ bool TUIntraSubPartitioner::hasNextPart()
   return ( ( m_partStack.back().idx + 1 ) < m_partStack.back().parts.size() );
 }
 
-bool TUIntraSubPartitioner::canSplit( const PartSplit split, const CodingStructure &cs )
+bool TUIntraSubPartitioner::canSplit( const PartSplit split, const CodingStructure &cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+  , bool disableBTV, bool disableBTH
+#endif
+)
 {
   //const PartSplit implicitSplit = getImplicitSplit(cs);
   const UnitArea &area = currArea();
diff --git a/source/Lib/CommonLib/UnitPartitioner.h b/source/Lib/CommonLib/UnitPartitioner.h
index 0e41fc0400c49eaf5a7a9cb769af7e622cdc3e5c..73ac1eb4568b84fb39d27f05a8adb3af48886c12 100644
--- a/source/Lib/CommonLib/UnitPartitioner.h
+++ b/source/Lib/CommonLib/UnitPartitioner.h
@@ -127,6 +127,9 @@ public:
   Position currQgPos;
   Position currQgChromaPos;
 
+#if JVET_AI0087_BTCUS_RESTRICTION 
+  int         btFirstPartDecs[4];
+#endif
   unsigned currImplicitBtDepth;
   ChannelType chType;
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
@@ -161,9 +164,16 @@ public:
 #if JVET_AH0135_TEMPORAL_PARTITIONING
     , unsigned& maxMtt
 #endif 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , bool disableBTV, bool disableBTH
+#endif
   ) = 0;
 
-  virtual bool canSplit                   ( const PartSplit split,                          const CodingStructure &cs ) = 0;
+  virtual bool canSplit                   ( const PartSplit split,                          const CodingStructure &cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , bool disableBTV, bool disableBTH
+#endif
+  ) = 0;
   virtual bool isSplitImplicit            ( const PartSplit split,                          const CodingStructure &cs ) = 0;
   virtual PartSplit getImplicitSplit      (                                                 const CodingStructure &cs ) = 0;
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
@@ -194,10 +204,17 @@ public:
   void canSplit                   ( const CodingStructure &cs, bool& canNo, bool& canQt, bool& canBh, bool& canBv, bool& canTh, bool& canTv 
 #if JVET_AH0135_TEMPORAL_PARTITIONING
     , unsigned& maxMtt
+#endif
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , bool disableBTV, bool disableBTH
 #endif
   );
 
-  bool canSplit                   ( const PartSplit split,                          const CodingStructure &cs );
+  bool canSplit                   ( const PartSplit split,                          const CodingStructure &cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , bool disableBTV, bool disableBTH
+#endif
+  );
   bool isSplitImplicit            ( const PartSplit split,                          const CodingStructure &cs );
   PartSplit getImplicitSplit      (                                                 const CodingStructure &cs );
 };
@@ -234,9 +251,17 @@ public:
 #if JVET_AH0135_TEMPORAL_PARTITIONING
     , unsigned& maxMtt
 #endif
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , bool disableBTV, bool disableBTH
+#endif
+
   ) {};
 
-  bool canSplit              (const PartSplit split, const CodingStructure &cs);
+  bool canSplit              (const PartSplit split, const CodingStructure &cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , bool disableBTV, bool disableBTH
+#endif
+  );
   bool isSplitImplicit       (const PartSplit split, const CodingStructure &cs) { return false; }; //not needed
   PartSplit getImplicitSplit (const CodingStructure &cs) { return CU_DONT_SPLIT; }; //not needed
 };
diff --git a/source/Lib/DecoderLib/CABACReader.cpp b/source/Lib/DecoderLib/CABACReader.cpp
index f4579c4429d6555784fbf7d5234b7c2be580451b..cf13edaa88ef1ea952bbb240c7d368505b841a20 100644
--- a/source/Lib/DecoderLib/CABACReader.cpp
+++ b/source/Lib/DecoderLib/CABACReader.cpp
@@ -138,6 +138,42 @@ bool CABACReader::terminating_bit()
   return false;
 }
 
+#if JVET_AI0087_BTCUS_RESTRICTION 
+bool CABACReader::isLumaNonBoundaryCu(const Partitioner& partitioner, SizeType picWidth, SizeType picHeight )
+{
+  bool validCU = false;
+  if (isLuma(partitioner.chType))
+  {
+    int maxWidthHeight = std::max(partitioner.currArea().lwidth(), partitioner.currArea().lheight()) - 1;
+    if ((partitioner.currArea().Y().x + maxWidthHeight < picWidth)
+      && (partitioner.currArea().Y().y + maxWidthHeight < picHeight))
+    {
+      validCU = true;
+    }
+  }
+  return validCU;
+}
+void CABACReader::setBtFirstPart(const Partitioner& partitioner, SizeType blockSize, CodingStructure& cs, PartSplit setValue)
+{
+  if (blockSize == 128)
+  {
+    cs.btFirstPartDecs[0] = setValue;
+  }
+  else if (blockSize == 64)
+  {
+    cs.btFirstPartDecs[1] = setValue;
+  }
+  else if (blockSize == 32)
+  {
+    cs.btFirstPartDecs[2] = setValue;
+  }
+  else if (blockSize == 16)
+  {
+    cs.btFirstPartDecs[3] = setValue;
+  }  
+}
+#endif
+
 void CABACReader::remaining_bytes( bool noTrailingBytesExpected )
 {
   if( noTrailingBytesExpected )
@@ -175,7 +211,10 @@ void CABACReader::coding_tree_unit( CodingStructure& cs, const UnitArea& area, i
 #endif
 
   partitioner.initCtu(area, CH_L, *cs.slice);
-#if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
+  #if JVET_AI0087_BTCUS_RESTRICTION 
+  std::memset(cs.btFirstPartDecs,0, sizeof(cs.btFirstPartDecs));
+#endif
+  #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
   cs.treeType = partitioner.treeType = TREE_D;
   cs.modeType = partitioner.modeType = MODE_TYPE_ALL;
 #endif
@@ -763,7 +802,11 @@ void CABACReader::coding_tree( CodingStructure& cs, Partitioner& partitioner, CU
 
   const PartSplit splitMode = split_cu_mode( cs, partitioner );
 
-  CHECK( !partitioner.canSplit( splitMode, cs ), "Got an invalid split!" );
+#if JVET_AI0087_BTCUS_RESTRICTION
+  CHECK(!partitioner.canSplit(splitMode, cs, false, false), "Got an invalid split!");
+#else
+  CHECK(!partitioner.canSplit(splitMode, cs), "Got an invalid split!");
+#endif
 
   if( splitMode != CU_DONT_SPLIT )
   {
@@ -1122,21 +1165,86 @@ ModeType CABACReader::mode_constraint( CodingStructure& cs, Partitioner &partiti
 PartSplit CABACReader::split_cu_mode( CodingStructure& cs, Partitioner &partitioner )
 {
   RExt__DECODER_DEBUG_BIT_STATISTICS_CREATE_SET_SIZE2( STATS__CABAC_BITS__SPLIT_FLAG, partitioner.currArea().blocks[partitioner.chType].size(), partitioner.chType );
+#if JVET_AI0087_BTCUS_RESTRICTION
+  bool disableBTV = false;
+  bool disableBTH = false;
 
+  if (CABACReader::isLumaNonBoundaryCu(partitioner, cs.picture->lwidth(), cs.picture->lheight()) && (!(cs.slice->getProcessingIntraRegion() && cs.slice->getProcessingSeparateTrees()) || cs.slice->isIntra()) )
+  {
+    if ((partitioner.currBtDepth == 0) && (partitioner.currArea().lwidth() == partitioner.currArea().lheight()))
+    {
+      CABACReader::setBtFirstPart(partitioner, partitioner.currArea().lwidth(), cs, CTU_LEVEL);
+    }
+
+    if ((partitioner.currBtDepth == 1) && (partitioner.currPartIdx() == 1))
+    {
+      if (partitioner.currPartLevel().split == CU_HORZ_SPLIT)
+      {
+        if (partitioner.currArea().lwidth() == 128 && cs.btFirstPartDecs[0] == CU_VERT_SPLIT)
+        {
+          disableBTV = true;
+        }
+        else if (partitioner.currArea().lwidth() == 64 && cs.btFirstPartDecs[1] == CU_VERT_SPLIT)
+        {
+          disableBTV = true;
+        }
+        else if (partitioner.currArea().lwidth() == 32 && cs.btFirstPartDecs[2] == CU_VERT_SPLIT)
+        {
+          disableBTV = true;
+        }
+        else if (partitioner.currArea().lwidth() == 16 && cs.btFirstPartDecs[3] == CU_VERT_SPLIT)
+        {
+          disableBTV = true;
+        }
+      }
+      else if (partitioner.currPartLevel().split == CU_VERT_SPLIT)   // BTV Case
+      {
+        if (partitioner.currArea().lheight() == 128 && cs.btFirstPartDecs[0] == CU_HORZ_SPLIT)
+        {
+          disableBTH = true;
+        }
+        else if (partitioner.currArea().lheight() == 64 && cs.btFirstPartDecs[1] == CU_HORZ_SPLIT)
+        {
+          disableBTH = true;
+        }
+        else if (partitioner.currArea().lheight() == 32 && cs.btFirstPartDecs[2] == CU_HORZ_SPLIT)
+        {
+          disableBTH = true;
+        }
+        else if (partitioner.currArea().lheight() == 16 && cs.btFirstPartDecs[3] == CU_HORZ_SPLIT)
+        {
+          disableBTH = true;
+        }
+      }
+    }
+  }
+#endif
   PartSplit mode = CU_DONT_SPLIT;
 
   bool canNo, canQt, canBh, canBv, canTh, canTv;
 #if JVET_AH0135_TEMPORAL_PARTITIONING
   unsigned maxMtt;
-  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxMtt );
+  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxMtt 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  );
 #else
-  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
+  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  );
 #endif
 
   bool canSpl[6] = { canNo, canQt, canBh, canBv, canTh, canTv };
 
   unsigned ctxSplit = 0, ctxQtSplit = 0, ctxBttHV = 0, ctxBttH12 = 0, ctxBttV12;
-  DeriveCtx::CtxSplit( cs, partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl );
+  DeriveCtx::CtxSplit( cs, partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  );
 
   bool isSplit = canBh || canBv || canTh || canTv || canQt;
 #if JVET_AH0135_TEMPORAL_PARTITIONING
@@ -1308,6 +1416,38 @@ PartSplit CABACReader::split_cu_mode( CodingStructure& cs, Partitioner &partitio
     mode = CU_TRIH_SPLIT;
   }
 
+#if JVET_AI0087_BTCUS_RESTRICTION
+  if (CABACReader::isLumaNonBoundaryCu(partitioner, cs.picture->lwidth(), cs.picture->lheight())
+      && (!(cs.slice->getProcessingIntraRegion() && cs.slice->getProcessingSeparateTrees()) || cs.slice->isIntra()))
+  {
+    if ((partitioner.currBtDepth == 1) && (partitioner.currPartIdx() == 0))
+    {
+      if (partitioner.currPartLevel().split == CU_HORZ_SPLIT)   // BTH Case
+      {
+        if (mode == CU_VERT_SPLIT)
+        {
+          CABACReader::setBtFirstPart(partitioner, partitioner.currArea().lwidth(), cs, CU_VERT_SPLIT);
+        }
+        else
+        {
+          CABACReader::setBtFirstPart(partitioner, partitioner.currArea().lwidth(), cs, CTU_LEVEL);
+        }
+      }
+      else if (partitioner.currPartLevel().split == CU_VERT_SPLIT)   // BTV Case
+      {
+        if (mode == CU_HORZ_SPLIT)
+        {
+          CABACReader::setBtFirstPart(partitioner, partitioner.currArea().lheight(), cs, CU_HORZ_SPLIT);
+        }
+        else
+        {
+          CABACReader::setBtFirstPart(partitioner, partitioner.currArea().lheight(), cs, CTU_LEVEL);
+        }
+      }
+    }
+  }
+#endif
+
   DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() pos=(%d,%d) size=%dx%d chType=%d ctxHv=%d ctx12=%d mode=%d\n", block.x, block.y, block.width, block.height, partitioner.chType, ctxBttHV, isVer ? ctxBttV12 : ctxBttH12, mode );
 
   return mode;
@@ -1781,8 +1921,16 @@ void CABACReader::separate_tree_cu_flag( CodingUnit& cu, Partitioner& partitione
   bool inferredSeparateTreeFlag = false;
   if ( cu.slice->getSeparateTreeEnabled() && CU::isIntra( cu ) && !cu.cs->slice->getProcessingIntraRegion() )
   {
-    bool canSplit = partitioner.canSplit(CU_QUAD_SPLIT, *cu.cs);
-    canSplit = canSplit || partitioner.canSplit( CU_MT_SPLIT, *cu.cs );
+    bool canSplit = partitioner.canSplit(CU_QUAD_SPLIT, *cu.cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
+    canSplit = canSplit || partitioner.canSplit( CU_MT_SPLIT, *cu.cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
 
     int separateTreeFlag = -1;
     cu.cs->deriveSeparateTreeFlagInference( separateTreeFlag, inferredSeparateTreeFlag, partitioner.currArea().lumaSize().width, partitioner.currArea().lumaSize().height, canSplit );
@@ -7316,22 +7464,38 @@ void CABACReader::transform_tree( CodingStructure &cs, Partitioner &partitioner,
   int       subTuCounter = subTuIdx;
 
   // split_transform_flag
-  bool split = partitioner.canSplit(TU_MAX_TR_SPLIT, cs);
+  bool split = partitioner.canSplit(TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
   const unsigned  trDepth = partitioner.currTrDepth;
 
-  if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
+  if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  ) )
   {
     split = true;
   }
 
   if( !split && cu.ispMode )
   {
-    split = partitioner.canSplit( ispType, cs );
+    split = partitioner.canSplit( ispType, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
   }
 
   if( split )
   {
-    if (partitioner.canSplit(TU_MAX_TR_SPLIT, cs))
+    if (partitioner.canSplit(TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ))
     {
 #if ENABLE_TRACING
       const CompArea &tuArea = partitioner.currArea().blocks[partitioner.chType];
@@ -7345,7 +7509,11 @@ void CABACReader::transform_tree( CodingStructure &cs, Partitioner &partitioner,
     {
       partitioner.splitCurrArea(ispType, cs);
     }
-    else if (cu.sbtInfo && partitioner.canSplit(PartSplit(cu.getSbtTuSplit()), cs))
+    else if (cu.sbtInfo && partitioner.canSplit(PartSplit(cu.getSbtTuSplit()), cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ))
     {
       partitioner.splitCurrArea(PartSplit(cu.getSbtTuSplit()), cs);
     }
diff --git a/source/Lib/DecoderLib/CABACReader.h b/source/Lib/DecoderLib/CABACReader.h
index 4bc58f2a2f788e9f7508e8a309f8365f262a8592..0696b2e94cf1ea9670cf7c78dd3f4255bfd2203b 100644
--- a/source/Lib/DecoderLib/CABACReader.h
+++ b/source/Lib/DecoderLib/CABACReader.h
@@ -70,6 +70,10 @@ public:
   const BinStoreVector *getBinBuffer()             const { return m_BinDecoder.getBinBuffer(); }
   void                  updateCtxs  (BinStoreVector *bb) { m_BinDecoder.updateCtxs(bb);        }
 #endif
+#if JVET_AI0087_BTCUS_RESTRICTION
+  bool         isLumaNonBoundaryCu      (const Partitioner& partitioner, SizeType picWidth, SizeType picHeight);
+  void         setBtFirstPart           (const Partitioner& partitioner, SizeType blockSize, CodingStructure& cs, PartSplit setValue);
+#endif
 
 public:
   // slice segment data (clause 7.3.8.1)
diff --git a/source/Lib/EncoderLib/CABACWriter.cpp b/source/Lib/EncoderLib/CABACWriter.cpp
index 986e8b933b6d3116eaaacb6f891236257bc21721..9052734e8de62b6bf543355c248039a9ebcf3417 100644
--- a/source/Lib/EncoderLib/CABACWriter.cpp
+++ b/source/Lib/EncoderLib/CABACWriter.cpp
@@ -139,6 +139,42 @@ SliceType xGetCtxInitId( const Slice& slice, const BinEncIf& binEncoder, Ctx& ct
   }
 }
 
+#if JVET_AI0087_BTCUS_RESTRICTION 
+bool CABACWriter::isLumaNonBoundaryCu(const Partitioner& partitioner, SizeType picWidth, SizeType picHeight)
+{
+  bool validCU = false;
+  if (isLuma(partitioner.chType))
+  {
+    int maxWidthHeight = std::max(partitioner.currArea().lwidth(), partitioner.currArea().lheight()) - 1;
+    if ((partitioner.currArea().Y().x + maxWidthHeight < picWidth)
+      && (partitioner.currArea().Y().y + maxWidthHeight < picHeight))
+    {
+      validCU = true;
+    }
+  }
+  return validCU;
+}
+
+void CABACWriter::setBtFirstPart(Partitioner& partitioner, SizeType blockSize, PartSplit setValue)
+{
+  if (blockSize == 128)
+  {
+    partitioner.btFirstPartDecs[0] = setValue;
+  }
+  else if (blockSize == 64)
+  {
+    partitioner.btFirstPartDecs[1] = setValue;
+  }
+  else if (blockSize == 32)
+  {
+    partitioner.btFirstPartDecs[2] = setValue;
+  }
+  else if (blockSize == 16)
+  {
+    partitioner.btFirstPartDecs[3] = setValue;
+  }
+}
+#endif
 
 SliceType CABACWriter::getCtxInitId( const Slice& slice )
 {
@@ -598,14 +634,21 @@ void CABACWriter::coding_tree(const CodingStructure& cs, Partitioner& partitione
 #endif
 
   const PartSplit splitMode = CU::getSplitAtDepth( cu, partitioner.currDepth );
-
+  split_cu_mode(splitMode, cs, partitioner
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
-  split_cu_mode( splitMode, cs, partitioner, &cu);
+    , & cu
+#endif
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , true
+#endif
+  );
+
+#if JVET_AI0087_BTCUS_RESTRICTION
+  CHECK(!partitioner.canSplit(splitMode, cs, false, false), "The chosen split mode is invalid!");
 #else
-  split_cu_mode( splitMode, cs, partitioner);
+  CHECK(!partitioner.canSplit(splitMode, cs), "The chosen split mode is invalid!");
 #endif
 
-  CHECK( !partitioner.canSplit( splitMode, cs ), "The chosen split mode is invalid!" );
 
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
   if( splitMode != CU_DONT_SPLIT && ( cs.slice->getProcessingIntraRegion() || !CU::isIntraRegionRoot( cu, partitioner ) ) )
@@ -829,25 +872,140 @@ void CABACWriter::mode_constraint( const PartSplit split, const CodingStructure&
   }
 }
 #endif
-
+void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner 
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
-void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner, const CodingUnit* cu )
-#else
-void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& cs, Partitioner& partitioner )
+  , const CodingUnit* cu
 #endif
+#if JVET_AI0087_BTCUS_RESTRICTION
+  , bool updatePartInfo
+#endif
+)
 {
+#if JVET_AI0087_BTCUS_RESTRICTION
+  bool disableBTV = false;
+  bool disableBTH = false;
+
+  if (CABACWriter::isLumaNonBoundaryCu(partitioner, cs.picture->lwidth(), cs.picture->lheight()) && (!(cs.slice->getProcessingIntraRegion() && cs.slice->getProcessingSeparateTrees()) || cs.slice->isIntra()) )
+  {
+    if ((partitioner.currBtDepth == 0) && (partitioner.currArea().lwidth() == partitioner.currArea().lheight()))
+    {
+      if (updatePartInfo)
+      {
+        CABACWriter::setBtFirstPart(partitioner, partitioner.currArea().lwidth(), CTU_LEVEL);
+      }
+    }
+
+    if ((partitioner.currBtDepth == 1) && (partitioner.currPartIdx() == 1))
+    {
+      if (partitioner.currPartLevel().split == CU_HORZ_SPLIT)   // BTH Case
+      {
+        if (updatePartInfo)
+        {
+          if (partitioner.currArea().lwidth() == 128 && partitioner.btFirstPartDecs[0] == CU_VERT_SPLIT)
+          {
+            disableBTV = true;
+          }
+          else if (partitioner.currArea().lwidth() == 64 && partitioner.btFirstPartDecs[1] == CU_VERT_SPLIT)
+          {
+            disableBTV = true;
+          }
+          else if (partitioner.currArea().lwidth() == 32 && partitioner.btFirstPartDecs[2] == CU_VERT_SPLIT)
+          {
+            disableBTV = true;
+          }
+          else if (partitioner.currArea().lwidth() == 16 && partitioner.btFirstPartDecs[3] == CU_VERT_SPLIT)
+          {
+            disableBTV = true;
+          }
+        }
+        else
+        {
+          if (partitioner.currArea().lwidth() == 128 && cs.btFirstPartDecs[0] == CU_VERT_SPLIT)
+          {
+            disableBTV = true;
+          }
+          else if (partitioner.currArea().lwidth() == 64 && cs.btFirstPartDecs[1] == CU_VERT_SPLIT)
+          {
+            disableBTV = true;
+          }
+          else if (partitioner.currArea().lwidth() == 32 && cs.btFirstPartDecs[2] == CU_VERT_SPLIT)
+          {
+            disableBTV = true;
+          }
+          else if (partitioner.currArea().lwidth() == 16 && cs.btFirstPartDecs[3] == CU_VERT_SPLIT)
+          {
+            disableBTV = true;
+          }
+        }
+      }
+      else if (partitioner.currPartLevel().split == CU_VERT_SPLIT)   // BTV Case
+      {
+        if (updatePartInfo)
+        {
+          if (partitioner.currArea().lheight() == 128 && partitioner.btFirstPartDecs[0] == CU_HORZ_SPLIT)
+          {
+            disableBTH = true;
+          }
+          else if (partitioner.currArea().lheight() == 64 && partitioner.btFirstPartDecs[1] == CU_HORZ_SPLIT)
+          {
+            disableBTH = true;
+          }
+          else if (partitioner.currArea().lheight() == 32 && partitioner.btFirstPartDecs[2] == CU_HORZ_SPLIT)
+          {
+            disableBTH = true;
+          }
+          else if (partitioner.currArea().lheight() == 16 && partitioner.btFirstPartDecs[3] == CU_HORZ_SPLIT)
+          {
+            disableBTH = true;
+          }
+        }
+        else
+        {
+          if (partitioner.currArea().lheight() == 128 && cs.btFirstPartDecs[0] == CU_HORZ_SPLIT)
+          {
+            disableBTH = true;
+          }
+          else if (partitioner.currArea().lheight() == 64 && cs.btFirstPartDecs[1] == CU_HORZ_SPLIT)
+          {
+            disableBTH = true;
+          }
+          else if (partitioner.currArea().lheight() == 32 && cs.btFirstPartDecs[2] == CU_HORZ_SPLIT)
+          {
+            disableBTH = true;
+          }
+          else if (partitioner.currArea().lheight() == 16 && cs.btFirstPartDecs[3] == CU_HORZ_SPLIT)
+          {
+            disableBTH = true;
+          }
+        }
+      }
+    }
+  }
+#endif
   bool canNo, canQt, canBh, canBv, canTh, canTv;
 #if JVET_AH0135_TEMPORAL_PARTITIONING
   unsigned maxMtt;
-  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxMtt );
+  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxMtt 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  );
 #else
-  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv );
+  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  );
 #endif
 
   bool canSpl[6] = { canNo, canQt, canBh, canBv, canTh, canTv };
 
   unsigned ctxSplit = 0, ctxQtSplit = 0, ctxBttHV = 0, ctxBttH12 = 0, ctxBttV12;
-  DeriveCtx::CtxSplit( cs, partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl );
+  DeriveCtx::CtxSplit( cs, partitioner, ctxSplit, ctxQtSplit, ctxBttHV, ctxBttH12, ctxBttV12, canSpl 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  );
 
   const bool canSplit = canBh || canBv || canTh || canTv || canQt;
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
@@ -985,6 +1143,37 @@ void CABACWriter::split_cu_mode( const PartSplit split, const CodingStructure& c
     m_BinEncoder.encodeBin( is12, Ctx::Split12Flag( isVer ? ctxBttV12 : ctxBttH12 ) );
   }
 
+#if JVET_AI0087_BTCUS_RESTRICTION
+  if (CABACWriter::isLumaNonBoundaryCu(partitioner, cs.picture->lwidth(), cs.picture->lheight())
+      && (!(cs.slice->getProcessingIntraRegion() && cs.slice->getProcessingSeparateTrees()) || cs.slice->isIntra()))
+  {
+    if (updatePartInfo && (partitioner.currBtDepth == 1) && (partitioner.currPartIdx() == 0))
+    {
+      if (partitioner.currPartLevel().split == CU_HORZ_SPLIT)   // BTH Case
+      {
+        if (split == CU_VERT_SPLIT)
+        {
+          CABACWriter::setBtFirstPart(partitioner, partitioner.currArea().lwidth(), CU_VERT_SPLIT);
+        }
+        else
+        {
+          CABACWriter::setBtFirstPart(partitioner, partitioner.currArea().lwidth(), CTU_LEVEL);
+        }
+      }
+      else if (partitioner.currPartLevel().split == CU_VERT_SPLIT)   // BTV Case
+      {
+        if (split == CU_HORZ_SPLIT)
+        {
+          CABACWriter::setBtFirstPart(partitioner, partitioner.currArea().lheight(), CU_HORZ_SPLIT);
+        }
+        else
+        {
+          CABACWriter::setBtFirstPart(partitioner, partitioner.currArea().lheight(), CTU_LEVEL);
+        }
+      }
+    }
+  }
+#endif
   DTRACE( g_trace_ctx, D_SYNTAX, "split_cu_mode() pos=(%d,%d) size=%dx%d chType=%d ctxHv=%d ctx12=%d mode=%d\n", block.x, block.y, block.width, block.height, partitioner.chType, ctxBttHV, isVer ? ctxBttV12 : ctxBttH12, split);
 }
 
@@ -1291,8 +1480,16 @@ void CABACWriter::separate_tree_cu_flag( const CodingUnit& cu, Partitioner& part
   if ( cu.slice->getSeparateTreeEnabled() && !cu.slice->getProcessingIntraRegion() && CU::isIntra( cu ) && CU::isIntraRegionRoot( cu, partitioner ) )
 #endif
   {
-    bool canSplit = partitioner.canSplit( CU_QUAD_SPLIT, *cu.cs );
-    canSplit = canSplit || partitioner.canSplit( CU_MT_SPLIT, *cu.cs );
+    bool canSplit = partitioner.canSplit( CU_QUAD_SPLIT, *cu.cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
+    canSplit = canSplit || partitioner.canSplit( CU_MT_SPLIT, *cu.cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
     cu.cs->determineIfSeparateTreeFlagInferred( inferredSeparateTreeFlag, partitioner.currArea().lumaSize().width, partitioner.currArea().lumaSize().height, canSplit );
 
     if ( !inferredSeparateTreeFlag )
@@ -7124,11 +7321,19 @@ void CABACWriter::transform_tree(const CodingStructure& cs, Partitioner& partiti
   const bool            split = (tu.depth > trDepth);
 
   // split_transform_flag
-  if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+  if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  ) )
   {
     CHECK( !split, "transform split implied" );
   }
-  else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
+  else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  ) )
   {
     CHECK( !split, "transform split implied - sbt" );
   }
@@ -7139,7 +7344,11 @@ void CABACWriter::transform_tree(const CodingStructure& cs, Partitioner& partiti
   if( split )
   {
 
-    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
 #if ENABLE_TRACING
       const CompArea &tuArea = partitioner.currArea().blocks[partitioner.chType];
@@ -7152,7 +7361,11 @@ void CABACWriter::transform_tree(const CodingStructure& cs, Partitioner& partiti
     {
       partitioner.splitCurrArea( ispType, cs );
     }
-    else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
+    else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
       partitioner.splitCurrArea( PartSplit( cu.getSbtTuSplit() ), cs );
     }
diff --git a/source/Lib/EncoderLib/CABACWriter.h b/source/Lib/EncoderLib/CABACWriter.h
index 26fb5603c05889b307d8953d1d1fbc1d0ee1168b..2460594cac40f5c775af998b4dddd3ff50039de5 100644
--- a/source/Lib/EncoderLib/CABACWriter.h
+++ b/source/Lib/EncoderLib/CABACWriter.h
@@ -64,9 +64,13 @@ public:
 
 public:
 #if JVET_AG0196_CABAC_RETRAIN
-  void        initCtxModels             ( Slice&                  slice );
+  void initCtxModels(Slice &slice);
 #else
-  void        initCtxModels             ( const Slice&                  slice );
+  void        initCtxModels(const Slice &slice);
+#endif
+#if JVET_AI0087_BTCUS_RESTRICTION
+  bool         isLumaNonBoundaryCu(const Partitioner& partitioner, SizeType picWidth, SizeType picHeight);
+  void         setBtFirstPart(Partitioner& partitioner, SizeType blockSize, PartSplit setValue);
 #endif
   void        setEncCu(EncCu* pcEncCu) { m_EncCu = pcEncCu; }
   SliceType   getCtxInitId              ( const Slice&                  slice );
@@ -109,10 +113,18 @@ public:
   // coding (quad)tree (clause 7.3.8.4)
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
   void        coding_tree               ( const CodingStructure&        cs,       Partitioner&      pm,         CUCtx& cuCtx, int (&qps)[2], Partitioner* pPartitionerChroma = nullptr, CUCtx* pCuCtxChroma = nullptr);
-  void        split_cu_mode             ( const PartSplit               split,    const CodingStructure& cs,    Partitioner& pm,    const CodingUnit* cu );
+  void        split_cu_mode             ( const PartSplit               split,    const CodingStructure& cs,     Partitioner& pm, const CodingUnit* cu
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , bool btUpdateInfo
+#endif
+  );
 #else
   void        coding_tree               ( const CodingStructure&        cs,       Partitioner&      pm,         CUCtx& cuCtx, Partitioner* pPartitionerChroma = nullptr, CUCtx* pCuCtxChroma = nullptr);
-  void        split_cu_mode             ( const PartSplit               split,    const CodingStructure& cs,    Partitioner& pm );
+  void        split_cu_mode             ( const PartSplit               split,    const CodingStructure& cs,    Partitioner& pm
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , bool btUpdateInfo
+#endif
+  );
 #endif
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
   void        mode_constraint           ( const PartSplit               split,    const CodingStructure& cs,    Partitioner& pm,    const ModeType modeType );
diff --git a/source/Lib/EncoderLib/EncCu.cpp b/source/Lib/EncoderLib/EncCu.cpp
index bb3a6eee125d801e1754e7d6110ffd79d7452381..bd7942a254a8b7311fb032c011863dad080ce420 100644
--- a/source/Lib/EncoderLib/EncCu.cpp
+++ b/source/Lib/EncoderLib/EncCu.cpp
@@ -878,6 +878,119 @@ int  EncCu::updateCtuDataISlice(const CPelBuf buf)
   return( iSumHad );
 }
 
+#if JVET_AI0087_BTCUS_RESTRICTION
+bool EncCu::isLumaNonBoundaryCu(const Partitioner &partitioner, SizeType picWidth, SizeType picHeight)
+{
+  bool validCU = false;
+  if (isLuma(partitioner.chType))
+  {
+    int maxWidthHeight = std::max(partitioner.currArea().lwidth(), partitioner.currArea().lheight()) - 1;
+    if ((partitioner.currArea().Y().x + maxWidthHeight < picWidth)
+        && (partitioner.currArea().Y().y + maxWidthHeight < picHeight))
+    {
+      validCU = true;
+    }
+  }
+  return validCU;
+}
+bool EncCu::xStoreRDcostandPredMode(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode &encTestMode, double lastModeBestCost)
+{
+  if (EncCu::isLumaNonBoundaryCu(partitioner, bestCS->picture->lwidth(), bestCS->picture->lheight())
+      && (!(bestCS->slice->getProcessingIntraRegion() && bestCS->slice->getProcessingSeparateTrees())
+          || bestCS->slice->isIntra()))
+  {
+    bool PrevbestCostisChangedtoNewBestCost = (lastModeBestCost != bestCS->cost);
+    if ((partitioner.currBtDepth == 1) && (partitioner.currPartIdx() == 0) && PrevbestCostisChangedtoNewBestCost)
+    {
+      if (partitioner.currPartLevel().split == CU_HORZ_SPLIT
+          || partitioner.currPartLevel().split == CU_VERT_SPLIT)   // BTH or BTV Case
+      {
+        if (partitioner.currPartLevel().split == CU_HORZ_SPLIT)
+        {
+          if (partitioner.currArea().lwidth() == 128)
+          {
+            bestCS->btFirstPartDecs[0] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+            tempCS->btFirstPartDecs[0] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+          }
+          else if (partitioner.currArea().lwidth() == 64)
+          {
+            bestCS->btFirstPartDecs[1] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+            tempCS->btFirstPartDecs[1] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+          }
+          else if (partitioner.currArea().lwidth() == 32)
+          {
+            bestCS->btFirstPartDecs[2] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+            tempCS->btFirstPartDecs[2] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+          }
+          else if (partitioner.currArea().lwidth() == 16)
+          {
+            bestCS->btFirstPartDecs[3] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+            tempCS->btFirstPartDecs[3] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+          }
+        }
+        else
+        {
+          if (partitioner.currArea().lheight() == 128)
+          {
+            bestCS->btFirstPartDecs[0] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+            tempCS->btFirstPartDecs[0] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+          }
+          else if (partitioner.currArea().lheight() == 64)
+          {
+            bestCS->btFirstPartDecs[1] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+            tempCS->btFirstPartDecs[1] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+          }
+          else if (partitioner.currArea().lheight() == 32)
+          {
+            bestCS->btFirstPartDecs[2] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+            tempCS->btFirstPartDecs[2] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+          }
+          else if (partitioner.currArea().lheight() == 16)
+          {
+            bestCS->btFirstPartDecs[3] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+            tempCS->btFirstPartDecs[3] = encTestMode.type == ETM_SPLIT_BT_H
+                                           ? CU_HORZ_SPLIT
+                                           : (encTestMode.type == ETM_SPLIT_BT_V ? CU_VERT_SPLIT : 0);
+          }
+        }
+      }
+    }
+  }
+
+  return true;
+}
+#endif
+
 bool EncCu::xCheckBestMode( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &partitioner, const EncTestMode& encTestMode )
 {
   bool bestCSUpdated = false;
@@ -1345,6 +1458,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 
     if( currTestMode.type == ETM_INTER_ME )
     {
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
 #if ENABLE_OBMC
       bool tryObmc = true;
 #if JVET_AA0129_INTERHASH_OBMCOFF_RD
@@ -1365,6 +1481,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
           tryObmc = xCheckRDCostInterIMV(tempCS, bestCS, partitioner, currTestMode, bestIntPelCost);
 #else
           xCheckRDCostInterIMV(tempCS, bestCS, partitioner, currTestMode, bestIntPelCost);
+#endif
+#if JVET_AI0087_BTCUS_RESTRICTION 
+          xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
 #endif
           tempCS->bestCS = nullptr;
 #if JVET_Y0152_TT_ENC_SPEEDUP
@@ -1380,6 +1499,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
         tryObmc = xCheckRDCostInter(tempCS, bestCS, partitioner, currTestMode);
 #else
         xCheckRDCostInter( tempCS, bestCS, partitioner, currTestMode );
+#endif
+#if JVET_AI0087_BTCUS_RESTRICTION 
+        xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
 #endif
         tempCS->bestCS = nullptr;
 #if JVET_Y0152_TT_ENC_SPEEDUP
@@ -1400,6 +1522,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
     }
     else if (currTestMode.type == ETM_HASH_INTER)
     {
+#if JVET_AI0087_BTCUS_RESTRICTION
+      double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
 #if ENABLE_OBMC && JVET_AA0129_INTERHASH_OBMCOFF_RD
       bool tryObmc = xCheckRDCostHashInter( tempCS, bestCS, partitioner, currTestMode );
 #else
@@ -1414,6 +1539,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
       {
         xCheckRDCostInterWoOBMC(  tempCS, bestCS, partitioner, currTestMode );
       }
+#endif
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
 #endif
     }
 #if !MERGE_ENC_OPT
@@ -1449,7 +1577,13 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #if REUSE_CU_RESULTS
     else if( currTestMode.type == ETM_RECO_CACHED )
     {
+#if JVET_AI0087_BTCUS_RESTRICTION 
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
       xReuseCachedResult( tempCS, bestCS, partitioner );
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 #if JVET_Y0152_TT_ENC_SPEEDUP
       splitRdCostBest[CTU_LEVEL] = bestCS->cost;
       tempCS->splitRdCostBest = splitRdCostBest;
@@ -1458,7 +1592,13 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #endif
     else if( currTestMode.type == ETM_MERGE_SKIP )
     {
+#if JVET_AI0087_BTCUS_RESTRICTION 
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
       xCheckRDCostMerge2Nx2N( tempCS, bestCS, partitioner, currTestMode );
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 
       CodingUnit* cu = bestCS->getCU(partitioner.chType);
 
@@ -1471,6 +1611,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
     }
     else if( currTestMode.type == ETM_MERGE_GEO )
     {
+#if JVET_AI0087_BTCUS_RESTRICTION 
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
 #if JVET_W0097_GPM_MMVD_TM
       CodedCUInfo    &relatedCU = ((EncModeCtrlMTnoRQT *)m_modeCtrl)->getBlkInfo(partitioner.currArea());
       if (!relatedCU.isGPMTested)
@@ -1485,6 +1628,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #else
       xCheckRDCostMergeGeo2Nx2N( tempCS, bestCS, partitioner, currTestMode );
 #endif
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 #if JVET_Y0152_TT_ENC_SPEEDUP
       splitRdCostBest[CTU_LEVEL] = bestCS->cost;
       tempCS->splitRdCostBest = splitRdCostBest;
@@ -1493,7 +1639,13 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #if MULTI_HYP_PRED
     else if (currTestMode.type == ETM_INTER_MULTIHYP)
     {
+#if JVET_AI0087_BTCUS_RESTRICTION
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
       xCheckRDCostInterMultiHyp2Nx2N(tempCS, bestCS, partitioner, currTestMode);
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 #if JVET_Y0152_TT_ENC_SPEEDUP
       splitRdCostBest[CTU_LEVEL] = bestCS->cost;
       tempCS->splitRdCostBest = splitRdCostBest;
@@ -1502,6 +1654,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #endif
     else if( currTestMode.type == ETM_INTRA )
     {
+#if JVET_AI0087_BTCUS_RESTRICTION
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
       if (slice.getSPS()->getUseColorTrans() && !CS::isDualITree(*tempCS))
       {
         bool skipSecColorSpace = false;
@@ -1548,7 +1703,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
         }
       }
 #endif
-
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 #if JVET_Y0152_TT_ENC_SPEEDUP
       splitRdCostBest[CTU_LEVEL] = bestCS->cost;
       tempCS->splitRdCostBest = splitRdCostBest;
@@ -1557,8 +1714,16 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
     else if( currTestMode.type == ETM_SEPARATE_TREE_INTRA )
     {
+#if JVET_AI0087_BTCUS_RESTRICTION
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
       xCheckRDCostSeparateTreeIntra( tempCS, bestCS, partitioner, currTestMode );
 
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
+
+
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
 #if JVET_Z0118_GDR
       if (bestCS->cus.size() > 0 && splitmode != bestCS->cus[0]->splitSeries)
@@ -1582,7 +1747,13 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
 #endif
     else if (currTestMode.type == ETM_PALETTE)
     {
+#if JVET_AI0087_BTCUS_RESTRICTION 
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
       xCheckPLT( tempCS, bestCS, partitioner, currTestMode );
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 #if JVET_Y0152_TT_ENC_SPEEDUP
       splitRdCostBest[CTU_LEVEL] = bestCS->cost;
       tempCS->splitRdCostBest = splitRdCostBest;
@@ -1590,6 +1761,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
     }
     else if (currTestMode.type == ETM_IBC)
     {
+#if JVET_AI0087_BTCUS_RESTRICTION 
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
 #if JVET_AA0070_RRIBC
       if (m_pcEncCfg->getIntraPeriod() <= 1)
       {
@@ -1607,6 +1781,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
       else
 #endif
       xCheckRDCostIBCMode(tempCS, bestCS, partitioner, currTestMode);
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 #if JVET_Y0152_TT_ENC_SPEEDUP
       splitRdCostBest[CTU_LEVEL] = bestCS->cost;
       tempCS->splitRdCostBest = splitRdCostBest;
@@ -1614,10 +1791,16 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
     }
     else if (currTestMode.type == ETM_IBC_MERGE)
     {
+#if JVET_AI0087_BTCUS_RESTRICTION 
+    double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
 #if JVET_AE0169_BIPREDICTIVE_IBC
       if (!m_skipIbcMerge)
 #endif
       xCheckRDCostIBCModeMerge2Nx2N(tempCS, bestCS, partitioner, currTestMode);
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 #if JVET_Y0152_TT_ENC_SPEEDUP
       splitRdCostBest[CTU_LEVEL] = bestCS->cost;
       tempCS->splitRdCostBest = splitRdCostBest;
@@ -1629,6 +1812,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
       {
         splitmode = bestCS->cus[0]->splitSeries;
       }
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      double lastModeBestCost = bestCS->cost == MAX_DOUBLE ? MAX_DOUBLE : bestCS->cost;
+#endif
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
       assert( partitioner.modeType == tempCS->modeType );
       int signalModeConsVal = tempCS->signalModeCons( getPartSplit( currTestMode ), partitioner, modeTypeParent );
@@ -1682,6 +1868,9 @@ void EncCu::xCompressCU( CodingStructure*& tempCS, CodingStructure*& bestCS, Par
       xCheckModeSplit(tempCS, bestCS, partitioner, currTestMode);
 #endif
 #endif
+#if JVET_AI0087_BTCUS_RESTRICTION 
+      xStoreRDcostandPredMode(tempCS, bestCS, partitioner, currTestMode, lastModeBestCost);
+#endif
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
         //recover cons modes
         tempCS->modeType = partitioner.modeType = modeTypeParent;
@@ -2305,9 +2494,17 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
 
   m_CABACEstimator->resetBits();
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
-  m_CABACEstimator->split_cu_mode( split, *tempCS, partitioner, nullptr );
+  m_CABACEstimator->split_cu_mode( split, *tempCS, partitioner, nullptr
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false
+#endif
+  );
 #else
-  m_CABACEstimator->split_cu_mode( split, *tempCS, partitioner );
+  m_CABACEstimator->split_cu_mode(split, *tempCS, partitioner
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false
+#endif
+  );
 #endif
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
   m_CABACEstimator->mode_constraint( split, *tempCS, partitioner, modeTypeChild );
@@ -2401,6 +2598,66 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
         }
       }
 #endif 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      if (EncCu::isLumaNonBoundaryCu(partitioner, bestCS->picture->lwidth(), bestCS->picture->lheight())
+          && (!(bestCS->slice->getProcessingIntraRegion() && bestCS->slice->getProcessingSeparateTrees())
+              || bestCS->slice->isIntra()))
+      {
+        if (partitioner.currPartLevel().split == CU_HORZ_SPLIT
+            || partitioner.currPartLevel().split == CU_VERT_SPLIT)   // BTH or BTV Case
+        {
+          if ((partitioner.currBtDepth == 1) && (partitioner.currPartIdx() == 0))
+          {
+            if (partitioner.currPartLevel().split == CU_HORZ_SPLIT)
+            {
+              if (partitioner.currArea().lwidth() == 128)
+              {
+                tempCS->btFirstPartDecs[0] = 0;
+                bestCS->btFirstPartDecs[0] = 0;
+              }
+              else if (partitioner.currArea().lwidth() == 64)
+              {
+                tempCS->btFirstPartDecs[1] = 0;
+                bestCS->btFirstPartDecs[1] = 0;
+              }
+              else if (partitioner.currArea().lwidth() == 32)
+              {
+                tempCS->btFirstPartDecs[2] = 0;
+                bestCS->btFirstPartDecs[2] = 0;
+              }
+              else if (partitioner.currArea().lwidth() == 16)
+              {
+                tempCS->btFirstPartDecs[3] = 0;
+                bestCS->btFirstPartDecs[3] = 0;
+              }
+            }
+            else
+            {
+              if (partitioner.currArea().lheight() == 128)
+              {
+                tempCS->btFirstPartDecs[0] = 0;
+                bestCS->btFirstPartDecs[0] = 0;
+              }
+              else if (partitioner.currArea().lheight() == 64)
+              {
+                tempCS->btFirstPartDecs[1] = 0;
+                bestCS->btFirstPartDecs[1] = 0;
+              }
+              else if (partitioner.currArea().lheight() == 32)
+              {
+                tempCS->btFirstPartDecs[2] = 0;
+                bestCS->btFirstPartDecs[2] = 0;
+              }
+              if (partitioner.currArea().lheight() == 16)
+              {
+                tempCS->btFirstPartDecs[3] = 0;
+                bestCS->btFirstPartDecs[3] = 0;
+              }
+            }
+          }
+        }
+      }
+#endif
       tempCS->initSubStructure( *tempSubCS, partitioner.chType, subCUArea, false );
       tempCS->initSubStructure( *bestSubCS, partitioner.chType, subCUArea, false );
       tempSubCS->bestParent = bestSubCS->bestParent = bestCS;
@@ -2628,9 +2885,17 @@ void EncCu::xCheckModeSplit(CodingStructure *&tempCS, CodingStructure *&bestCS,
       m_CABACEstimator->resetBits();
 
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
-      m_CABACEstimator->split_cu_mode( split, *tempCS, partitioner, nullptr );
+      m_CABACEstimator->split_cu_mode(split, *tempCS, partitioner, nullptr
+#if JVET_AI0087_BTCUS_RESTRICTION
+        , false
+#endif
+      );
 #else
-      m_CABACEstimator->split_cu_mode( split, *tempCS, partitioner );
+      m_CABACEstimator->split_cu_mode(split, *tempCS, partitioner
+#if JVET_AI0087_BTCUS_RESTRICTION
+        , false
+#endif
+      );
 #endif
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
       partitioner.modeType = modeTypeParent;
@@ -2723,8 +2988,16 @@ void EncCu::xCheckRDCostSeparateTreeIntra( CodingStructure *&tempCS, CodingStruc
   int startFlagVal     = 0;
   int endFlagVal       = 1;
   int inferredFlagVal  = -1;
-  bool canSplit        = partitioner.canSplit( CU_QUAD_SPLIT, *tempCS );
-  canSplit             = canSplit || partitioner.canSplit( CU_MT_SPLIT, *tempCS );
+  bool canSplit        = partitioner.canSplit( CU_QUAD_SPLIT, *tempCS 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
+  canSplit             = canSplit || partitioner.canSplit( CU_MT_SPLIT, *tempCS 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
 
   tempCS->deriveSeparateTreeFlagInference( inferredFlagVal, inferredSeparateTreeFlag, partitioner.currArea().lwidth(), partitioner.currArea().lheight(), canSplit );
   if ( inferredSeparateTreeFlag )
@@ -23634,11 +23907,14 @@ void EncCu::xEncodeInterResidual(   CodingStructure *&tempCS
 void EncCu::xEncodeDontSplit( CodingStructure &cs, Partitioner &partitioner )
 {
   m_CABACEstimator->resetBits();
+  m_CABACEstimator->split_cu_mode(CU_DONT_SPLIT, cs, partitioner
 #if JVET_AI0136_ADAPTIVE_DUAL_TREE
-  m_CABACEstimator->split_cu_mode( CU_DONT_SPLIT, cs, partitioner, nullptr );
-#else
-  m_CABACEstimator->split_cu_mode( CU_DONT_SPLIT, cs, partitioner );
+    , nullptr
+#endif
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false
 #endif
+  );
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
   if( partitioner.treeType == TREE_C )
     CHECK( m_CABACEstimator->getEstFracBits() != 0, "must be 0 bit" );
diff --git a/source/Lib/EncoderLib/EncCu.h b/source/Lib/EncoderLib/EncCu.h
index 218a4cd0946082a3c3bf1a5f7f1ec91d6d3dc626..8f16a4d7074e8f83b4dff429e665bc4c6c121613 100644
--- a/source/Lib/EncoderLib/EncCu.h
+++ b/source/Lib/EncoderLib/EncCu.h
@@ -494,7 +494,11 @@ public:
   void  compressCtu         ( CodingStructure& cs, const UnitArea& area, const unsigned ctuRsAddr, const int prevQP[], const int currQP[] );
   /// CTU encoding function
   int   updateCtuDataISlice ( const CPelBuf buf );
-
+  /// function to check whether the current CU is luma and non-boundary CU
+#if JVET_AI0087_BTCUS_RESTRICTION
+  bool isLumaNonBoundaryCu(const Partitioner &partitioner, SizeType picWidth, SizeType picHeight);
+  bool xStoreRDcostandPredMode(CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode &encTestmode, double tempcost);
+#endif
   EncModeCtrl* getModeCtrl  () { return m_modeCtrl; }
 
 #if JVET_V0094_BILATERAL_FILTER || JVET_X0071_CHROMA_BILATERAL_FILTER
@@ -521,7 +525,6 @@ protected:
   void xCompressCUParallel    ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm );
   void copyState              ( EncCu* other, Partitioner& pm, const UnitArea& currArea, const bool isDist );
 #endif
-
   bool
     xCheckBestMode         ( CodingStructure *&tempCS, CodingStructure *&bestCS, Partitioner &pm, const EncTestMode& encTestmode );
 #if !INTRA_RM_SMALL_BLOCK_SIZE_CONSTRAINTS
diff --git a/source/Lib/EncoderLib/EncModeCtrl.cpp b/source/Lib/EncoderLib/EncModeCtrl.cpp
index 3cf0aeee7a9c6f88285aeea80ca4cf64f016e5d3..d9ffc6e843dd11b5ff679a4f3771fa433b703594 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.cpp
+++ b/source/Lib/EncoderLib/EncModeCtrl.cpp
@@ -177,6 +177,23 @@ void EncModeCtrl::setBest( CodingStructure& cs )
   }
 }
 
+#if JVET_AI0087_BTCUS_RESTRICTION 
+bool EncModeCtrl::isLumaNonBoundaryCu(const Partitioner& partitioner, SizeType picWidth, SizeType picHeight)
+{
+  bool validCU = false;
+  if (isLuma(partitioner.chType))
+  {
+    int maxWidthHeight = std::max(partitioner.currArea().lwidth(), partitioner.currArea().lheight()) - 1;
+    if ((partitioner.currArea().Y().x + maxWidthHeight < picWidth)
+      && (partitioner.currArea().Y().y + maxWidthHeight < picHeight))
+    {
+      validCU = true;
+    }
+  }
+  return validCU;
+}
+#endif
+
 void EncModeCtrl::xGetMinMaxQP( int& minQP, int& maxQP, const CodingStructure& cs, const Partitioner &partitioner, const int baseQP, const SPS& sps, const PPS& pps, const PartSplit splitMode )
 {
   if( m_pcEncCfg->getUseRateCtrl() )
@@ -1707,6 +1724,57 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
   m_ComprCUCtxList.push_back( ComprCUCtx( cs, minDepth, maxDepth, NUM_EXTRA_FEATURES ) );
 #endif
 
+#if JVET_AI0087_BTCUS_RESTRICTION
+  bool disableBTV = false;
+  bool disableBTH = false;
+  if (EncModeCtrl::isLumaNonBoundaryCu(partitioner, cs.picture->lwidth(), cs.picture->lheight()) && (!(cs.slice->getProcessingIntraRegion() && cs.slice->getProcessingSeparateTrees()) || cs.slice->isIntra()) )
+  {
+    if ((partitioner.currBtDepth == 1) && (partitioner.currPartIdx() == 1))
+    {
+      if (partitioner.currPartLevel().split == CU_HORZ_SPLIT)   // BTH Case
+      {
+        if (partitioner.currArea().lwidth() == 128 && cs.btFirstPartDecs[0] == CU_VERT_SPLIT)
+        {
+          disableBTV = true;
+        }
+
+        else if (partitioner.currArea().lwidth() == 64 && cs.btFirstPartDecs[1] == CU_VERT_SPLIT)
+        {
+          disableBTV = true;
+        }
+        else if (partitioner.currArea().lwidth() == 32 && cs.btFirstPartDecs[2] == CU_VERT_SPLIT)
+        {
+          disableBTV = true;
+        }
+        else if (partitioner.currArea().lwidth() == 16 && cs.btFirstPartDecs[3] == CU_VERT_SPLIT)
+        {
+          disableBTV = true;
+        }
+      }
+
+      else if (partitioner.currPartLevel().split == CU_VERT_SPLIT)   // BTV Case
+      {
+        if (partitioner.currArea().lheight() == 128 && cs.btFirstPartDecs[0] == CU_HORZ_SPLIT)
+        {
+          disableBTH = true;
+        }
+        else if (partitioner.currArea().lheight() == 64 && cs.btFirstPartDecs[1] == CU_HORZ_SPLIT)
+        {
+          disableBTH = true;
+        }
+        else if (partitioner.currArea().lheight() == 32 && cs.btFirstPartDecs[2] == CU_HORZ_SPLIT)
+        {
+          disableBTH = true;
+        }
+        if (partitioner.currArea().lheight() == 16 && cs.btFirstPartDecs[3] == CU_HORZ_SPLIT)
+        {
+          disableBTH = true;
+        }
+      }
+    }
+  }
+#endif
+
 #if ENABLE_SPLIT_PARALLELISM
   if( m_runNextInParallel )
   {
@@ -1735,7 +1803,11 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
   unsigned maxBTD;
   bool canNo, canQt, canBh, canBv, canTh, canTv;
 
-  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxBTD );
+  partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxBTD 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
 
   if (!canBh && !canBv)
   {
@@ -1862,7 +1934,11 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
 #if JVET_AH0135_TEMPORAL_PARTITIONING 
   if ( canTv )
 #else
-  if( partitioner.canSplit( CU_TRIV_SPLIT, cs ) )
+  if( partitioner.canSplit( CU_TRIV_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  ) )
 #endif
   {
     // add split modes
@@ -1879,7 +1955,11 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
 #if JVET_AH0135_TEMPORAL_PARTITIONING
   if ( canTh )
 #else
-  if( partitioner.canSplit( CU_TRIH_SPLIT, cs ) )
+  if( partitioner.canSplit( CU_TRIH_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  ) )
 #endif
   {
     // add split modes
@@ -1897,9 +1977,17 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
   int maxQPq = maxQP;
   xGetMinMaxQP( minQP, maxQP, cs, partitioner, baseQP, *cs.sps, *cs.pps, CU_BT_SPLIT );
 #if JVET_AH0135_TEMPORAL_PARTITIONING
-  if ( canBv )
+  if ( canBv
+#if JVET_AI0087_BTCUS_RESTRICTION 
+    && !(disableBTV)
+#endif
+    )
 #else
-  if( partitioner.canSplit( CU_VERT_SPLIT, cs ) )
+  if( partitioner.canSplit( CU_VERT_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  ) )
 #endif
   {
     // add split modes
@@ -1927,9 +2015,17 @@ void EncModeCtrlMTnoRQT::initCULevel( Partitioner &partitioner, const CodingStru
   }
 
 #if JVET_AH0135_TEMPORAL_PARTITIONING
-  if ( canBh )
+  if ( canBh
+#if JVET_AI0087_BTCUS_RESTRICTION 
+    && !(disableBTH)
+#endif
+    )
 #else
-  if( partitioner.canSplit( CU_HORZ_SPLIT, cs ) )
+  if( partitioner.canSplit( CU_HORZ_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , disableBTV, disableBTH
+#endif
+  ) )
 #endif
   {
     // add split modes
@@ -2519,7 +2615,11 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
   }
   else if( isBoundary && encTestmode.type == ETM_SPLIT_QT )
   {
-    return partitioner.canSplit( CU_QUAD_SPLIT, cs );
+    return partitioner.canSplit( CU_QUAD_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
   }
 
 #if REUSE_CU_RESULTS
@@ -2558,17 +2658,26 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
   CodedCUInfo    &relatedCU          = getBlkInfo( partitioner.currArea() );
 #endif
 
-  if( cuECtx.minDepth > partitioner.currQtDepth && partitioner.canSplit( CU_QUAD_SPLIT, cs ) )
+  if( cuECtx.minDepth > partitioner.currQtDepth && partitioner.canSplit( CU_QUAD_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+
+  ) )
   {
     // enforce QT
     return encTestmode.type == ETM_SPLIT_QT;
   }
-  else if( encTestmode.type == ETM_SPLIT_QT && cuECtx.maxDepth <= partitioner.currQtDepth )
+  else if (encTestmode.type == ETM_SPLIT_QT && cuECtx.maxDepth <= partitioner.currQtDepth)
   {
-    // don't check this QT depth
-    return false;
+#if JVET_AI0087_BTCUS_RESTRICTION  
+        if (!(partitioner.chType == CHANNEL_TYPE_LUMA && partitioner.currBtDepth == 0 && (partitioner.currArea().lwidth() == 128 || partitioner.currArea().lwidth() == 64 || partitioner.currArea().lwidth() == 32)))
+#endif      
+        {
+          // don't check this QT depth
+          return false;
+        }      
   }
-
   if( bestCS && bestCS->cus.size() == 1 )
   {
     // update the best non-split cost
@@ -2984,7 +3093,11 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
     }
 
     const PartSplit split = getPartSplit( encTestmode );
-    if( !partitioner.canSplit( split, cs ) || skipScore >= 2 )
+    if( !partitioner.canSplit( split, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif    
+    ) || skipScore >= 2 )
     {
       if( split == CU_HORZ_SPLIT ) cuECtx.set( DID_HORZ_SPLIT, false );
       if( split == CU_VERT_SPLIT ) cuECtx.set( DID_VERT_SPLIT, false );
@@ -3068,7 +3181,11 @@ bool EncModeCtrlMTnoRQT::tryMode( const EncTestMode& encTestmode, const CodingSt
 #if JVET_AH0135_TEMPORAL_PARTITIONING
             bool canNo, canQt, canBh, canBv, canTh, canTv;
             unsigned maxBTD;
-            partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxBTD );
+            partitioner.canSplit( cs, canNo, canQt, canBh, canBv, canTh, canTv, maxBTD 
+#if JVET_AI0087_BTCUS_RESTRICTION
+              , false, false
+#endif
+            );
 #else 
             unsigned maxBTD        = cs.pcv->getMaxBtDepth( slice, partitioner.chType );
 #endif
@@ -3896,7 +4013,11 @@ bool EncModeCtrlMTnoRQT::useModeResult( const EncTestMode& encTestmode, CodingSt
 #if JVET_AH0135_TEMPORAL_PARTITIONING
   bool canNo, canQt, canBh, canBv, canTh, canTv;
   unsigned maxBTD;
-  partitioner.canSplit( *tempCS, canNo, canQt, canBh, canBv, canTh, canTv, maxBTD );
+  partitioner.canSplit( *tempCS, canNo, canQt, canBh, canBv, canTh, canTv, maxBTD
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
   maxMtD = (int)maxBTD;
 #endif
 
diff --git a/source/Lib/EncoderLib/EncModeCtrl.h b/source/Lib/EncoderLib/EncModeCtrl.h
index 94e0c3661be366b6c33bb205998f8feddf8c8eff..f86fbb8b29ab9edeacbb5a8de36ee63fc43d2101 100644
--- a/source/Lib/EncoderLib/EncModeCtrl.h
+++ b/source/Lib/EncoderLib/EncModeCtrl.h
@@ -407,6 +407,9 @@ public:
 #endif
   virtual void setBest              ( CodingStructure& cs );
   bool         anyMode              () const;
+#if JVET_AI0087_BTCUS_RESTRICTION
+  bool         isLumaNonBoundaryCu(const Partitioner& partitioner, SizeType picWidth, SizeType picHeight);
+#endif
 #if JVET_AE0057_MTT_ET
   void         setNoSplitIntraCost  (double cost) { m_noSplitIntraRdCost = cost; }
 #endif
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index da4eedd5e920bfb3fdeca7d275b679841c929031..2a99a0f3db75e27deea79a272361019b8298469e 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -12573,11 +12573,19 @@ void InterSearch::xEncodeInterResidualQT(CodingStructure &cs, Partitioner &parti
 
   if (compID == MAX_NUM_TBLOCKS)  // we are not processing a channel, instead we always recurse and code the CBFs
   {
-    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
       CHECK( !bSubdiv, "Not performing the implicit TU split" );
     }
-    else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
+    else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
       CHECK( !bSubdiv, "Not performing the implicit TU split - sbt" );
     }
@@ -12652,11 +12660,19 @@ void InterSearch::xEncodeInterResidualQT(CodingStructure &cs, Partitioner &parti
   {
     if( compID == MAX_NUM_TBLOCKS || TU::getCbfAtDepth( currTU, compID, currDepth ) )
     {
-      if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+      if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+        , false, false
+#endif
+      ) )
       {
         partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
       }
-      else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
+      else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+        , false, false
+#endif
+      ) )
       {
         partitioner.splitCurrArea( PartSplit( cu.getSbtTuSplit() ), cs );
       }
@@ -12939,8 +12955,16 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
   const unsigned currDepth = partitioner.currTrDepth;
   const bool colorTransFlag = cs.cus[0]->colorTransform;
 
-  bool bCheckFull  = !partitioner.canSplit( TU_MAX_TR_SPLIT, cs );
-  if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
+  bool bCheckFull  = !partitioner.canSplit( TU_MAX_TR_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
+  if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  ) )
   {
     bCheckFull = false;
   }
@@ -14742,11 +14766,19 @@ void InterSearch::xEstimateInterResidualQT(CodingStructure &cs, Partitioner &par
       m_CABACEstimator->getCtx() = ctxStart;
     }
 
-    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
       partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
     }
-    else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs ) )
+    else if( cu.sbtInfo && partitioner.canSplit( PartSplit( cu.getSbtTuSplit() ), cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
       partitioner.splitCurrArea( PartSplit( cu.getSbtTuSplit() ), cs );
     }
diff --git a/source/Lib/EncoderLib/IntraSearch.cpp b/source/Lib/EncoderLib/IntraSearch.cpp
index ad84c2205ca0d9e97267da98f58f40852a07bc81..a1b68d55eff481bbee2ebee7699f13e8962a67b5 100644
--- a/source/Lib/EncoderLib/IntraSearch.cpp
+++ b/source/Lib/EncoderLib/IntraSearch.cpp
@@ -4271,7 +4271,11 @@ void IntraSearch::estIntraPredChromaQT( CodingUnit &cu, Partitioner &partitioner
       if (CS::isDualITree(cs))
 #endif
       {
-        if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+        if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+          , false, false
+#endif
+        ) )
         {
           partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
 
@@ -8957,7 +8961,11 @@ void IntraSearch::xEncSubdivCbfQT( CodingStructure &cs, Partitioner &partitioner
   const bool subdiv        = currTU.depth > currDepth;
   ComponentID compID = partitioner.chType == CHANNEL_TYPE_LUMA ? COMPONENT_Y : COMPONENT_Cb;
 
-  if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+  if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  ) )
   {
     CHECK( !subdiv, "TU split implied" );
   }
@@ -8990,7 +8998,11 @@ void IntraSearch::xEncSubdivCbfQT( CodingStructure &cs, Partitioner &partitioner
 
   if (subdiv)
   {
-    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
       partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
     }
@@ -9059,7 +9071,11 @@ void IntraSearch::xEncCoeffQT( CodingStructure &cs, Partitioner &partitioner, co
 
   if (subdiv)
   {
-    if (partitioner.canSplit(TU_MAX_TR_SPLIT, cs))
+    if (partitioner.canSplit(TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ))
     {
       partitioner.splitCurrArea(TU_MAX_TR_SPLIT, cs);
     }
@@ -10744,13 +10760,25 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
   const SPS &sps           = *cs.sps;
   bool bCheckFull          = true;
   bool bCheckSplit         = false;
-  bCheckFull               = !partitioner.canSplit( TU_MAX_TR_SPLIT, cs );
-  bCheckSplit              = partitioner.canSplit( TU_MAX_TR_SPLIT, cs );
+  bCheckFull               = !partitioner.canSplit( TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
+  bCheckSplit              = partitioner.canSplit( TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
   const Slice           &slice = *cs.slice;
 
   if( cu.ispMode )
   {
-    bCheckSplit = partitioner.canSplit( ispType, cs );
+    bCheckSplit = partitioner.canSplit( ispType, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    );
     bCheckFull = !bCheckSplit;
   }
   uint32_t    numSig           = 0;
@@ -11333,7 +11361,11 @@ bool IntraSearch::xRecurIntraCodingLumaQT( CodingStructure &cs, Partitioner &par
 
     bool uiSplitCbfLuma  = false;
     bool splitIsSelected = true;
-    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
       partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
     }
@@ -11470,7 +11502,11 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
   const Slice    &slice = *cs.slice;
   const SPS      &sps = *cs.sps;
 
-  bool bCheckFull = !partitioner.canSplit(TU_MAX_TR_SPLIT, cs);
+  bool bCheckFull = !partitioner.canSplit(TU_MAX_TR_SPLIT, cs
+#if JVET_AI0087_BTCUS_RESTRICTION
+    , false, false
+#endif
+  );
   bool bCheckSplit = !bCheckFull;
 
   TempCtx ctxStart(m_ctxCache, m_CABACEstimator->getCtx());
@@ -12279,7 +12315,11 @@ bool IntraSearch::xRecurIntraCodingACTQT(CodingStructure &cs, Partitioner &parti
   bool validReturnSplit = false;
   if (bCheckSplit)
   {
-    if (partitioner.canSplit(TU_MAX_TR_SPLIT, *csSplit))
+    if (partitioner.canSplit(TU_MAX_TR_SPLIT, *csSplit
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ))
     {
       partitioner.splitCurrArea(TU_MAX_TR_SPLIT, *csSplit);
     }
@@ -13051,7 +13091,11 @@ ChromaCbfs IntraSearch::xRecurIntraChromaCodingQT( CodingStructure &cs, Partitio
     unsigned    numValidTBlocks   = ::getNumberValidTBlocks( *cs.pcv );
     ChromaCbfs  SplitCbfs         ( false );
 
-    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs ) )
+    if( partitioner.canSplit( TU_MAX_TR_SPLIT, cs 
+#if JVET_AI0087_BTCUS_RESTRICTION
+      , false, false
+#endif
+    ) )
     {
       partitioner.splitCurrArea( TU_MAX_TR_SPLIT, cs );
     }