- #include <cassert> 
- #include <cstdio> 
- #include <cstring> 
- #include <cstdint> 
-   
- template <int N> 
- int find_high_bits_in_byte_r(uint8_t x, int base_idx) 
- { 
-     uint8_t high = x >> N; 
-     uint8_t low = ((1 << N) - 1) & x; 
-     if (high > 0) 
-     { 
-         return find_high_bits_in_byte_r<N / 2>(high, base_idx + N); 
-     } 
-     else 
-     { 
-         return find_high_bits_in_byte_r<N / 2>(low, base_idx); 
-     } 
- } 
-   
- template <> 
- int find_high_bits_in_byte_r<0>(uint8_t x, int base_idx) 
- { 
-     return base_idx; 
- } 
-   
- int find_high_bits_in_byte(uint8_t x) 
- { 
-     return find_high_bits_in_byte_r<4>(x, 0); 
- } 
-   
- template <int N> 
- bool is_greater_than_zero(uint8_t data[N]) 
- { 
-     uint8_t zerofill[N] = { 0 }; 
-     auto retval = std::memcmp(data, zerofill, N); 
-     return (retval != 0); 
- } 
-   
- template <int N> 
- int find_high_bit_r(uint8_t data[N], int base_idx) 
- { 
-     union container_t { 
-         uint8_t data[N]; 
-         struct 
-         { 
-             uint8_t low[N / 2]; 
-             uint8_t high[N / 2]; 
-         }; 
-     } c; 
-     std::memcpy(c.data, data, N); 
-   
-     if (is_greater_than_zero<N / 2>(c.high)) 
-     { 
-         return find_high_bit_r<N / 2>(c.high, base_idx + N / 2); 
-     } 
-     else 
-     { 
-         return find_high_bit_r<N / 2>(c.low, base_idx); 
-     } 
- } 
-   
- template <> 
- int find_high_bit_r<1>(uint8_t data[1], int base_idx) 
- { 
-     auto bit_idx = find_high_bits_in_byte(data[0]); 
-     return bit_idx + base_idx * 8; 
- } 
-   
- template <typename T> 
- int find_high_bit(T x) 
- { 
-     if (x == 0) 
-     { 
-         return -1; 
-     } 
-   
-     union container_t { 
-         T val; 
-         uint8_t data[sizeof(T)]; 
-     }; 
-     container_t c; 
-     c.val = x; 
-     return find_high_bit_r<sizeof(T)>(c.data, 0); 
- } 
-   
- int main() 
- { 
-     for (int i = 0; i < 8; i++) 
-     { 
-         assert(i == find_high_bits_in_byte(1 << i)); 
-     } 
-   
-     for (int i = 0; i < 32; i++) 
-     { 
-         assert(i == find_high_bit<uint32_t>(1 << i)); 
-     } 
-   
-     assert(3 == find_high_bit<uint32_t>(0b1011)); 
-     assert(27 == find_high_bit<uint32_t>(0b00001000'00000100'00000010'00000001)); 
-   
-     return 0; 
- } 
-   
				I2luY2x1ZGUgPGNhc3NlcnQ+CiNpbmNsdWRlIDxjc3RkaW8+CiNpbmNsdWRlIDxjc3RyaW5nPgojaW5jbHVkZSA8Y3N0ZGludD4KCnRlbXBsYXRlIDxpbnQgTj4KaW50IGZpbmRfaGlnaF9iaXRzX2luX2J5dGVfcih1aW50OF90IHgsIGludCBiYXNlX2lkeCkKewogICAgdWludDhfdCBoaWdoID0geCA+PiBOOwogICAgdWludDhfdCBsb3cgPSAoKDEgPDwgTikgLSAxKSAmIHg7CiAgICBpZiAoaGlnaCA+IDApCiAgICB7CiAgICAgICAgcmV0dXJuIGZpbmRfaGlnaF9iaXRzX2luX2J5dGVfcjxOIC8gMj4oaGlnaCwgYmFzZV9pZHggKyBOKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXR1cm4gZmluZF9oaWdoX2JpdHNfaW5fYnl0ZV9yPE4gLyAyPihsb3csIGJhc2VfaWR4KTsKICAgIH0KfQoKdGVtcGxhdGUgPD4KaW50IGZpbmRfaGlnaF9iaXRzX2luX2J5dGVfcjwwPih1aW50OF90IHgsIGludCBiYXNlX2lkeCkKewogICAgcmV0dXJuIGJhc2VfaWR4Owp9CgppbnQgZmluZF9oaWdoX2JpdHNfaW5fYnl0ZSh1aW50OF90IHgpCnsKICAgIHJldHVybiBmaW5kX2hpZ2hfYml0c19pbl9ieXRlX3I8ND4oeCwgMCk7Cn0KCnRlbXBsYXRlIDxpbnQgTj4KYm9vbCBpc19ncmVhdGVyX3RoYW5femVybyh1aW50OF90IGRhdGFbTl0pCnsKICAgIHVpbnQ4X3QgemVyb2ZpbGxbTl0gPSB7IDAgfTsKICAgIGF1dG8gcmV0dmFsID0gc3RkOjptZW1jbXAoZGF0YSwgemVyb2ZpbGwsIE4pOwogICAgcmV0dXJuIChyZXR2YWwgIT0gMCk7Cn0KCnRlbXBsYXRlIDxpbnQgTj4KaW50IGZpbmRfaGlnaF9iaXRfcih1aW50OF90IGRhdGFbTl0sIGludCBiYXNlX2lkeCkKewogICAgdW5pb24gY29udGFpbmVyX3QgewogICAgICAgIHVpbnQ4X3QgZGF0YVtOXTsKICAgICAgICBzdHJ1Y3QKICAgICAgICB7CiAgICAgICAgICAgIHVpbnQ4X3QgbG93W04gLyAyXTsKICAgICAgICAgICAgdWludDhfdCBoaWdoW04gLyAyXTsKICAgICAgICB9OwogICAgfSBjOwogICAgc3RkOjptZW1jcHkoYy5kYXRhLCBkYXRhLCBOKTsKCiAgICBpZiAoaXNfZ3JlYXRlcl90aGFuX3plcm88TiAvIDI+KGMuaGlnaCkpCiAgICB7CiAgICAgICAgcmV0dXJuIGZpbmRfaGlnaF9iaXRfcjxOIC8gMj4oYy5oaWdoLCBiYXNlX2lkeCArIE4gLyAyKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICByZXR1cm4gZmluZF9oaWdoX2JpdF9yPE4gLyAyPihjLmxvdywgYmFzZV9pZHgpOwogICAgfQp9Cgp0ZW1wbGF0ZSA8PgppbnQgZmluZF9oaWdoX2JpdF9yPDE+KHVpbnQ4X3QgZGF0YVsxXSwgaW50IGJhc2VfaWR4KQp7CiAgICBhdXRvIGJpdF9pZHggPSBmaW5kX2hpZ2hfYml0c19pbl9ieXRlKGRhdGFbMF0pOwogICAgcmV0dXJuIGJpdF9pZHggKyBiYXNlX2lkeCAqIDg7Cn0KCnRlbXBsYXRlIDx0eXBlbmFtZSBUPgppbnQgZmluZF9oaWdoX2JpdChUIHgpCnsKICAgIGlmICh4ID09IDApCiAgICB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHVuaW9uIGNvbnRhaW5lcl90IHsKICAgICAgICBUIHZhbDsKICAgICAgICB1aW50OF90IGRhdGFbc2l6ZW9mKFQpXTsKICAgIH07CiAgICBjb250YWluZXJfdCBjOwogICAgYy52YWwgPSB4OwogICAgcmV0dXJuIGZpbmRfaGlnaF9iaXRfcjxzaXplb2YoVCk+KGMuZGF0YSwgMCk7Cn0KCmludCBtYWluKCkKewogICAgZm9yIChpbnQgaSA9IDA7IGkgPCA4OyBpKyspCiAgICB7CiAgICAgICAgYXNzZXJ0KGkgPT0gZmluZF9oaWdoX2JpdHNfaW5fYnl0ZSgxIDw8IGkpKTsKICAgIH0KCiAgICBmb3IgKGludCBpID0gMDsgaSA8IDMyOyBpKyspCiAgICB7CiAgICAgICAgYXNzZXJ0KGkgPT0gZmluZF9oaWdoX2JpdDx1aW50MzJfdD4oMSA8PCBpKSk7CiAgICB9CgogICAgYXNzZXJ0KDMgPT0gZmluZF9oaWdoX2JpdDx1aW50MzJfdD4oMGIxMDExKSk7CiAgICBhc3NlcnQoMjcgPT0gZmluZF9oaWdoX2JpdDx1aW50MzJfdD4oMGIwMDAwMTAwMCcwMDAwMDEwMCcwMDAwMDAxMCcwMDAwMDAwMSkpOwoKICAgIHJldHVybiAwOwp9Cg==