diff --git a/source/Lib/CommonLib/MotionInfo.h b/source/Lib/CommonLib/MotionInfo.h
index cee7ca760617dacc945923e133b5aa91c0c286fd..9f61cf6aa8bf1cbd68a17cffe9c60690fcb08ab9 100644
--- a/source/Lib/CommonLib/MotionInfo.h
+++ b/source/Lib/CommonLib/MotionInfo.h
@@ -106,18 +106,36 @@ struct MotionInfo
 #endif
   char     interDir;
   uint16_t   sliceIdx;
-
+#if JVET_M0264_HMVP_WITH_GBIIDX
+  uint8_t         GBiIdx;
+#endif
   Mv      mv     [ NUM_REF_PIC_LIST_01 ];
   int16_t   refIdx [ NUM_REF_PIC_LIST_01 ];
   Mv      bv;
 #if JVET_M0483_IBC
+#if JVET_M0264_HMVP_WITH_GBIIDX
+  MotionInfo() : isInter(false), isIBCmot(false), interDir(0), sliceIdx(0), refIdx{ NOT_VALID, NOT_VALID }, GBiIdx(0) { }
+#else
   MotionInfo() : isInter(false), isIBCmot(false), interDir(0), sliceIdx(0), refIdx{ NOT_VALID, NOT_VALID } { }
+#endif
   // ensure that MotionInfo(0) produces '\x000....' bit pattern - needed to work with AreaBuf - don't use this constructor for anything else
+#if JVET_M0264_HMVP_WITH_GBIIDX
+  MotionInfo(int i) : isInter(i != 0), isIBCmot(false), interDir(0), sliceIdx(0), refIdx{ 0,         0 }, GBiIdx(0) { CHECKD(i != 0, "The argument for this constructor has to be '0'"); }
+#else
   MotionInfo(int i) : isInter(i != 0), isIBCmot(false), interDir(0), sliceIdx(0), refIdx{ 0,         0 } { CHECKD(i != 0, "The argument for this constructor has to be '0'"); }
+#endif
+#else
+#if JVET_M0264_HMVP_WITH_GBIIDX
+  MotionInfo() : isInter(false), interDir(0), sliceIdx(0), refIdx{ NOT_VALID, NOT_VALID }, GBiIdx(0) { }
 #else
   MotionInfo()        : isInter(  false ), interDir( 0 ), sliceIdx( 0 ), refIdx{ NOT_VALID, NOT_VALID } { }
+#endif
   // ensure that MotionInfo(0) produces '\x000....' bit pattern - needed to work with AreaBuf - don't use this constructor for anything else
+#if JVET_M0264_HMVP_WITH_GBIIDX
+  MotionInfo(int i) : isInter(i != 0), interDir(0), sliceIdx(0), refIdx{ 0,         0 }, GBiIdx(0) { CHECKD(i != 0, "The argument for this constructor has to be '0'"); }
+#else
   MotionInfo( int i ) : isInter( i != 0 ), interDir( 0 ), sliceIdx( 0 ), refIdx{         0,         0 } { CHECKD( i != 0, "The argument for this constructor has to be '0'" ); }
+#endif
 #endif
 
   bool operator==( const MotionInfo& mi ) const
diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp
index 975e7ff4e4d1f37e696daec9a6f095071f96147c..3ed31b85423ef7e2367db204856bc7525d184697 100644
--- a/source/Lib/CommonLib/Slice.cpp
+++ b/source/Lib/CommonLib/Slice.cpp
@@ -1752,6 +1752,9 @@ void Slice::updateMotionLUTs(LutMotionCand* lutMC, CodingUnit & cu)
   if (cu.triangle) { return; }
 
   MotionInfo newMi = selectedPU->getMotionInfo();
+#if JVET_M0264_HMVP_WITH_GBIIDX
+    newMi.GBiIdx = (newMi.interDir == 3) ? cu.GBiIdx : GBI_DEFAULT;
+#endif
 #if JVET_M0483_IBC
   addMotionInfoToLUTs(lutMC, newMi, CU::isIBC(cu));
 #else
diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h
index f0d716ddd67ebc17e9be17bd95b49bf6347b38a2..0bae68972ecaa4ff4b97936f3a52a156613388ad 100644
--- a/source/Lib/CommonLib/TypeDef.h
+++ b/source/Lib/CommonLib/TypeDef.h
@@ -54,6 +54,8 @@
 
 #define JVET_M0145_AFFINE_MV_CLIP                         1 // Missing clipping for MV storage in affine
 
+#define JVET_M0264_HMVP_WITH_GBIIDX                       1 // Harmonization between HMVP and GBi
+
 #define JVET_M0381_ONE_CTX_FOR_SUBBLOCK_MRG_IDX           1 // CE2.2.2 a: one context for subblock Merge index
 
 #define JVET_M0118_M0185_TRIANGLE_FLAG_FIX                1 // Avoid signaling triangle flag if a CU uses MMVD or CIIP
