Acknowledgement The main idea of the microbial analysis and the phyloseq dataset are coming from this paper Temporal and spatial variation of the human microbiota during pregnancy The idea which is underlying this analysis is to use clustering to discover the dynamic of the gut community via Community State Types (CST). CSTs are discrete set of clusters.
Initialize:
## [1] '1.34.0'
## [1] '3.3.5'
## [1] '2.1.2'
## [1] '1.2.6'
## [1] '0.8.6'
Cluster into CSTs
The vaginal community is dominated by closely related, but functionally distinct, Lactobacillus species. Therefore it is better to use a non-phylogenetically aware distance measure so as to be able to separate these species. Start with an MDS (or PCoA) ordination: 
## [1] 42.210864 22.612218 12.083443 9.496256 8.919936 6.947028 6.888458
## [8] 5.240856 4.622571 4.539161 4.246411 3.870323 3.374326 3.117964
## [15] 2.861045 2.852497 2.468666 2.355515 2.090535 1.991523
## [1] -0.3676292 -0.3957017 -0.4337434 -0.4744555 -0.5301270 -0.8299508
Denoise distance matrix
We would like to clean some of the noise from the data by restricting this to the truly significant dimensions. The top 5 eigenvalues are clearly very significant, but let’s keep all the positive eigenvalues that clearly exceed the magnitude of the smallest negative eigenvalues:
h_sub5 <- hist(evs[6:length(evs)], 100)

plot(h_sub5$mids, h_sub5$count, log="y", type='h', lwd=10, lend=2)

Looks like eigenvalues 6 and 7 still stand out, so we’ll go with 7 MDS dimensions.
Determine number of clusters
We will use the gap statistic to indicate the number of clusters in this data: 
The gap statistic strongly suggests at least three clusters, but makes another big jump at K=5 before the slope gets a lot smaller. So, K=5 it is.
Cluster into CSTs
Perform PAM 5-fold clusters:
Evaluate clustering
Inspect the results in MDS and NMDS ordinations:
## Run 0 stress 0.18648
## Run 1 stress 0.190787
## Run 2 stress 0.1862701
## ... New best solution
## ... Procrustes: rmse 0.01168006 max resid 0.09976727
## Run 3 stress 0.1933471
## Run 4 stress 0.201474
## Run 5 stress 0.1954427
## Run 6 stress 0.1922218
## Run 7 stress 0.1879763
## Run 8 stress 0.1921214
## Run 9 stress 0.1884075
## Run 10 stress 0.2235917
## Run 11 stress 0.1919761
## Run 12 stress 0.198366
## Run 13 stress 0.1877754
## Run 14 stress 0.190696
## Run 15 stress 0.187102
## Run 16 stress 0.1891335
## Run 17 stress 0.1956618
## Run 18 stress 0.1917857
## Run 19 stress 0.1842801
## ... New best solution
## ... Procrustes: rmse 0.01003169 max resid 0.09694101
## Run 20 stress 0.200065
## *** No convergence -- monoMDS stopping criteria:
## 1: no. of iterations >= maxit
## 11: stress ratio > sratmax
## 8: scale factor of the gradient < sfgrmin

Post hoc
Post hoc by implementing Conover’s test for the significant p_values using shannon index with adjusted p_value is (Benjamini-Hochberg).

