import time
from threading import Thread
from multiprocessing import Process
x = [ 0 , 10 , 20 , 30 , 40 , 50 , 60 , 70 , 80 , 90 , 100 , 110 , 120 , 130 , 140 , 150 , 160 ]
#x_shared = [0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0]
r = 1
#state values ==> [write_miss][read_hit][read_miss][Invalidate]
#bus=[state,coreNum,blockNum]
busLabels= [ " bus_request : " , " coreNum : " , " BlockNum " ]
bus= [ "no_request" , -1 , -1 ]
lock = 0
#write_core
def fun1( ) :
coreNum = 1
cach1= [ 0 , 0 , 7 , 0 ]
cach1V= [ 0 , 0 , 70 , 0 ]
v= [ 0 , 1 , 0 , 0 ] #valid bit
s= [ 0 , 0 , 0 , 0 ] #shared bit
d= [ 0 , 0 , 0 , 0 ] #dirty bit indcate modified or not
blockNum = 5
print ( "\n =====================================================================\n " )
print ( "Core <<1>>: read new blockNum : " , end= '' )
print ( 5 , end= ' ' ) #blockNum
print ( " conflicts with current shared block then make replacement" )
bus[ 0 ] = "read_miss"
bus[ 1 ] = coreNum
bus[ 2 ] = 5
print ( busLabels)
print ( bus)
v[ 5 %4 ] = 1
d[ 5 %4 ] = 0
s[ 5 %4 ] = 1
cach1[ 5 %4 ] = 5
cach1V[ 5 %4 ] = x[ 5 ]
#write miss (block invalid become modified )
print ( "\n =====================================================================\n " )
print ( "Core <<1>>: write new blockNum : " , end= '' )
print ( 15 , end= ' ' ) #blockNum
print ( " then the block invalid become modified" )
bus[ 0 ] = "write_miss"
bus[ 1 ] = 3
bus[ 2 ] = 15
print ( busLabels)
print ( bus)
v[ 15 %4 ] = 1
d[ 15 %4 ] = 1
s[ 15 %4 ] = 0
x[ 15 ] = 155
cach1[ 15 %4 ] = 15
cach1V[ 15 %4 ] = x[ 15 ]
#snooping
for i in range ( 10 *9999999 ) :
if ( bus[ 0 ] == "read_miss" or bus[ 0 ] == "write_miss" ) and bus[ 1 ] != coreNum and v[ bus[ 2 ] %4 ] == 1 and cach1[ bus[ 2 ] %4 ] == bus[ 2 ] and s[ bus[ 2 ] %4 ] == 0 : #have block modified , bus read miss ==> write back and
for i in range ( 20000000 ) :
pass
s[ bus[ 2 ] %4 ] = 1 ;
print ( "cach Number " , end = '' )
print ( coreNum, end = '' )
print ( " puts modified blockNum " , end = '' )
print ( bus[ 2 ] , end = '' )
print ( " on bus and update memory and the block become shared " , end = '' )
if ( bus[ 0 ] == "Invalidate" or bus[ 0 ] == "write_miss" ) and bus[ 1 ] != coreNum and v[ bus[ 2 ] %4 ] == 1 and cach1[ bus[ 2 ] %4 ] == bus[ 2 ] : # have block shared ,bus Invalidate ===> invalide block in this cach if exist
for i in range ( 20000000 ) :
pass
v[ bus[ 2 ] %4 ] = 0 ;
print ( "cach Number " , end = '' )
print ( coreNum, end = '' )
print ( " invalidate BlockNum: " , end = '' )
print ( bus[ 2 ] , end = '' )
print ( " as cachNum " , end = '' )
print ( bus[ 1 ] , end = '' )
print ( "want to write in this block" )
print ( " blockNum: " )
print ( cach1)
print ( " BlockValue: " )
print ( cach1V)
print ( " ValidBit: " )
print ( v)
print ( " SharedBit :" )
print ( s)
print ( "DirtyBit : " )
print ( d)
#=================================================================================
#=================================================================================
def fun3( ) :
cach3= [ 16 , 0 , 0 , 0 ]
cach3V= [ 160 , 0 , 0 , 0 ]
v= [ 1 , 0 , 0 , 0 ] #valid bit
s= [ 1 , 0 , 0 , 0 ] #shared bit
d= [ 0 , 0 , 0 , 0 ] #dirty bit indcate modified or not
blockNum = 5
for i in range ( 3 *9999999 ) :
pass
#read miss
print ( "\n =====================================================================\n " )
print ( "Core <<3>>: read new blockNum " , end= '' )
print ( 5 , end= '' ) #blockNum
print ( "then this block will be midified" )
bus[ 0 ] = "read_miss"
bus[ 1 ] = 3 #coreNum
bus[ 2 ] = 5 #blockNum
print ( busLabels)
print ( bus)
v[ 5 %4 ] = 1
d[ 5 %4 ] = 0
cach3[ 5 %4 ] = blockNum
cach3V[ 5 %4 ] = x[ blockNum]
for i in range ( 3 *9999999 ) :
pass
#write_hit
print ( "\n =====================================================================\n " )
print ( "Core <<3>>: write to blockNum " , end= '' )
print ( 5 , end = '' ) #blockNum
print ( "then this block will be midified" )
bus[ 0 ] = "Invalidate"
bus[ 1 ] = 3 #coreNum
bus[ 2 ] = 5 #blockNum
print ( busLabels)
print ( bus)
v[ 5 %4 ] = 1 #set validity bit
d[ 5 %4 ] = 1 #set dirty bit as block modified with write
s[ 5 %4 ] = 0 #cleared shared bit
cach3[ 5 %4 ] = 5 #cach block num
cach3V[ 5 %4 ] = x[ 5 ] #cach block value
for i in range ( 3 *9999999 ) : #delay
pass
#read miss (conflict with block modified 5)
print ( "\n =====================================================================\n " )
print ( "Core <<3>>: read new blockNum " , end= '' )
print ( 9 , end= ' ' ) #blockNum
print ( " conflicts with current modified blockNum then make replacement and update memory" )
bus[ 0 ] = "read_miss"
x[ 9 ] = cach3V[ 9 %4 ] #memory write back
#9====> block num
bus[ 1 ] = 3
bus[ 2 ] = 9
print ( busLabels)
print ( bus)
v[ 9 %4 ] = 1
d[ 9 %4 ] = 0
cach3[ 9 %4 ] = 9
cach3V[ 9 %4 ] = x[ 9 ]
for i in range ( 2 *9999999 ) : #delay
pass
#read miss (conflict with block shared )
print ( "\n =====================================================================\n " )
print ( "Core <<3>>: read new blockNum : " , end= '' )
print ( 12 , end= ' ' ) #blockNum
print ( " conflicts with current shared block then make replacement" )
bus[ 0 ] = "read_miss"
#x_shared[blockNum]-=1
x[ 0 ] = cach3V[ 16 %4 ] #memory write back
bus[ 1 ] = 3 #coreNum
bus[ 2 ] = 12 #blockNum
print ( busLabels)
print ( bus)
v[ 12 %4 ] = 1
d[ 12 %4 ] = 0
s[ 12 %4 ] = 1
cach3[ 12 %4 ] = 12
cach3V[ 12 %4 ] = x[ 12 ]
for i in range ( 2 *9999999 ) : #delay
pass
#write miss (block invalid become modified )
print ( "\n =====================================================================\n " )
print ( "Core <<3>>: write new blockNum : " , end= '' )
print ( 15 , end= ' ' ) #blockNum
print ( " then the block invalid become modified" )
bus[ 0 ] = "write_miss"
bus[ 1 ] = 3 #coreNum
bus[ 2 ] = 15 #blockNum
print ( busLabels)
print ( bus)
v[ 15 %4 ] = 1
d[ 15 %4 ] = 1
x[ 15 ] = 155
cach3[ 15 %4 ] = 15
cach3V[ 15 %4 ] = x[ 15 ]
#=================================================================================
if __name__ == '__main__' :
for i in range ( 50 ) :
x.append ( i)
print ( x)
t1 = Thread( target= fun1, args= ( ) )
t3 = Thread( target= fun3, args= ( ) )
t1.start ( )
t3.start ( )
t1.join ( )
t3.join ( )
aW1wb3J0IHRpbWUKZnJvbSB0aHJlYWRpbmcgaW1wb3J0IFRocmVhZApmcm9tIG11bHRpcHJvY2Vzc2luZyBpbXBvcnQgUHJvY2Vzcwp4ID0gWzAsMTAsMjAsMzAsNDAsNTAsNjAsNzAsODAsOTAsMTAwLDExMCwxMjAsMTMwLDE0MCwxNTAsMTYwXQojeF9zaGFyZWQgPSBbMCwwLDAsMCwxLDAsMCwwLDAsMCwwLDAsMCwwLDAsMF0KciA9IDEKI3N0YXRlIHZhbHVlcyA9PT4gW3dyaXRlX21pc3NdW3JlYWRfaGl0XVtyZWFkX21pc3NdW0ludmFsaWRhdGVdCiNidXM9W3N0YXRlLGNvcmVOdW0sYmxvY2tOdW1dCmJ1c0xhYmVscz1bIiBidXNfcmVxdWVzdCA6ICIsIiBjb3JlTnVtIDogIiwiIEJsb2NrTnVtICJdCmJ1cz1bIm5vX3JlcXVlc3QiLC0xLC0xXQpsb2NrID0gMAojd3JpdGVfY29yZQpkZWYgZnVuMSgpOgogY29yZU51bSA9IDEKIGNhY2gxPVswLDAsNywwXQogY2FjaDFWPVswLDAsNzAsMF0KIHY9WzAsMSwwLDBdICN2YWxpZCBiaXQKIHM9WzAsMCwwLDBdICNzaGFyZWQgYml0CiBkPVswLDAsMCwwXSAjZGlydHkgYml0IGluZGNhdGUgbW9kaWZpZWQgb3Igbm90CiAKIGJsb2NrTnVtID0gNQoKIHByaW50KCJcbj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuIikKIHByaW50KCJDb3JlIDw8MT4+OiByZWFkIG5ldyBibG9ja051bSA6ICIsZW5kPScnKQogcHJpbnQoNSxlbmQ9JyAgJykjYmxvY2tOdW0KIHByaW50KCIgY29uZmxpY3RzIHdpdGggY3VycmVudCBzaGFyZWQgIGJsb2NrIHRoZW4gbWFrZSByZXBsYWNlbWVudCIpCiBidXNbMF09InJlYWRfbWlzcyIKIGJ1c1sxXT1jb3JlTnVtCiBidXNbMl09NQogcHJpbnQoYnVzTGFiZWxzKQogcHJpbnQoYnVzKQogdls1JTRdID0gMQogZFs1JTRdID0gMAogc1s1JTRdID0gMQogY2FjaDFbNSU0XT01CiBjYWNoMVZbNSU0XSA9IHhbNV0KCiAgICN3cml0ZSBtaXNzIChibG9jayBpbnZhbGlkIGJlY29tZSBtb2RpZmllZCApCiBwcmludCgiXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpCiBwcmludCgiQ29yZSA8PDE+Pjogd3JpdGUgbmV3IGJsb2NrTnVtIDogIixlbmQ9JycpCiBwcmludCgxNSxlbmQ9JyAgJykjYmxvY2tOdW0KIHByaW50KCIgdGhlbiB0aGUgYmxvY2sgaW52YWxpZCBiZWNvbWUgbW9kaWZpZWQiKQogYnVzWzBdPSJ3cml0ZV9taXNzIgogYnVzWzFdPTMKIGJ1c1syXT0xNQogcHJpbnQoYnVzTGFiZWxzKQogcHJpbnQoYnVzKQogdlsxNSU0XSA9IDEKIGRbMTUlNF0gPSAxCiBzWzE1JTRdID0gMAogeFsxNV0gPSAxNTUKIGNhY2gxWzE1JTRdPTE1CiBjYWNoMVZbMTUlNF0gPSB4WzE1XQogCiAjc25vb3BpbmcKIGZvciBpIGluIHJhbmdlKDEwKjk5OTk5OTkpOgogICAgICAgICAKICAgICBpZiAoYnVzWzBdID09ICJyZWFkX21pc3MiIG9yIGJ1c1swXSA9PSAid3JpdGVfbWlzcyIpYW5kIGJ1c1sxXSAhPSBjb3JlTnVtIGFuZCB2W2J1c1syXSU0XSA9PSAxIGFuZCBjYWNoMVtidXNbMl0lNF0gPT0gYnVzWzJdIGFuZCBzW2J1c1syXSU0XSA9PSAwOiAjaGF2ZSBibG9jayBtb2RpZmllZCAsIGJ1cyByZWFkIG1pc3MgPT0+IHdyaXRlIGJhY2sgYW5kIAogICAgICAgICBmb3IgaSBpbiByYW5nZSgyMDAwMDAwMCk6CiAgICAgICAgICAgICBwYXNzCiAgICAgICAgIHNbYnVzWzJdJTRdID0gMTsKICAgICAgICAgcHJpbnQoImNhY2ggTnVtYmVyICIsZW5kID0gJycpCiAgICAgICAgIHByaW50KGNvcmVOdW0sZW5kID0gJycpCiAgICAgICAgIHByaW50KCIgcHV0cyBtb2RpZmllZCBibG9ja051bSAiLGVuZCA9ICcnKQogICAgICAgICBwcmludChidXNbMl0sZW5kID0gJycpCiAgICAgICAgIHByaW50KCIgIG9uIGJ1cyBhbmQgdXBkYXRlIG1lbW9yeSBhbmQgdGhlIGJsb2NrIGJlY29tZSBzaGFyZWQgIixlbmQgPSAnJykKCiAgICAgCiAgICAgaWYgKGJ1c1swXSA9PSAiSW52YWxpZGF0ZSIgb3IgYnVzWzBdID09ICJ3cml0ZV9taXNzIikgYW5kIGJ1c1sxXSAhPSBjb3JlTnVtIGFuZCB2W2J1c1syXSU0XSA9PSAxIGFuZCBjYWNoMVtidXNbMl0lNF0gPT0gYnVzWzJdOiAgIyBoYXZlIGJsb2NrIHNoYXJlZCAsYnVzIEludmFsaWRhdGUgPT09PiBpbnZhbGlkZSBibG9jayBpbiB0aGlzIGNhY2ggaWYgZXhpc3QKICAgICAgICAgZm9yIGkgaW4gcmFuZ2UoMjAwMDAwMDApOgogICAgICAgICAgICAgcGFzcwogICAgICAgICB2W2J1c1syXSU0XSA9IDA7CiAgICAgICAgIHByaW50KCJjYWNoIE51bWJlciAiLGVuZCA9ICcnKQogICAgICAgICBwcmludChjb3JlTnVtLGVuZCA9ICcnKQogICAgICAgICBwcmludCgiIGludmFsaWRhdGUgQmxvY2tOdW06ICIsZW5kID0gJycpCiAgICAgICAgIHByaW50KGJ1c1syXSxlbmQgPSAnJykKICAgICAgICAgcHJpbnQoIiBhcyBjYWNoTnVtICIsZW5kID0gJycpCiAgICAgICAgIHByaW50KGJ1c1sxXSxlbmQgPSAnJykKICAgICAgICAgcHJpbnQoIndhbnQgdG8gd3JpdGUgaW4gdGhpcyBibG9jayIpCgogCgogICAgICAgIAogCgogCiAgICAgICAgCiBwcmludCgiIGJsb2NrTnVtOiAiKQogcHJpbnQoY2FjaDEpCiBwcmludCgiIEJsb2NrVmFsdWU6ICIpCiBwcmludChjYWNoMVYpCiBwcmludCgiIFZhbGlkQml0OiAiKQogcHJpbnQodikKIHByaW50KCIgU2hhcmVkQml0IDoiKQogcHJpbnQocykKIHByaW50KCJEaXJ0eUJpdCA6ICIpCiBwcmludChkKQogIz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKICM9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KZGVmIGZ1bjMoKToKIGNhY2gzPVsxNiwwLDAsMF0KIGNhY2gzVj1bMTYwLDAsMCwwXQogdj1bMSwwLDAsMF0gI3ZhbGlkIGJpdAogcz1bMSwwLDAsMF0gI3NoYXJlZCBiaXQKIGQ9WzAsMCwwLDBdICNkaXJ0eSBiaXQgaW5kY2F0ZSBtb2RpZmllZCBvciBub3QKIGJsb2NrTnVtID0gNQogZm9yIGkgaW4gcmFuZ2UoMyo5OTk5OTk5KToKICAgICBwYXNzCiAjcmVhZCBtaXNzCiBwcmludCgiXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpCiBwcmludCgiQ29yZSA8PDM+PjogcmVhZCBuZXcgIGJsb2NrTnVtICIsZW5kPScnKQogcHJpbnQoNSxlbmQ9JycpICNibG9ja051bQogcHJpbnQoInRoZW4gdGhpcyBibG9jayB3aWxsIGJlIG1pZGlmaWVkIikKIGJ1c1swXT0icmVhZF9taXNzIgogYnVzWzFdPTMgI2NvcmVOdW0KIGJ1c1syXT01ICNibG9ja051bQogcHJpbnQoYnVzTGFiZWxzKQogcHJpbnQoYnVzKQogdls1JTRdID0gMQogZFs1JTRdID0gMAogY2FjaDNbNSU0XT1ibG9ja051bQogY2FjaDNWWzUlNF0gPSB4W2Jsb2NrTnVtXQoKIGZvciBpIGluIHJhbmdlKDMqOTk5OTk5OSk6CiAgICAgcGFzcwojd3JpdGVfaGl0CiBwcmludCgiXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpCiBwcmludCgiQ29yZSA8PDM+Pjogd3JpdGUgdG8gYmxvY2tOdW0gIixlbmQ9JycpCiBwcmludCg1LGVuZCA9ICcnKSAjYmxvY2tOdW0KIHByaW50KCJ0aGVuIHRoaXMgYmxvY2sgd2lsbCBiZSBtaWRpZmllZCIpCiBidXNbMF09IkludmFsaWRhdGUiCiBidXNbMV09MyAjY29yZU51bQogYnVzWzJdPTUgI2Jsb2NrTnVtCiBwcmludChidXNMYWJlbHMpCiBwcmludChidXMpCiB2WzUlNF0gPSAxICNzZXQgdmFsaWRpdHkgYml0IAogZFs1JTRdID0gMSAjc2V0IGRpcnR5IGJpdCBhcyBibG9jayBtb2RpZmllZCB3aXRoIHdyaXRlCiBzWzUlNF0gPSAwICNjbGVhcmVkIHNoYXJlZCBiaXQgCiBjYWNoM1s1JTRdPTUgI2NhY2ggYmxvY2sgbnVtIAogY2FjaDNWWzUlNF0gPSB4WzVdICNjYWNoIGJsb2NrIHZhbHVlCgogZm9yIGkgaW4gcmFuZ2UoMyo5OTk5OTk5KTogI2RlbGF5CiAgICAgcGFzcwogI3JlYWQgbWlzcyAoY29uZmxpY3Qgd2l0aCBibG9jayBtb2RpZmllZCA1KQogcHJpbnQoIlxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKQogcHJpbnQoIkNvcmUgPDwzPj46IHJlYWQgbmV3IGJsb2NrTnVtICIsZW5kPScnKQogcHJpbnQoOSxlbmQ9JyAnKSNibG9ja051bQogcHJpbnQoIiBjb25mbGljdHMgd2l0aCBjdXJyZW50IG1vZGlmaWVkIGJsb2NrTnVtIHRoZW4gbWFrZSByZXBsYWNlbWVudCBhbmQgdXBkYXRlIG1lbW9yeSIpCiBidXNbMF09InJlYWRfbWlzcyIKIHhbOV0gPSBjYWNoM1ZbOSU0XSAjbWVtb3J5IHdyaXRlIGJhY2sKICM5PT09PT4gYmxvY2sgbnVtIAogYnVzWzFdPTMKIGJ1c1syXT05CiBwcmludChidXNMYWJlbHMpCiBwcmludChidXMpCiB2WzklNF0gPSAxCiBkWzklNF0gPSAwCiBjYWNoM1s5JTRdPTkKIGNhY2gzVls5JTRdID0geFs5XQoKIGZvciBpIGluIHJhbmdlKDIqOTk5OTk5OSk6ICNkZWxheQogICAgIHBhc3MKICAgIAogI3JlYWQgbWlzcyAoY29uZmxpY3Qgd2l0aCBibG9jayBzaGFyZWQgKQogcHJpbnQoIlxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4iKQogcHJpbnQoIkNvcmUgPDwzPj46IHJlYWQgbmV3IGJsb2NrTnVtIDogIixlbmQ9JycpCiBwcmludCgxMixlbmQ9JyAgJykjYmxvY2tOdW0KIHByaW50KCIgY29uZmxpY3RzIHdpdGggY3VycmVudCBzaGFyZWQgIGJsb2NrIHRoZW4gbWFrZSByZXBsYWNlbWVudCIpCiBidXNbMF09InJlYWRfbWlzcyIKICN4X3NoYXJlZFtibG9ja051bV0tPTEKIHhbMF0gPSBjYWNoM1ZbMTYlNF0gI21lbW9yeSB3cml0ZSBiYWNrCiBidXNbMV09MyAjY29yZU51bQogYnVzWzJdPTEyICNibG9ja051bQogcHJpbnQoYnVzTGFiZWxzKQogcHJpbnQoYnVzKQogdlsxMiU0XSA9IDEKIGRbMTIlNF0gPSAwCiBzWzEyJTRdID0gMQogY2FjaDNbMTIlNF09MTIKIGNhY2gzVlsxMiU0XSA9IHhbMTJdCiBmb3IgaSBpbiByYW5nZSgyKjk5OTk5OTkpOiAjZGVsYXkKICAgICBwYXNzCiN3cml0ZSBtaXNzIChibG9jayBpbnZhbGlkIGJlY29tZSBtb2RpZmllZCApCiBwcmludCgiXG49PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiIpCiBwcmludCgiQ29yZSA8PDM+Pjogd3JpdGUgbmV3IGJsb2NrTnVtIDogIixlbmQ9JycpCiBwcmludCgxNSxlbmQ9JyAgJykjYmxvY2tOdW0KIHByaW50KCIgdGhlbiB0aGUgYmxvY2sgaW52YWxpZCBiZWNvbWUgbW9kaWZpZWQiKQogYnVzWzBdPSJ3cml0ZV9taXNzIgogYnVzWzFdPTMgI2NvcmVOdW0KIGJ1c1syXT0xNSAjYmxvY2tOdW0KIHByaW50KGJ1c0xhYmVscykKIHByaW50KGJ1cykKIHZbMTUlNF0gPSAxCiBkWzE1JTRdID0gMQogeFsxNV0gPSAxNTUKIGNhY2gzWzE1JTRdPTE1CiBjYWNoM1ZbMTUlNF0gPSB4WzE1XQoKIz09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQppZiBfX25hbWVfXyA9PSAnX19tYWluX18nOiAgICAKCiAgZm9yIGkgaW4gcmFuZ2UoNTApOgogICAgICB4LmFwcGVuZChpKQogIHByaW50KHgpCiAgdDEgPSBUaHJlYWQodGFyZ2V0PWZ1bjEsIGFyZ3M9KCkpCiAgdDMgPSBUaHJlYWQodGFyZ2V0PWZ1bjMsIGFyZ3M9KCkpCgogIHQxLnN0YXJ0KCkKICB0My5zdGFydCgpIAogIHQxLmpvaW4oKQogIHQzLmpvaW4oKQ==