diff --git a/source/Lib/CommonLib/UnitTools.cpp b/source/Lib/CommonLib/UnitTools.cpp
index 584d41176f3c9343b3a640d23a4d66b0c736536a..aa69d6ff2cee3f57888d354c39b79b3cdaa6622e 100644
--- a/source/Lib/CommonLib/UnitTools.cpp
+++ b/source/Lib/CommonLib/UnitTools.cpp
@@ -778,6 +778,9 @@ bool PU::addMergeHMVPCand(const Slice &slice, MergeCtx& mrgCtx, bool isCandInter
 #endif
 #endif
     mrgCtx.interDirNeighbours[cnt] = miNeighbor.interDir;
+#if JVET_M0264_HMVP_WITH_GBIIDX
+    mrgCtx.GBiIdx[cnt] = (mrgCtx.interDirNeighbours[cnt] == 3) ? miNeighbor.GBiIdx : GBI_DEFAULT;
+#endif
     mrgCtx.mvFieldNeighbours[cnt << 1].setMvField(miNeighbor.mv[0], miNeighbor.refIdx[0]);
     if (slice.isInterB())
     {
@@ -2314,20 +2317,12 @@ void PU::fillMvpCand(PredictionUnit &pu, const RefPicList &eRefPicList, const in
 
   {
     const PredictionUnit* tmpPU = cs.getPURestricted( posLB.offset( -1, 1 ), pu, pu.chType ); // getPUBelowLeft(idx, partIdxLB);
-#if JVET_M0483_IBC    
-    isScaledFlagLX = tmpPU != NULL && !CU::isIntra(*tmpPU->cu);
-#else
     isScaledFlagLX = tmpPU != NULL && CU::isInter( *tmpPU->cu );
-#endif
 
     if( !isScaledFlagLX )
     {
       tmpPU = cs.getPURestricted( posLB.offset( -1, 0 ), pu, pu.chType );
-#if JVET_M0483_IBC
-      isScaledFlagLX = tmpPU != NULL && !CU::isIntra(*tmpPU->cu);
-#else
       isScaledFlagLX = tmpPU != NULL && CU::isInter( *tmpPU->cu );
-#endif
     }
   }
 
@@ -2912,22 +2907,14 @@ bool PU::addMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &eRefPic
 
   neibPU = cs.getPURestricted( neibPos, pu, pu.chType );
 
-#if JVET_M0483_IBC
-  if (neibPU == NULL || neibPU->cu->predMode != pu.cu->predMode)
-#else
   if( neibPU == NULL || !CU::isInter( *neibPU->cu ) )
-#endif
   {
     return false;
   }
 
   const MotionInfo& neibMi        = neibPU->getMotionInfo( neibPos );
 
-#if JVET_M0483_IBC
-  const int        currRefPOC     = CU::isIBC(*pu.cu) ? cs.slice->getPOC() : cs.slice->getRefPic(eRefPicList, iRefIdx)->getPOC();
-#else
   const int        currRefPOC     = cs.slice->getRefPic( eRefPicList, iRefIdx )->getPOC();
-#endif
   const RefPicList eRefPicList2nd = ( eRefPicList == REF_PIC_LIST_0 ) ? REF_PIC_LIST_1 : REF_PIC_LIST_0;
 
   for( int predictorSource = 0; predictorSource < 2; predictorSource++ ) // examine the indicated reference picture list, then if not available, examine the other list.
@@ -2935,11 +2922,7 @@ bool PU::addMVPCandUnscaled( const PredictionUnit &pu, const RefPicList &eRefPic
     const RefPicList eRefPicListIndex = ( predictorSource == 0 ) ? eRefPicList : eRefPicList2nd;
     const int        neibRefIdx       = neibMi.refIdx[eRefPicListIndex];
 
-#if JVET_M0483_IBC
-    if (neibRefIdx >= 0 && currRefPOC == (CU::isIBC(*neibPU->cu) ? cs.slice->getPOC() : cs.slice->getRefPOC(eRefPicListIndex, neibRefIdx)))
-#else
     if( neibRefIdx >= 0 && currRefPOC == cs.slice->getRefPOC( eRefPicListIndex, neibRefIdx ) )
-#endif
     {
       info.mvCand[info.numCand++] = neibMi.mv[eRefPicListIndex];
       return true;
diff --git a/source/Lib/EncoderLib/InterSearch.cpp b/source/Lib/EncoderLib/InterSearch.cpp
index 1f828600fe1fc9df8d0148c5a9e21af9c34fdaaf..4e34f4258280531931d8070e46b8d0eee0afe3b8 100644
--- a/source/Lib/EncoderLib/InterSearch.cpp
+++ b/source/Lib/EncoderLib/InterSearch.cpp
@@ -1286,6 +1286,11 @@ void InterSearch::xSetIntraSearchRange(PredictionUnit& pu, int iRoiWidth, int iR
 
 bool InterSearch::predIBCSearch(CodingUnit& cu, Partitioner& partitioner, const int localSearchRangeX, const int localSearchRangeY, IbcHashMap& ibcHashMap)
 {
+#if JVET_M0483_IBC==0
+  // check only no greater than IBC_MAX_CAND_SIZE
+  if (cu.Y().width > IBC_MAX_CAND_SIZE || cu.Y().height > IBC_MAX_CAND_SIZE)
+    return false;
+#endif
   Mv           cMvSrchRngLT;
   Mv           cMvSrchRngRB;