LS0tDQp0aXRsZTogJ0NvbW11bml0eSBTdGF0ZSBUeXBlcyAoQ1NUKScNCmF1dGhvcjogIldpc2FtIg0KZGF0ZTogImByIFN5cy5EYXRlKClgIg0Kb3V0cHV0OiANCiAgaHRtbF9kb2N1bWVudDoNCiAgICAgIHRvYzogdHJ1ZQ0KICAgICAgdG9jX2RlcHRoOiA0DQogICAgICB0b2NfZmxvYXQ6IHRydWUNCiAgICAgIGNvZGVfZG93bmxvYWQ6IHRydWUNCi0tLQ0KDQoqKkFja25vd2xlZGdlbWVudCoqIFRoZSBtYWluIGlkZWEgb2YgdGhlIG1pY3JvYmlhbCBhbmFseXNpcyBhbmQgdGhlIHBoeWxvc2VxIGRhdGFzZXQgYXJlIGNvbWluZyBmcm9tIHRoaXMgcGFwZXIgW1RlbXBvcmFsIGFuZCBzcGF0aWFsIHZhcmlhdGlvbiBvZiB0aGUgaHVtYW4gbWljcm9iaW90YSBkdXJpbmcgcHJlZ25hbmN5XShodHRwczovL3d3dy5wbmFzLm9yZy9jb250ZW50LzExMi8zNS8xMTA2MCkNClRoZSBpZGVhIHdoaWNoIGlzIHVuZGVybHlpbmcgdGhpcyBhbmFseXNpcyBpcyB0byB1c2UgY2x1c3RlcmluZyB0byBkaXNjb3ZlciB0aGUgZHluYW1pYyBvZiB0aGUgZ3V0IGNvbW11bml0eSB2aWEgQ29tbXVuaXR5IFN0YXRlIFR5cGVzIChDU1QpLiBDU1RzIGFyZSBkaXNjcmV0ZSBzZXQgb2YgY2x1c3RlcnMuDQoNCg0KDQpJbml0aWFsaXplOg0KYGBge3IgaW5pdCwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoInBoeWxvc2VxIik7IHBhY2thZ2VWZXJzaW9uKCJwaHlsb3NlcSIpDQpsaWJyYXJ5KCJnZ3Bsb3QyIik7IHBhY2thZ2VWZXJzaW9uKCJnZ3Bsb3QyIikNCmxpYnJhcnkoImNsdXN0ZXIiKTsgcGFja2FnZVZlcnNpb24oImNsdXN0ZXIiKQ0KbGlicmFyeSgiaWdyYXBoIik7IHBhY2thZ2VWZXJzaW9uKCJpZ3JhcGgiKQ0KbGlicmFyeSgibWFya292Y2hhaW4iKTsgcGFja2FnZVZlcnNpb24oIm1hcmtvdmNoYWluIikNCmxpYnJhcnkoIlJDb2xvckJyZXdlciIpDQpsaWJyYXJ5KCJncmlkRXh0cmEiKQ0KDQpzZXQuc2VlZCgxMDApDQpkZWZhdWx0LnBhciA8LSBwYXIobm8ucmVhZG9ubHkgPSBUUlVFKQ0Kb3B0aW9ucyhzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpDQp0aGVtZV9zZXQodGhlbWVfYncoKSkNCiMgRVhDTFVERU1BUkdJTkFMIGlzIGEgZmxhZyB0byBleGNsdWRlIG1hcmdpbmFsbHkgcHJldGVybSBiaXJ0aHMgKD0zNyB3ZWVrcykgaW4gdGhlIGxhdGVyIGFuYWx5c2lzDQpFWENMVURFTUFSR0lOQUwgPSBUUlVFDQpgYGANCg0KDQoqICoqUGh5bG9zZXEgZGF0YXNldCoqDQpGcm9tIHRoZSBzYW1lIHBhcGVyIFtUZW1wb3JhbCBhbmQgc3BhdGlhbCB2YXJpYXRpb24gb2YgdGhlIGh1bWFuIG1pY3JvYmlvdGEgZHVyaW5nIHByZWduYW5jeV0oaHR0cHM6Ly93d3cucG5hcy5vcmcvY29udGVudC8xMTIvMzUvMTEwNjApDQoNCiMjIyBEYXRhc2V0IGZyb20gc3Rvb2wNCg0KDQpgYGB7ciBkYXRhX3ZhZ2luYSwgZWNobz1ULCBtZXNzYWdlPUZBTFNFLCBlcnJvcj1GQUxTRX0NCg0KZGE8LSBsb2FkKCdSREEvUHJlZ25hbmN5Q2xvc2VkMTUuUmRhdGEnKQ0Kc2l0ZSA8LSAiU3Rvb2wiDQpwaHkgPC0gUFNQcmVnW1tzaXRlXV0NCnBoeQ0KDQpgYGANCioqUmVtb3ZlIHJhcmUgdGF4YSoqIA0KVHJhbnNmb3JtIHRoZSBkYXRhIChwcm9wb3J0aW9ucyk6DQpgYGB7ciB0cmFuc2Zvcm0tZGF0YSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCnBoeV9jb21wIDwtIHRyYW5zZm9ybV9zYW1wbGVfY291bnRzKHBoeSwgZnVuY3Rpb24oT1RVKSBPVFUvc3VtKE9UVSkpDQpwaHlfY29tcDwtcHJ1bmVfdGF4YSh0YXhhX3N1bXMocGh5X2NvbXApID4gMCwgcGh5X2NvbXApDQpwaHlfY29tcA0KDQpgYGANCldlIGFyZSBub3QgZG9pbmcgZGlmZmVyZW50aWFsIGFidW5kYW5jZSBhbmFseXNpcyBoZXJlLCBzbyB0aGUgcHJvcG9ydGlvbiB0cmFuc2Zvcm1hdGlvbiBpcyB1c2VkIGZvciBleHBsb3JhdG9yeSBhbmFseXNlcyBvbmx5Lg0KDQojIENsdXN0ZXIgaW50byBDU1RzDQoNClRoZSB2YWdpbmFsIGNvbW11bml0eSBpcyBkb21pbmF0ZWQgYnkgY2xvc2VseSByZWxhdGVkLCBidXQgZnVuY3Rpb25hbGx5IGRpc3RpbmN0LCBMYWN0b2JhY2lsbHVzIHNwZWNpZXMuIFRoZXJlZm9yZSBpdCBpcyBiZXR0ZXIgdG8gdXNlIGEgbm9uLXBoeWxvZ2VuZXRpY2FsbHkgYXdhcmUgZGlzdGFuY2UgbWVhc3VyZSBzbyBhcyB0byBiZSBhYmxlIHRvIHNlcGFyYXRlIHRoZXNlIHNwZWNpZXMuIFN0YXJ0IHdpdGggYW4gTURTIChvciBQQ29BKSBvcmRpbmF0aW9uOg0KYGBge3IgTURTLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KYnJheWRpc3QgPC0gcGh5bG9zZXE6OmRpc3RhbmNlKHBoeV9jb21wLCBtZXRob2Q9ImJyYXkiKQ0Kb3JkID0gb3JkaW5hdGUocGh5X2NvbXAsIG1ldGhvZCA9ICJNRFMiLCBkaXN0YW5jZSA9IGJyYXlkaXN0KQ0KcGxvdF9zY3JlZShvcmQpICsgeGxpbShhcy5jaGFyYWN0ZXIoc2VxKDEsMTIpKSkgKyBnZ3RpdGxlKCJNRFMtYnJheSBvcmRpbmF0aW9uIGVpZ2VudmFsdWVzIikNCmV2cyA8LSBvcmQkdmFsdWUkRWlnZW52YWx1ZXMNCnByaW50KGV2c1sxOjIwXSkNCnByaW50KHRhaWwoZXZzKSkNCmBgYA0KDQojIyBEZW5vaXNlIGRpc3RhbmNlIG1hdHJpeA0KDQpXZSB3b3VsZCBsaWtlIHRvIGNsZWFuIHNvbWUgb2YgdGhlIG5vaXNlIGZyb20gdGhlIGRhdGEgYnkgcmVzdHJpY3RpbmcgdGhpcyB0byB0aGUgdHJ1bHkgc2lnbmlmaWNhbnQgZGltZW5zaW9ucy4gVGhlIHRvcCA1IGVpZ2VudmFsdWVzIGFyZSBjbGVhcmx5IHZlcnkgc2lnbmlmaWNhbnQsIGJ1dCBsZXQncyBrZWVwIGFsbCB0aGUgcG9zaXRpdmUgZWlnZW52YWx1ZXMgdGhhdCBjbGVhcmx5IGV4Y2VlZCB0aGUgbWFnbml0dWRlIG9mIHRoZSBzbWFsbGVzdCBuZWdhdGl2ZSBlaWdlbnZhbHVlczoNCmBgYHtyIFBDb0EtY3V0b2ZmMiwgd2FybmluZz1GQUxTRX0NCmhfc3ViNSA8LSBoaXN0KGV2c1s2Omxlbmd0aChldnMpXSwgMTAwKQ0KcGxvdChoX3N1YjUkbWlkcywgaF9zdWI1JGNvdW50LCBsb2c9InkiLCB0eXBlPSdoJywgbHdkPTEwLCBsZW5kPTIpDQpgYGANCg0KTG9va3MgbGlrZSBlaWdlbnZhbHVlcyA2IGFuZCA3IHN0aWxsIHN0YW5kIG91dCwgc28gd2UnbGwgZ28gd2l0aCA3IE1EUyBkaW1lbnNpb25zLg0KDQojIyBEZXRlcm1pbmUgbnVtYmVyIG9mIGNsdXN0ZXJzDQpXZSB3aWxsIHVzZSB0aGUgZ2FwIHN0YXRpc3RpYyB0byBpbmRpY2F0ZSB0aGUgbnVtYmVyIG9mIGNsdXN0ZXJzIGluIHRoaXMgZGF0YToNCmBgYHtyIGdhcC1zdGF0LCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KTkRJTSA8LSA3DQp4IDwtIG9yZCR2ZWN0b3JzWywxOk5ESU1dICAjIHJvd3M9c2FtcGxlLCBjb2xzPU1EUyBheGVzLCBlbnRyaWVzID0gdmFsdWUNCnBhbVBDb0EgPSBmdW5jdGlvbih4LCBrKSB7DQogICAgbGlzdChjbHVzdGVyID0gcGFtKHhbLDE6Ml0sIGssIGNsdXN0ZXIub25seSA9IFRSVUUpKQ0KfQ0KZ3MgPSBjbHVzR2FwKHgsIEZVTiA9IHBhbVBDb0EsIEsubWF4ID0gMTIsIEIgPSA1MCkNCnBsb3RfY2x1c2dhcChncykgKyBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzPWMoc2VxKDAsIDEyLCAyKSkpDQpgYGANCg0KVGhlIGdhcCBzdGF0aXN0aWMgc3Ryb25nbHkgc3VnZ2VzdHMgYXQgbGVhc3QgdGhyZWUgY2x1c3RlcnMsIGJ1dCBtYWtlcyBhbm90aGVyIGJpZyBqdW1wIGF0IEs9NSBiZWZvcmUgdGhlIHNsb3BlIGdldHMgYSBsb3Qgc21hbGxlci4gU28sIEs9NSBpdCBpcy4NCg0KIyMgQ2x1c3RlciBpbnRvIENTVHMNCg0KUGVyZm9ybSBQQU0gNS1mb2xkIGNsdXN0ZXJzOg0KYGBge3IgcGFtLWs1LCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KSyA8LSA1DQp4IDwtIG9yZCR2ZWN0b3JzWywxOk5ESU1dDQpjbHVzdCA8LSBhcy5mYWN0b3IocGFtKHgsIGs9SywgY2x1c3Rlci5vbmx5PVQpKQ0KIyBTV0FQUElORyBUSEUgQVNTSUdOTUVOVCBPRiAyIEFORCAzIFRPIE1BVENIIFJBVkVMIENTVCBFTlVNRVJBVElPTg0KY2x1c3RbY2x1c3Q9PTJdIDwtIE5BDQpjbHVzdFtjbHVzdD09M10gPC0gMg0KY2x1c3RbaXMubmEoY2x1c3QpXSA8LSAzDQpzYW1wbGVfZGF0YShwaHlfY29tcCkkQ1NUIDwtIGNsdXN0DQpDU1RzIDwtIGFzLmNoYXJhY3RlcihzZXEoSykpDQpgYGANCg0KIyMgRXZhbHVhdGUgY2x1c3RlcmluZw0KDQpJbnNwZWN0IHRoZSByZXN1bHRzIGluIE1EUyBhbmQgTk1EUyBvcmRpbmF0aW9uczoNCmBgYHtyIHNlZS1wYW0tazUsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQpDU1RDb2xvcnMgPC0gYnJld2VyLnBhbCg2LCJQYWlyZWQiKVtjKDEsMywyLDUsNCw2KV0gIyBMZW5ndGggNiBmb3IgY29uc2lzdGVuY3kgd2l0aCBwcmUtcmV2aXNpb24gDQpuYW1lcyhDU1RDb2xvcnMpIDwtIENTVHMNCkNTVENvbG9yU2NhbGUgPC0gc2NhbGVfY29sb3VyX21hbnVhbChuYW1lID0gIkNTVCIsIHZhbHVlcyA9IENTVENvbG9yc1sxOjVdKQ0KQ1NURmlsbFNjYWxlIDwtIHNjYWxlX2ZpbGxfbWFudWFsKG5hbWUgPSAiQ1NUIiwgdmFsdWVzID0gQ1NUQ29sb3JzWzE6NV0pDQoNCm9rPC1vcmRpbmF0ZShwaHlfY29tcCwgbWV0aG9kPSJOTURTIiwgZGlzdGFuY2U9YnJheWRpc3QpDQoNCmtuaXRyOjpvcHRzX2NodW5rJHNldChyZXN1bHRzID0gImhpZGUiKQ0KYGBgDQoNCg0KYGBge3Igc2VlLXBhbS1wbG90LCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KcGxvdF9vcmRpbmF0aW9uKHBoeV9jb21wLG9rICwgY29sb3I9IkNTVCIpICsgQ1NUQ29sb3JTY2FsZSArIGdndGl0bGUoIk5NRFMgLS0gYnJheSAtLSBCeSBDbHVzdGVyIikNCg0KYGBgDQoNCiMgSGVhdG1hcHMgZm9yIHRheGEgcGVyIGNsdXN0ZXJzDQpUaGUgb3JkaW5hdGlvbnMgb2ZmZXIgc3VwcG9ydCBmb3IgdGhlc2UgYmVpbmcgbGVnaXRpbWF0ZSBjbHVzdGVycywgZXZlbiBpZiB0aGV5IGFyZSBub3QgcGVyZmVjdCBhbmQgc29tZSBzYW1wbGVzIGxvb2sgbGlrZSB0aGV5IG1pZ2h0IGJlIG1peHR1cmVzIG9mIHR3byBjbHVzdGVycy4gTGV0J3MgdGFrZSBhIGxvb2sgYXQgdGhlIGhlYXRtYXBzIG9mIGVhY2ggY2x1c3RlciBmb3IgYWRkaXRpb25hbCBwZXJzcGVjdGl2ZToNCg0KYGBge3IgY2x1c3QtZGl2ZXJzZSwgbWVzc2FnZT1GQUxTRSwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRSwgb3V0LndpZHRoPSI1MCUifQ0KI3RheGEub3JkZXIgPC0gbmFtZXMoc29ydCh0YXhhX3N1bXMocGh5X2NvbXApKSkNCmZvcihDU1QgaW4gQ1NUcykgew0KICBwc2htIDwtIHBydW5lX3RheGEobmFtZXMoc29ydCh0YXhhX3N1bXMocGh5X2NvbXApLCBUKSlbMTozMF0sIHBoeV9jb21wKQ0KICBwc2htIDwtIHBydW5lX3NhbXBsZXMoc2FtcGxlX2RhdGEocHNobSkkQ1NUID09IENTVCwgcHNobSkNCiAgcHJpbnQocGxvdF9oZWF0bWFwKHBzaG0sIHRheGEubGFiZWw9IlNwZWNpZXMiLCB0YXhhLm9yZGVyPXRheGEub3JkZXIpICsgZ2d0aXRsZShwYXN0ZSgiQ1NUOiIsIENTVCkpKQ0KDQoNCn0NCg0KYGBgDQoNCg0KDQpgYGB7ciBwaHlfMzAsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0V9DQp0YXhhLm9yZGVyMTwtbmFtZXMoc29ydCh0YXhhX3N1bXMocHNobSksIFQpKVsxOjMwXQ0KDQpwaHlfMzA8LXBydW5lX3RheGEodGF4YS5vcmRlcjEsIHBoeSkNCiMjIyBDaGVjayB1cCBmb3IgcmFuZG9tDQojVmlldyhvdHVfdGFibGUocGh5XzMwKUAuRGF0YVsnMTkwMTAwMjI4OCcsJzQ0NjgyMzQnXSkNCiNWaWV3KG90dV90YWJsZShwaHkpQC5EYXRhWycxOTAxMDAyMjg4JywnNDQ2ODIzNCddKQ0KI1ZpZXcob3R1X3RhYmxlKHBoeV9jb21wKUAuRGF0YVsnMTkwMTAwMjI4OCcsJzQ0NjgyMzQnXSkNCnBoeV8zMA0KYGBgDQoNCg0KYGBge3IgcGh5XzMwX21ldGFkYXRhLCBtZXNzYWdlPUZBTFNFLCBlY2hvPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQ0KdGF4YS5vcmRlciA8LSBuYW1lcyhzb3J0KHRheGFfc3VtcyhwaHlfY29tcCkpKQ0KZGF0YWxpc3Q8LWxpc3QoKQ0KZm9yKENTVCBpbiBDU1RzKSB7DQogIHBzaG0gPC0gcHJ1bmVfdGF4YShuYW1lcyhzb3J0KHRheGFfc3VtcyhwaHlfY29tcCksIFQpKVsxOjMwXSwgcGh5X2NvbXApDQogIHBzaG0gPC0gcHJ1bmVfc2FtcGxlcyhzYW1wbGVfZGF0YShwc2htKSRDU1QgPT0gQ1NULCBwc2htKQ0KICBkZjwtIGdldF92YXJpYWJsZShwc2htKQ0KICANCiAgZGF0YWxpc3RbW0NTVF1dIDwtIGRmDQoNCn0NCmRmMTwtZG8uY2FsbChyYmluZC5kYXRhLmZyYW1lLCBkYXRhbGlzdCkNCnJvd25hbWVzKGRmMSk8LWRmMSRTYW1wbGVJRA0Kc2FtcGxlX2RhdGEocGh5XzMwKTwtIGRmMQ0KYGBgDQoNCg0KIyBCb3hwbG90cyANCkJveHBsb3RzIGZvciBlYWNoICoqU3BlY2llcyoqIGluIHRoZSBmaXZlIGNsdXN0ZXJzLiBXZSB3aWxsIGludmVzdGlnYXRlIHNoYW5ub24gaW5kZXggd2l0aCBub24gcGFyYW1ldHJpYyBLcnVza2FsIHRlc3QgZm9yIGVhY2ggdGF4YSBhbW9uZyB0aGUgZml2ZSBjbHVzdGVycw0KDQpgYGB7ciBjbHVzdC1kaXZlcnNlX2JveHBsb3QsIG1lc3NhZ2U9RkFMU0UsIGVjaG89RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG91dC53aWR0aD0iMjUlIn0NCnRoZW1lX3NldCh0aGVtZV9idyhiYXNlX3NpemUgPSAyMCkpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoZ2diZWVzd2FybSkNCmxpYnJhcnkoY29ub3Zlci50ZXN0KQ0KI2xpYnJhcnkobWljcm9iaW9tZSkNCmRmMSRzaGFubm9uPC1lc3RpbWF0ZV9yaWNobmVzcyhwaHlfMzAsIG1lYXN1cmVzID0gJ1NoYW5ub24nKQ0KZGYxJENTVDwtZmFjdG9yKGRmMSRDU1QsIGxldmVscyA9IGMoJzEnLCcyJywnMycsJzQnLCc1JykpDQoNCiNwaHlfMzBfY29tcDwtdHJhbnNmb3JtX3NhbXBsZV9jb3VudHMocGh5XzMwLCBmdW5jdGlvbihPVFUpIE9UVS9zdW0oT1RVKSkNCg0KI2lkZW50aWNhbCh0KGdldF90YXhhKHBoeV8zMCkpLCBhYnVuZGFuY2VzKHBoeV8zMCkpDQpmb3IgKHRheCBpbiByZXYodGF4YS5vcmRlcjEpKSB7DQogIGRmMSR0YXhhPC0gdChnZXRfdGF4YShwaHlfMzBfY29tcCkpW3RheCxdDQogICNkZiR0YXhhPC0gb3R1X3RhYmxlKHBzKUAuRGF0YVt0YXgsXQ0KICBwdjwtIHJvdW5kKGtydXNrYWwudGVzdChzaGFubm9uJFNoYW5ub24gfiBDU1QsIGRhdGEgPSBkZjEpJHAudmFsdWUsIDMpDQogICNwdl9zaGFuPC0gcm91bmQoa3J1c2thbC50ZXN0KHNoYW5ub24kU2hhbm5vbiB+IENTVCwgZGF0YSA9IGRmMSkkcC52YWx1ZSwgMykNCiAgdDwtIGFzLmRhdGEuZnJhbWUodGF4X3RhYmxlKHBoeV8zMF9jb21wKVt0YXgsXSkkU3BlY2llcw0KICBwcmludCh0KQ0KICBwPC0gZ2dwbG90KGRmMSwgYWVzKHggPSBmYWN0b3IoQ1NUKSwgeSA9IHRheGEpKSsgeWxpbSgwLDEpICsgZ2VvbV9iZWVzd2FybShjb2xvciA9ICJkYXJrYmx1ZSIsIHNpemU9IDAuMykrIGdndGl0bGUocGFzdGUwKHQpKSsgeWxhYigiUmVsYXRpdmUgYWJ1bmRhbmNlIikgK3hsYWIoIkNvbW11bml0eSBTdGF0ZSBUeXBlcyAoQ1NUKSIpKyBsYWJzKHRpdGxlID0gcGFzdGUwKHQpLCBzdWJ0aXRsZSA9IHBhc3RlMCgncF92YWx1ZSBmb3IgU2hhbm5vbiBpczogJywgcHYpKSANCiAgcHJpbnQocCkNCg0KfQ0KYGBgDQoNCiMgUG9zdCBob2MNClBvc3QgaG9jIGJ5IGltcGxlbWVudGluZyBDb25vdmVy4oCZcyB0ZXN0IGZvciB0aGUgc2lnbmlmaWNhbnQgcF92YWx1ZXMgdXNpbmcgKipzaGFubm9uIGluZGV4Kiogd2l0aCBhZGp1c3RlZCBwX3ZhbHVlIGlzIChCZW5qYW1pbmktSG9jaGJlcmcpLg0KDQoNCmBgYHtyIHBvc3RfaG9jLCBtZXNzYWdlPUZBTFNFLGV2YWw9VFJVRSwgZWNobz1GQUxTRSwgd2FybmluZz1GQUxTRX0NCmxpYnJhcnkoImNvbm92ZXIudGVzdCIpDQpjb3Y8LWNvbm92ZXIudGVzdDo6Y29ub3Zlci50ZXN0KGRmMSRzaGFubm9uJFNoYW5ub24sIGRmMSRDU1QsIGt3ID0gVCwgbWV0aG9kPSJiaCIpDQoNCnByaW50KGNvdikNCmBgYA0KDQoNCiFbXShwb3N0X2hvYy5wbmcpe3dpZHRoPTE1MCV9DQo=