#include <iostream>
#include <vector>
#include <cmath>
#include <cstdio>
#define infinity 1000000000
using namespace std;
typedef pair<double,double> interval;
int n;
double dist2(double x, double y){
return sqrt(x*x+y*y);
}
double startx,starty;
// Returns the intersection of two intervals. isempty returns false if the intersection is empty
interval intersection(interval i, interval j, bool& isempty){
interval k;
k.first = max(i.first, j.first);
k.second = min(i.second, j.second);
if (k.first > k.second) isempty = true;
return k;
}
// Returns the distance between (px,py) and (vx,vy) or -1 if vx is not contained in curr
double in_intersection(interval curr_i,double vx, double vy,double px,double py){
if (vx < curr_i.first or vx > curr_i.second) return -1;
return dist2(vx-px,vy-py);
}
// What is the minimum distance from (px,py) to the goal(curr_i,vy) in a straight line?
double reach_goal(interval curr_i, double vy, double px, double py){
double distmin = infinity;
double d1,d2,d3;
d1 = in_intersection(curr_i,curr_i.first,vy,startx,starty);
d2 = in_intersection(curr_i,curr_i.second,vy,startx,starty);
d3 = in_intersection(curr_i,startx,vy,startx,starty);
if (d1 > -0.5) distmin = min(distmin, d1);
if (d2 > -0.5) distmin = min(distmin, d2);
if (d3 > -0.5) distmin = min(distmin, d3);
return distmin;
}
// Distance between endpoints. -1 if it is not possible to reach it
double dist[1000][2][1000][2];
int main(){
int t;
cin>>t;
while (t--){
int n;
cin>>n;
vector<pair<double,double> > vx;
vector<double> vy;
cin >> startx >> starty;
for (int i=0;i<n;i++){
double a,b,c;
cin >> c >> a >> b;
vx.push_back(make_pair(a,b));
vy.push_back(c);
}
// Can I reach the i-th endpoint from the start in a straight line?
// -1 for not reaching, != -1 with the distance
double achieve_start[n][2];
// Can I reach the goal from the i-th endpoint in a straight line?
// -1 for not reaching, != -1 with the distance
double achieve_goal[n][2];
// Best path from the start to the gate, possibly zigzagging
double dp[n][2];
// Initialization
for (int i=0;i<n;i++) for (int j=0;j<2;j++) for (int k=0;k<n;k++) for (int l=0;l<2;l++) dist[i][j][k][l]=-1;
for (int i=0;i<n;i++) achieve_start[i][0] = achieve_start[i][1] = achieve_goal[i][0] = achieve_goal[i][1] = -1;
double distmin = infinity;
// We calculate the points reachable from the starting point
interval curr_i = vx[0];
double curr_y = vy[0];
achieve_start[0][0] = dist2(startx-vx[0].first,starty-vy[0]);
achieve_start[0][1] = dist2(startx-vx[0].second,starty-vy[0]);
for (int i=1;i<n;i++){
// We calculate the interval that we can reach in a straight line
curr_i.first = startx + (curr_i.first - startx)*(starty-vy[i]) / (starty-curr_y);
curr_i.second = startx + (curr_i.second - startx)*(starty-vy[i]) / (starty-curr_y);
curr_y = vy[i];
bool empty = false;
curr_i = intersection(curr_i,vx[i],empty);
if (empty) break;
achieve_start[i][0] = in_intersection(curr_i,vx[i].first,vy[i],startx,starty);
achieve_start[i][1] = in_intersection(curr_i,vx[i].second,vy[i],startx,starty);
if (i == n-1){
// We can reach the goal from the start
distmin = reach_goal(curr_i,vy[n-1],startx,starty);
}
}
// Very important. Don't forget this special case.
if (n == 1){
distmin = min(distmin,reach_goal(vx[0],vy[0],startx,starty));
}
// Distance between endpoints of the gates and gate->end
for (int i=0;i<n-1;i++){
for (int j=0;j<2;j++){
if (j == 0) startx = vx[i].first; else startx = vx[i].second;
starty = vy[i];
interval curr_i = vx[i+1];
double curr_y = vy[i+1];
dist[i][j][i+1][0] = dist2(startx-vx[i+1].first,starty-vy[i+1]);
dist[i][j][i+1][1] = dist2(startx-vx[i+1].second,starty-vy[i+1]);
for (int k=i+1;k<n;k++){
curr_i.first = startx + (curr_i.first - startx)*(starty-vy[k]) / (starty-curr_y);
curr_i.second = startx + (curr_i.second - startx)*(starty-vy[k]) / (starty-curr_y);
curr_y = vy[k];
bool empty = false;
curr_i = intersection(curr_i,vx[k],empty);
if (empty) break;
dist[i][j][k][0] = in_intersection(curr_i,vx[k].first,vy[k],startx,starty);
dist[i][j][k][1] = in_intersection(curr_i,vx[k].second,vy[k],startx,starty);
if (k == n-1){
// We can reach the goal (last interval) straight from this point
achieve_goal[i][j] = reach_goal(curr_i,vy[n-1],startx,starty);
}
}
}
}
for (int i=0;i<n;i++) for (int j=0;j<2;j++) dp[i][j] = infinity;
// min distance from the start in a straight line
for (int i=0;i<n;i++) for (int j=0;j<2;j++){
if (achieve_start[i][j] > -0.5) dp[i][j] = achieve_start[i][j];
}
// DP: min. distance from the start possibly zigzagging
for (int i=0;i<n;i++){
for (int j=0;j<2;j++){
for (int k=0;k<i;k++){
for (int l=0;l<2;l++){
if (dist[k][l][i][j] > -0.5){
dp[i][j] = min(dp[i][j], dp[k][l] + dist[k][l][i][j]);
}
}
}
}
}
// We search over the minimum of the sum start->gate + gate->end
for (int i=0;i<n;i++){
for (int j=0;j<2;j++){
if (achieve_goal[i][j] > -0.5){
distmin = min(distmin, achieve_goal[i][j] + dp[i][j]);
}
}
}
printf("%.6lf\n", distmin);
}
return 0;
}
I2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8dmVjdG9yPgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDxjc3RkaW8+CgojZGVmaW5lIGluZmluaXR5IDEwMDAwMDAwMDAKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnR5cGVkZWYgcGFpcjxkb3VibGUsZG91YmxlPiBpbnRlcnZhbDsKCmludCBuOwoKZG91YmxlIGRpc3QyKGRvdWJsZSB4LCBkb3VibGUgeSl7CiAgICAgICByZXR1cm4gc3FydCh4KngreSp5KTsKfQoKZG91YmxlIHN0YXJ0eCxzdGFydHk7CgovLyBSZXR1cm5zIHRoZSBpbnRlcnNlY3Rpb24gb2YgdHdvIGludGVydmFscy4gaXNlbXB0eSByZXR1cm5zIGZhbHNlIGlmIHRoZSBpbnRlcnNlY3Rpb24gaXMgZW1wdHkKaW50ZXJ2YWwgaW50ZXJzZWN0aW9uKGludGVydmFsIGksIGludGVydmFsIGosIGJvb2wmIGlzZW1wdHkpewogICAgICAgICBpbnRlcnZhbCBrOwogICAgICAgICBrLmZpcnN0ID0gbWF4KGkuZmlyc3QsIGouZmlyc3QpOwogICAgICAgICBrLnNlY29uZCA9IG1pbihpLnNlY29uZCwgai5zZWNvbmQpOwogICAgICAgICBpZiAoay5maXJzdCA+IGsuc2Vjb25kKSBpc2VtcHR5ID0gdHJ1ZTsKICAgICAgICAgcmV0dXJuIGs7Cn0KCi8vIFJldHVybnMgdGhlIGRpc3RhbmNlIGJldHdlZW4gKHB4LHB5KSBhbmQgKHZ4LHZ5KSBvciAtMSBpZiB2eCBpcyBub3QgY29udGFpbmVkIGluIGN1cnIKZG91YmxlIGluX2ludGVyc2VjdGlvbihpbnRlcnZhbCBjdXJyX2ksZG91YmxlIHZ4LCBkb3VibGUgdnksZG91YmxlIHB4LGRvdWJsZSBweSl7CiAgICAgICBpZiAodnggPCBjdXJyX2kuZmlyc3Qgb3IgdnggPiBjdXJyX2kuc2Vjb25kKSByZXR1cm4gLTE7CiAgICAgICByZXR1cm4gZGlzdDIodngtcHgsdnktcHkpOwp9CgovLyBXaGF0IGlzIHRoZSBtaW5pbXVtIGRpc3RhbmNlIGZyb20gKHB4LHB5KSB0byB0aGUgZ29hbChjdXJyX2ksdnkpIGluIGEgc3RyYWlnaHQgbGluZT8KZG91YmxlIHJlYWNoX2dvYWwoaW50ZXJ2YWwgY3Vycl9pLCBkb3VibGUgdnksIGRvdWJsZSBweCwgZG91YmxlIHB5KXsKICAgICAgIGRvdWJsZSBkaXN0bWluID0gaW5maW5pdHk7CiAgICAgICBkb3VibGUgZDEsZDIsZDM7CiAgICAgICBkMSA9IGluX2ludGVyc2VjdGlvbihjdXJyX2ksY3Vycl9pLmZpcnN0LHZ5LHN0YXJ0eCxzdGFydHkpOwogICAgICAgZDIgPSBpbl9pbnRlcnNlY3Rpb24oY3Vycl9pLGN1cnJfaS5zZWNvbmQsdnksc3RhcnR4LHN0YXJ0eSk7CiAgICAgICBkMyA9IGluX2ludGVyc2VjdGlvbihjdXJyX2ksc3RhcnR4LHZ5LHN0YXJ0eCxzdGFydHkpOwogICAgICAgaWYgKGQxID4gLTAuNSkgZGlzdG1pbiA9IG1pbihkaXN0bWluLCBkMSk7CiAgICAgICBpZiAoZDIgPiAtMC41KSBkaXN0bWluID0gbWluKGRpc3RtaW4sIGQyKTsKICAgICAgIGlmIChkMyA+IC0wLjUpIGRpc3RtaW4gPSBtaW4oZGlzdG1pbiwgZDMpOwogICAgICAgcmV0dXJuIGRpc3RtaW47Cn0KCgovLyBEaXN0YW5jZSBiZXR3ZWVuIGVuZHBvaW50cy4gLTEgaWYgaXQgaXMgbm90IHBvc3NpYmxlIHRvIHJlYWNoIGl0CmRvdWJsZSBkaXN0WzEwMDBdWzJdWzEwMDBdWzJdOwoKaW50IG1haW4oKXsKICAgIGludCB0OwogICAgY2luPj50OwogICAgd2hpbGUgKHQtLSl7CiAgICAgICAgICBpbnQgbjsKICAgICAgICAgIGNpbj4+bjsKICAgICAgICAgIHZlY3RvcjxwYWlyPGRvdWJsZSxkb3VibGU+ID4gdng7CiAgICAgICAgICB2ZWN0b3I8ZG91YmxlPiB2eTsKICAgICAgICAgIGNpbiA+PiBzdGFydHggPj4gc3RhcnR5OwogICAgICAgICAgZm9yIChpbnQgaT0wO2k8bjtpKyspewogICAgICAgICAgICAgIGRvdWJsZSBhLGIsYzsKICAgICAgICAgICAgICBjaW4gPj4gYyA+PiBhID4+IGI7CiAgICAgICAgICAgICAgdngucHVzaF9iYWNrKG1ha2VfcGFpcihhLGIpKTsKICAgICAgICAgICAgICB2eS5wdXNoX2JhY2soYyk7CiAgICAgICAgICB9CiAgICAgICAgICAvLyBDYW4gSSByZWFjaCB0aGUgaS10aCBlbmRwb2ludCBmcm9tIHRoZSBzdGFydCBpbiBhIHN0cmFpZ2h0IGxpbmU/CiAgICAgICAgICAvLyAtMSBmb3Igbm90IHJlYWNoaW5nLCAhPSAtMSB3aXRoIHRoZSBkaXN0YW5jZQogICAgICAgICAgZG91YmxlIGFjaGlldmVfc3RhcnRbbl1bMl07CiAgICAgICAgICAvLyBDYW4gSSByZWFjaCB0aGUgZ29hbCBmcm9tIHRoZSBpLXRoIGVuZHBvaW50IGluIGEgc3RyYWlnaHQgbGluZT8KICAgICAgICAgIC8vIC0xIGZvciBub3QgcmVhY2hpbmcsICE9IC0xIHdpdGggdGhlIGRpc3RhbmNlCiAgICAgICAgICBkb3VibGUgYWNoaWV2ZV9nb2FsW25dWzJdOwogICAgICAgICAgLy8gQmVzdCBwYXRoIGZyb20gdGhlIHN0YXJ0IHRvIHRoZSBnYXRlLCBwb3NzaWJseSB6aWd6YWdnaW5nCiAgICAgICAgICBkb3VibGUgZHBbbl1bMl07CiAgICAgICAgICAvLyBJbml0aWFsaXphdGlvbgogICAgICAgICAgZm9yIChpbnQgaT0wO2k8bjtpKyspIGZvciAoaW50IGo9MDtqPDI7aisrKSBmb3IgKGludCBrPTA7azxuO2srKykgZm9yIChpbnQgbD0wO2w8MjtsKyspIGRpc3RbaV1bal1ba11bbF09LTE7CiAgICAgICAgICBmb3IgKGludCBpPTA7aTxuO2krKykgYWNoaWV2ZV9zdGFydFtpXVswXSA9IGFjaGlldmVfc3RhcnRbaV1bMV0gPSBhY2hpZXZlX2dvYWxbaV1bMF0gPSBhY2hpZXZlX2dvYWxbaV1bMV0gPSAtMTsKCiAgICAgICAgICBkb3VibGUgZGlzdG1pbiA9IGluZmluaXR5OwogICAgICAgICAgLy8gV2UgY2FsY3VsYXRlIHRoZSBwb2ludHMgcmVhY2hhYmxlIGZyb20gdGhlIHN0YXJ0aW5nIHBvaW50CiAgICAgICAgICBpbnRlcnZhbCBjdXJyX2kgPSB2eFswXTsKICAgICAgICAgIGRvdWJsZSBjdXJyX3kgPSB2eVswXTsKICAgICAgICAgIGFjaGlldmVfc3RhcnRbMF1bMF0gPSBkaXN0MihzdGFydHgtdnhbMF0uZmlyc3Qsc3RhcnR5LXZ5WzBdKTsKICAgICAgICAgIGFjaGlldmVfc3RhcnRbMF1bMV0gPSBkaXN0MihzdGFydHgtdnhbMF0uc2Vjb25kLHN0YXJ0eS12eVswXSk7CiAgICAgICAgICBmb3IgKGludCBpPTE7aTxuO2krKyl7CiAgICAgICAgICAgICAgLy8gV2UgY2FsY3VsYXRlIHRoZSBpbnRlcnZhbCB0aGF0IHdlIGNhbiByZWFjaCBpbiBhIHN0cmFpZ2h0IGxpbmUKICAgICAgICAgICAgICBjdXJyX2kuZmlyc3QgPSBzdGFydHggKyAoY3Vycl9pLmZpcnN0IC0gc3RhcnR4KSooc3RhcnR5LXZ5W2ldKSAvIChzdGFydHktY3Vycl95KTsKICAgICAgICAgICAgICBjdXJyX2kuc2Vjb25kID0gc3RhcnR4ICsgKGN1cnJfaS5zZWNvbmQgLSBzdGFydHgpKihzdGFydHktdnlbaV0pIC8gKHN0YXJ0eS1jdXJyX3kpOwogICAgICAgICAgICAgIGN1cnJfeSA9IHZ5W2ldOwogICAgICAgICAgICAgIGJvb2wgZW1wdHkgPSBmYWxzZTsKICAgICAgICAgICAgICBjdXJyX2kgPSBpbnRlcnNlY3Rpb24oY3Vycl9pLHZ4W2ldLGVtcHR5KTsKICAgICAgICAgICAgICBpZiAoZW1wdHkpIGJyZWFrOwogICAgICAgICAgICAgIGFjaGlldmVfc3RhcnRbaV1bMF0gPSBpbl9pbnRlcnNlY3Rpb24oY3Vycl9pLHZ4W2ldLmZpcnN0LHZ5W2ldLHN0YXJ0eCxzdGFydHkpOwogICAgICAgICAgICAgIGFjaGlldmVfc3RhcnRbaV1bMV0gPSBpbl9pbnRlcnNlY3Rpb24oY3Vycl9pLHZ4W2ldLnNlY29uZCx2eVtpXSxzdGFydHgsc3RhcnR5KTsKICAgICAgICAgICAgICBpZiAoaSA9PSBuLTEpewogICAgICAgICAgICAgICAgIC8vIFdlIGNhbiByZWFjaCB0aGUgZ29hbCBmcm9tIHRoZSBzdGFydAogICAgICAgICAgICAgICAgIGRpc3RtaW4gPSByZWFjaF9nb2FsKGN1cnJfaSx2eVtuLTFdLHN0YXJ0eCxzdGFydHkpOwogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIC8vIFZlcnkgaW1wb3J0YW50LiBEb24ndCBmb3JnZXQgdGhpcyBzcGVjaWFsIGNhc2UuCiAgICAgICAgICBpZiAobiA9PSAxKXsKICAgICAgICAgICAgIGRpc3RtaW4gPSBtaW4oZGlzdG1pbixyZWFjaF9nb2FsKHZ4WzBdLHZ5WzBdLHN0YXJ0eCxzdGFydHkpKTsKICAgICAgICAgIH0KICAgICAgICAgIC8vIERpc3RhbmNlIGJldHdlZW4gZW5kcG9pbnRzIG9mIHRoZSBnYXRlcyBhbmQgZ2F0ZS0+ZW5kCiAgICAgICAgICBmb3IgKGludCBpPTA7aTxuLTE7aSsrKXsKICAgICAgICAgICAgICBmb3IgKGludCBqPTA7ajwyO2orKyl7CiAgICAgICAgICAgICAgICAgIGlmIChqID09IDApIHN0YXJ0eCA9IHZ4W2ldLmZpcnN0OyBlbHNlIHN0YXJ0eCA9IHZ4W2ldLnNlY29uZDsKICAgICAgICAgICAgICAgICAgc3RhcnR5ID0gdnlbaV07CiAgICAgICAgICAgICAgICAgIGludGVydmFsIGN1cnJfaSA9IHZ4W2krMV07CiAgICAgICAgICAgICAgICAgIGRvdWJsZSBjdXJyX3kgPSB2eVtpKzFdOwogICAgICAgICAgICAgICAgICBkaXN0W2ldW2pdW2krMV1bMF0gPSBkaXN0MihzdGFydHgtdnhbaSsxXS5maXJzdCxzdGFydHktdnlbaSsxXSk7CiAgICAgICAgICAgICAgICAgIGRpc3RbaV1bal1baSsxXVsxXSA9IGRpc3QyKHN0YXJ0eC12eFtpKzFdLnNlY29uZCxzdGFydHktdnlbaSsxXSk7CiAgICAgICAgICAgICAgICAgIGZvciAoaW50IGs9aSsxO2s8bjtrKyspewogICAgICAgICAgICAgICAgICAgICAgY3Vycl9pLmZpcnN0ID0gc3RhcnR4ICsgKGN1cnJfaS5maXJzdCAtIHN0YXJ0eCkqKHN0YXJ0eS12eVtrXSkgLyAoc3RhcnR5LWN1cnJfeSk7CiAgICAgICAgICAgICAgICAgICAgICBjdXJyX2kuc2Vjb25kID0gc3RhcnR4ICsgKGN1cnJfaS5zZWNvbmQgLSBzdGFydHgpKihzdGFydHktdnlba10pIC8gKHN0YXJ0eS1jdXJyX3kpOwogICAgICAgICAgICAgICAgICAgICAgY3Vycl95ID0gdnlba107CiAgICAgICAgICAgICAgICAgICAgICBib29sIGVtcHR5ID0gZmFsc2U7CiAgICAgICAgICAgICAgICAgICAgICBjdXJyX2kgPSBpbnRlcnNlY3Rpb24oY3Vycl9pLHZ4W2tdLGVtcHR5KTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChlbXB0eSkgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICBkaXN0W2ldW2pdW2tdWzBdID0gaW5faW50ZXJzZWN0aW9uKGN1cnJfaSx2eFtrXS5maXJzdCx2eVtrXSxzdGFydHgsc3RhcnR5KTsKICAgICAgICAgICAgICAgICAgICAgIGRpc3RbaV1bal1ba11bMV0gPSBpbl9pbnRlcnNlY3Rpb24oY3Vycl9pLHZ4W2tdLnNlY29uZCx2eVtrXSxzdGFydHgsc3RhcnR5KTsKICAgICAgICAgICAgICAgICAgICAgIGlmIChrID09IG4tMSl7CiAgICAgICAgICAgICAgICAgICAgICAgICAvLyBXZSBjYW4gcmVhY2ggdGhlIGdvYWwgKGxhc3QgaW50ZXJ2YWwpIHN0cmFpZ2h0IGZyb20gdGhpcyBwb2ludAogICAgICAgICAgICAgICAgICAgICAgICAgYWNoaWV2ZV9nb2FsW2ldW2pdID0gcmVhY2hfZ29hbChjdXJyX2ksdnlbbi0xXSxzdGFydHgsc3RhcnR5KTsKICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KCiAgICAgICAgICBmb3IgKGludCBpPTA7aTxuO2krKykgZm9yIChpbnQgaj0wO2o8MjtqKyspIGRwW2ldW2pdID0gaW5maW5pdHk7CgogICAgICAgICAgLy8gbWluIGRpc3RhbmNlIGZyb20gdGhlIHN0YXJ0IGluIGEgc3RyYWlnaHQgbGluZQogICAgICAgICAgZm9yIChpbnQgaT0wO2k8bjtpKyspIGZvciAoaW50IGo9MDtqPDI7aisrKXsKICAgICAgICAgICAgICBpZiAoYWNoaWV2ZV9zdGFydFtpXVtqXSA+IC0wLjUpIGRwW2ldW2pdID0gYWNoaWV2ZV9zdGFydFtpXVtqXTsKICAgICAgICAgIH0KCiAgICAgICAgICAvLyBEUDogbWluLiBkaXN0YW5jZSBmcm9tIHRoZSBzdGFydCBwb3NzaWJseSB6aWd6YWdnaW5nCiAgICAgICAgICBmb3IgKGludCBpPTA7aTxuO2krKyl7CiAgICAgICAgICAgICAgZm9yIChpbnQgaj0wO2o8MjtqKyspewogICAgICAgICAgICAgICAgICBmb3IgKGludCBrPTA7azxpO2srKyl7CiAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBsPTA7bDwyO2wrKyl7CiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGRpc3Rba11bbF1baV1bal0gPiAtMC41KXsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcFtpXVtqXSA9IG1pbihkcFtpXVtqXSwgZHBba11bbF0gKyBkaXN0W2tdW2xdW2ldW2pdKTsKICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICB9CiAgICAgICAgICB9CgogICAgICAgICAgLy8gV2Ugc2VhcmNoIG92ZXIgdGhlIG1pbmltdW0gb2YgdGhlIHN1bSBzdGFydC0+Z2F0ZSArIGdhdGUtPmVuZAogICAgICAgICAgZm9yIChpbnQgaT0wO2k8bjtpKyspewogICAgICAgICAgICAgIGZvciAoaW50IGo9MDtqPDI7aisrKXsKICAgICAgICAgICAgICAgICAgaWYgKGFjaGlldmVfZ29hbFtpXVtqXSA+IC0wLjUpewogICAgICAgICAgICAgICAgICAgICBkaXN0bWluID0gbWluKGRpc3RtaW4sIGFjaGlldmVfZ29hbFtpXVtqXSArIGRwW2ldW2pdKTsKICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIHByaW50ZigiJS42bGZcbiIsIGRpc3RtaW4pOwogICAgfQogICAgcmV0dXJuIDA7Cn0=