// https://p...content-available-to-author-only...j.com/problems/FR_07_03/
#include <iostream>
#include <vector>
#include <string>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <bitset>
#include <complex>
#include <queue>
#include <deque>
#include <map>
#include <stack>
#include <iterator>
#include <list>
#include <set>
using namespace std;
typedef vector<unsigned int> VI;
typedef long long LL;
#define FOR(x, from, to) for(int x = from; x <= (to); ++x)
#define FORD(x, from, to) for(int x = from; x >= (to); – –x)
#define REP(x, n) for(int x = 0; x < (n); ++x)
#define VAR(v, n) __typeof(n) v = (n)
#define ALL(c) (c).begin(), (c).end()
#define SIZE(x) ((int)(x).size())
#define FOREACH(i, c) for(VAR(i, (c).begin()); i != (c).end(); ++i)
#define PB push_back
#define ST first
#define ND second
static int AsciiSpecialCharacters[32] = {33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47 ,58, 59, 60, 61, 62, 63, 64, 91, 92, 93, 94, 95, 96, 123, 124, 125, 126};
void print_msg(string & function, string & msg);
bool is_login_and_password_are_correct(string &, string &);
bool is_lenght_correct(string &, string &);
bool is_login_contain_illegal_char(string &);
bool is_password_meet_criteria(string &);
void print_result(vector<string> & arr);
void print_accounts(map<string, string> & account);
bool is_account_exist(map<string,string> & account, string &);
string change_to_lower_case(string &);
void create_account(map<string, string> & account, string & login, string & password);
bool is_password_correct(map<string,string> & accounts, string & login, string & password);
int main(){
int loginAttemps;
int registerAttemps;
map<string, string> account;
string login;
string password;
vector<string> result;
cout << "register ";
cin >> registerAttemps;
REP(i, registerAttemps){
cin >> login >> password;
if(is_login_and_password_are_correct(login, password)){
if(!is_account_exist(account, login)){
create_account(account, login, password);
result.PB("Zarejestrowano");
}else
{
result.PB("Login zajety");
}
}else{
result.PB("Blad");
}
}
cout << "login ";
cin >> loginAttemps;
REP(i, loginAttemps){
cin >> login >> password;
if(is_account_exist(account, login)){
if(is_password_correct(account, login, password)){
result.PB("Zalogowano");
}else
{
result.PB("Zle haslo");
}
}else
{
result.PB("Konto nie istnieje");
}
}
cout << "register ";
cin >> registerAttemps;
REP(i, registerAttemps){
cin >> login >> password;
if(is_login_and_password_are_correct(login, password)){
if(!is_account_exist(account, login)){
create_account(account, login, password);
result.PB("Zarejestrowano");
}else
{
result.PB("Login zajety");
}
}else{
result.PB("Blad");
}
}
cout << "login ";
cin >> loginAttemps;
REP(i, loginAttemps){
cin >> login >> password;
if(is_account_exist(account, login)){
if(is_password_correct(account, login, password)){
result.PB("Zalogowano");
}else
{
result.PB("Zle haslo");
}
}else
{
result.PB("Konto nie istnieje");
}
}
print_result(result);
return 0;
}
void print_msg(string & function, string & msg){
cout << function << " " << msg << "\n";
}
void print_result(vector<string> & arr){
FOR(i, 0, SIZE(arr)-1){
cout << arr[i] << "\n";
}
}
void print_accounts(map<string, string> & account){
cout << "\n";
FOREACH(it, account){
cout << it->first << " " << it->second << "\n";
}
}
bool is_lenght_correct(string & login, string & password){
if(login.length()<3 || login.length()>12){
return false;
}
if(password.length()<5 || password.length()>15){
return false;
}
return true;
}
bool is_login_contain_illegal_char(string & login){
int character;
FOR(i, 0, login.length()-1){
character = (int)login[i];
FOR(j, 0, 32){
if(character == AsciiSpecialCharacters[j]){
// cout << "Special character detected " << a << endl;
return false;
}
}
}
return true;
}
/* these criteria is:
- number
- special character
- character in upper case
- character in lower case
*/
bool is_password_meet_criteria(string & password){
bool numberOccurence = false;
bool specialCharacterOccurence = false;
bool upperCaseCharacterOccurence = false;
bool lowerCaseCharacterOccurence = false;
FOR(i, 0, password.length()){
if(numberOccurence == false) FOR(n, 48, 57){
if((char)(n) == password[i]){
numberOccurence = true;
}
}
if(specialCharacterOccurence == false) FOR(j, 0, 32){
if(AsciiSpecialCharacters[j] == password[i]){
specialCharacterOccurence = true;
}
}
if(upperCaseCharacterOccurence == false) FOR(c, 65, 90){
if((char)(c) == password[i]){
upperCaseCharacterOccurence = true;
}
}
if(lowerCaseCharacterOccurence == false) FOR(c, 97, 122){
if((char)(c) == password[i]){
lowerCaseCharacterOccurence = true;
}
}
}
if(!(numberOccurence && specialCharacterOccurence && upperCaseCharacterOccurence && lowerCaseCharacterOccurence)){
return false;
}
return true;
}
bool is_login_and_password_are_correct(string & login, string & password){
if(!is_lenght_correct(login, password)){
return false;
}
if(!is_login_contain_illegal_char(login)){
return false;
}
if(!is_password_meet_criteria(password)){
return false;
}
return true;
}
string change_to_lower_case(string & text){
string lower_text = text;
FOR(i, 0, text.length()){
lower_text[i] = tolower(lower_text[i]);
}
return lower_text;
}
void create_account(map<string, string> & account, string & login, string & password){
string lowerCaseLogin = change_to_lower_case(login); // changing login to lower case because it doenst make an odds
account[lowerCaseLogin] = password;
}
bool is_account_exist(map<string,string> & accounts, string & login){
string lowerCaseLogin = change_to_lower_case(login);
FOREACH(it, accounts){
if((it->first.compare(lowerCaseLogin))==0){
return true;
}
}
return false;
}
bool is_password_correct(map<string,string> & accounts, string & login, string & password){
string lowerCaseLogin = change_to_lower_case(login);
FOREACH(it, accounts){
if((it->first.compare(lowerCaseLogin))==0){
if((it->second.compare(password))==0){
return true;
}
}
}
return false;
}
Ly8gaHR0cHM6Ly9wLi4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5qLmNvbS9wcm9ibGVtcy9GUl8wN18wMy8KCiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHZlY3Rvcj4KI2luY2x1ZGUgPHN0cmluZz4KI2luY2x1ZGUgPGNzdGRpbz4KI2luY2x1ZGUgPGNjdHlwZT4KI2luY2x1ZGUgPGNzdHJpbmc+CiNpbmNsdWRlIDxiaXRzZXQ+CiNpbmNsdWRlIDxjb21wbGV4PgojaW5jbHVkZSA8cXVldWU+CiNpbmNsdWRlIDxkZXF1ZT4KI2luY2x1ZGUgPG1hcD4KI2luY2x1ZGUgPHN0YWNrPgojaW5jbHVkZSA8aXRlcmF0b3I+CiNpbmNsdWRlIDxsaXN0PgojaW5jbHVkZSA8c2V0PgoKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKCnR5cGVkZWYgdmVjdG9yPHVuc2lnbmVkIGludD4gVkk7CnR5cGVkZWYgbG9uZyBsb25nIExMOwojZGVmaW5lIEZPUih4LCBmcm9tLCB0bykgZm9yKGludCB4ID0gZnJvbTsgeCA8PSAodG8pOyArK3gpCiNkZWZpbmUgRk9SRCh4LCBmcm9tLCB0bykgZm9yKGludCB4ID0gZnJvbTsgeCA+PSAodG8pOyDigJMg4oCTeCkKI2RlZmluZSBSRVAoeCwgbikgZm9yKGludCB4ID0gMDsgeCA8IChuKTsgKyt4KQojZGVmaW5lIFZBUih2LCBuKSBfX3R5cGVvZihuKSB2ID0gKG4pCiNkZWZpbmUgQUxMKGMpIChjKS5iZWdpbigpLCAoYykuZW5kKCkKI2RlZmluZSBTSVpFKHgpICgoaW50KSh4KS5zaXplKCkpCiNkZWZpbmUgRk9SRUFDSChpLCBjKSBmb3IoVkFSKGksIChjKS5iZWdpbigpKTsgaSAhPSAoYykuZW5kKCk7ICsraSkKI2RlZmluZSBQQiBwdXNoX2JhY2sKI2RlZmluZSBTVCBmaXJzdAojZGVmaW5lIE5EIHNlY29uZAoKc3RhdGljIGludCBBc2NpaVNwZWNpYWxDaGFyYWN0ZXJzWzMyXSA9IHszMywgMzQsIDM1LCAzNiwgMzcsIDM4LCAzOSwgNDAsIDQxLCA0MiwgNDMsIDQ0LCA0NSwgNDYsIDQ3ICw1OCwgNTksIDYwLCA2MSwgNjIsIDYzLCA2NCwgOTEsIDkyLCA5MywgOTQsIDk1LCA5NiwgMTIzLCAxMjQsIDEyNSwgMTI2fTsKCnZvaWQgcHJpbnRfbXNnKHN0cmluZyAmIGZ1bmN0aW9uLCAgc3RyaW5nICYgbXNnKTsKYm9vbCBpc19sb2dpbl9hbmRfcGFzc3dvcmRfYXJlX2NvcnJlY3Qoc3RyaW5nICYsIHN0cmluZyAmKTsKYm9vbCBpc19sZW5naHRfY29ycmVjdChzdHJpbmcgJiwgc3RyaW5nICAmKTsKYm9vbCBpc19sb2dpbl9jb250YWluX2lsbGVnYWxfY2hhcihzdHJpbmcgJik7CmJvb2wgaXNfcGFzc3dvcmRfbWVldF9jcml0ZXJpYShzdHJpbmcgJik7CnZvaWQgcHJpbnRfcmVzdWx0KHZlY3RvcjxzdHJpbmc+ICYgYXJyKTsKdm9pZCBwcmludF9hY2NvdW50cyhtYXA8c3RyaW5nLCBzdHJpbmc+ICYgYWNjb3VudCk7CmJvb2wgaXNfYWNjb3VudF9leGlzdChtYXA8c3RyaW5nLHN0cmluZz4gJiBhY2NvdW50LCBzdHJpbmcgJik7CnN0cmluZyBjaGFuZ2VfdG9fbG93ZXJfY2FzZShzdHJpbmcgJik7CnZvaWQgY3JlYXRlX2FjY291bnQobWFwPHN0cmluZywgc3RyaW5nPiAmIGFjY291bnQsIHN0cmluZyAmIGxvZ2luLCBzdHJpbmcgJiBwYXNzd29yZCk7CmJvb2wgaXNfcGFzc3dvcmRfY29ycmVjdChtYXA8c3RyaW5nLHN0cmluZz4gJiBhY2NvdW50cywgc3RyaW5nICYgbG9naW4sIHN0cmluZyAmIHBhc3N3b3JkKTsKCgoKCmludCBtYWluKCl7CgogICAgaW50IGxvZ2luQXR0ZW1wczsKICAgIGludCByZWdpc3RlckF0dGVtcHM7CiAgICBtYXA8c3RyaW5nLCBzdHJpbmc+IGFjY291bnQ7CiAgICBzdHJpbmcgbG9naW47CiAgICBzdHJpbmcgcGFzc3dvcmQ7CiAgICB2ZWN0b3I8c3RyaW5nPiByZXN1bHQ7CgogICAgY291dCA8PCAicmVnaXN0ZXIgIjsKICAgIGNpbiA+PiByZWdpc3RlckF0dGVtcHM7CiAgICBSRVAoaSwgcmVnaXN0ZXJBdHRlbXBzKXsKICAgICAgICBjaW4gPj4gbG9naW4gPj4gcGFzc3dvcmQ7CiAgICAgICAgaWYoaXNfbG9naW5fYW5kX3Bhc3N3b3JkX2FyZV9jb3JyZWN0KGxvZ2luLCBwYXNzd29yZCkpewogICAgICAgICAgICBpZighaXNfYWNjb3VudF9leGlzdChhY2NvdW50LCBsb2dpbikpewogICAgICAgICAgICAgICAgY3JlYXRlX2FjY291bnQoYWNjb3VudCwgbG9naW4sIHBhc3N3b3JkKTsKICAgICAgICAgICAgICAgIHJlc3VsdC5QQigiWmFyZWplc3Ryb3dhbm8iKTsKICAgICAgICAgICAgfWVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgcmVzdWx0LlBCKCJMb2dpbiB6YWpldHkiKTsKICAgICAgICAgICAgfQogICAgICAgIH1lbHNlewogICAgICAgICAgICAKICAgICAgICAgICAgcmVzdWx0LlBCKCJCbGFkIik7CiAgICAgICAgfSAgCiAgICB9CgogICAgY291dCA8PCAibG9naW4gIjsKICAgIGNpbiA+PiBsb2dpbkF0dGVtcHM7CiAgICBSRVAoaSwgbG9naW5BdHRlbXBzKXsKICAgICAgICBjaW4gPj4gbG9naW4gPj4gcGFzc3dvcmQ7CiAgICAgICAgaWYoaXNfYWNjb3VudF9leGlzdChhY2NvdW50LCBsb2dpbikpewogICAgICAgICAgICBpZihpc19wYXNzd29yZF9jb3JyZWN0KGFjY291bnQsIGxvZ2luLCBwYXNzd29yZCkpewogICAgICAgICAgICAgICAgcmVzdWx0LlBCKCJaYWxvZ293YW5vIik7CiAgICAgICAgICAgIH1lbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5QQigiWmxlIGhhc2xvIik7CiAgICAgICAgICAgIH0KICAgICAgICB9ZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmVzdWx0LlBCKCJLb250byBuaWUgaXN0bmllamUiKTsKICAgICAgICB9CiAgICAgICAgCiAgICB9CgoKICAgIGNvdXQgPDwgInJlZ2lzdGVyICI7CiAgICBjaW4gPj4gcmVnaXN0ZXJBdHRlbXBzOwogICAgUkVQKGksIHJlZ2lzdGVyQXR0ZW1wcyl7CiAgICAgICAgY2luID4+IGxvZ2luID4+IHBhc3N3b3JkOwogICAgICAgIGlmKGlzX2xvZ2luX2FuZF9wYXNzd29yZF9hcmVfY29ycmVjdChsb2dpbiwgcGFzc3dvcmQpKXsKICAgICAgICAgICAgaWYoIWlzX2FjY291bnRfZXhpc3QoYWNjb3VudCwgbG9naW4pKXsKICAgICAgICAgICAgICAgIGNyZWF0ZV9hY2NvdW50KGFjY291bnQsIGxvZ2luLCBwYXNzd29yZCk7CiAgICAgICAgICAgICAgICByZXN1bHQuUEIoIlphcmVqZXN0cm93YW5vIik7CiAgICAgICAgICAgIH1lbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5QQigiTG9naW4gemFqZXR5Iik7CiAgICAgICAgICAgIH0KICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgCiAgICAgICAgICAgIHJlc3VsdC5QQigiQmxhZCIpOwogICAgICAgIH0gIAogICAgfQoKCgogICAgY291dCA8PCAibG9naW4gIjsKICAgIGNpbiA+PiBsb2dpbkF0dGVtcHM7CiAgICBSRVAoaSwgbG9naW5BdHRlbXBzKXsKICAgICAgICBjaW4gPj4gbG9naW4gPj4gcGFzc3dvcmQ7CiAgICAgICAgaWYoaXNfYWNjb3VudF9leGlzdChhY2NvdW50LCBsb2dpbikpewogICAgICAgICAgICBpZihpc19wYXNzd29yZF9jb3JyZWN0KGFjY291bnQsIGxvZ2luLCBwYXNzd29yZCkpewogICAgICAgICAgICAgICAgcmVzdWx0LlBCKCJaYWxvZ293YW5vIik7CiAgICAgICAgICAgIH1lbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIHJlc3VsdC5QQigiWmxlIGhhc2xvIik7CiAgICAgICAgICAgIH0KICAgICAgICB9ZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmVzdWx0LlBCKCJLb250byBuaWUgaXN0bmllamUiKTsKICAgICAgICB9CiAgICAgICAgCiAgICB9CgoKCiAgICBwcmludF9yZXN1bHQocmVzdWx0KTsKCgoKICAgIHJldHVybiAwOwp9CnZvaWQgcHJpbnRfbXNnKHN0cmluZyAmIGZ1bmN0aW9uLCAgc3RyaW5nICYgbXNnKXsKICAgIGNvdXQgPDwgZnVuY3Rpb24gPDwgIiAiIDw8IG1zZyA8PCAiXG4iOwp9Cgp2b2lkIHByaW50X3Jlc3VsdCh2ZWN0b3I8c3RyaW5nPiAmIGFycil7CiAgICBGT1IoaSwgMCwgU0laRShhcnIpLTEpewogICAgICAgIGNvdXQgPDwgYXJyW2ldIDw8ICJcbiI7CiAgICB9Cn0Kdm9pZCBwcmludF9hY2NvdW50cyhtYXA8c3RyaW5nLCBzdHJpbmc+ICYgYWNjb3VudCl7CiAgICBjb3V0IDw8ICJcbiI7CiAgICBGT1JFQUNIKGl0LCBhY2NvdW50KXsKICAgICAgICBjb3V0IDw8IGl0LT5maXJzdCA8PCAiICIgPDwgaXQtPnNlY29uZCA8PCAiXG4iOwogICAgfQp9CmJvb2wgaXNfbGVuZ2h0X2NvcnJlY3Qoc3RyaW5nICYgbG9naW4sIHN0cmluZyAmIHBhc3N3b3JkKXsKCiAgICBpZihsb2dpbi5sZW5ndGgoKTwzIHx8IGxvZ2luLmxlbmd0aCgpPjEyKXsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZihwYXNzd29yZC5sZW5ndGgoKTw1IHx8IHBhc3N3b3JkLmxlbmd0aCgpPjE1KXsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICAKCiAgICByZXR1cm4gdHJ1ZTsKfQpib29sIGlzX2xvZ2luX2NvbnRhaW5faWxsZWdhbF9jaGFyKHN0cmluZyAmIGxvZ2luKXsKICAgIAogICAgaW50IGNoYXJhY3RlcjsKICAgIEZPUihpLCAwLCBsb2dpbi5sZW5ndGgoKS0xKXsKICAgICAgICBjaGFyYWN0ZXIgPSAoaW50KWxvZ2luW2ldOwogICAgICAgIAogICAgICAgIEZPUihqLCAwLCAzMil7CiAgICAgICAgICAgIGlmKGNoYXJhY3RlciA9PSBBc2NpaVNwZWNpYWxDaGFyYWN0ZXJzW2pdKXsKICAgICAgICAgICAgICAgIC8vIGNvdXQgPDwgIlNwZWNpYWwgY2hhcmFjdGVyIGRldGVjdGVkICIgPDwgYSA8PCBlbmRsOwogICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlOwogICAgICAgICAgICB9CiAgICAgICAgfSAgICAgCiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQovKiB0aGVzZSBjcml0ZXJpYSBpczoKLSBudW1iZXIKLSBzcGVjaWFsIGNoYXJhY3RlcgotIGNoYXJhY3RlciBpbiB1cHBlciBjYXNlCi0gY2hhcmFjdGVyIGluIGxvd2VyIGNhc2UKKi8KYm9vbCBpc19wYXNzd29yZF9tZWV0X2NyaXRlcmlhKHN0cmluZyAmIHBhc3N3b3JkKXsKICAgIGJvb2wgbnVtYmVyT2NjdXJlbmNlID0gZmFsc2U7CiAgICBib29sIHNwZWNpYWxDaGFyYWN0ZXJPY2N1cmVuY2UgPSBmYWxzZTsKICAgIGJvb2wgdXBwZXJDYXNlQ2hhcmFjdGVyT2NjdXJlbmNlID0gZmFsc2U7CiAgICBib29sIGxvd2VyQ2FzZUNoYXJhY3Rlck9jY3VyZW5jZSA9IGZhbHNlOwoKICAgIEZPUihpLCAwLCBwYXNzd29yZC5sZW5ndGgoKSl7CiAgICAgICAgaWYobnVtYmVyT2NjdXJlbmNlID09IGZhbHNlKSBGT1IobiwgNDgsIDU3KXsKICAgICAgICAgICAgaWYoKGNoYXIpKG4pID09IHBhc3N3b3JkW2ldKXsKICAgICAgICAgICAgICAgIG51bWJlck9jY3VyZW5jZSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYoc3BlY2lhbENoYXJhY3Rlck9jY3VyZW5jZSA9PSBmYWxzZSkgRk9SKGosIDAsIDMyKXsKICAgICAgICAgICAgaWYoQXNjaWlTcGVjaWFsQ2hhcmFjdGVyc1tqXSA9PSBwYXNzd29yZFtpXSl7CiAgICAgICAgICAgICAgICBzcGVjaWFsQ2hhcmFjdGVyT2NjdXJlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZih1cHBlckNhc2VDaGFyYWN0ZXJPY2N1cmVuY2UgPT0gZmFsc2UpIEZPUihjLCA2NSwgOTApewogICAgICAgICAgICBpZigoY2hhcikoYykgPT0gcGFzc3dvcmRbaV0pewogICAgICAgICAgICAgICAgdXBwZXJDYXNlQ2hhcmFjdGVyT2NjdXJlbmNlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZihsb3dlckNhc2VDaGFyYWN0ZXJPY2N1cmVuY2UgPT0gZmFsc2UpIEZPUihjLCA5NywgMTIyKXsKICAgICAgICAgICAgaWYoKGNoYXIpKGMpID09IHBhc3N3b3JkW2ldKXsKICAgICAgICAgICAgICAgIGxvd2VyQ2FzZUNoYXJhY3Rlck9jY3VyZW5jZSA9IHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBpZighKG51bWJlck9jY3VyZW5jZSAmJiBzcGVjaWFsQ2hhcmFjdGVyT2NjdXJlbmNlICYmIHVwcGVyQ2FzZUNoYXJhY3Rlck9jY3VyZW5jZSAmJiBsb3dlckNhc2VDaGFyYWN0ZXJPY2N1cmVuY2UpKXsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICByZXR1cm4gdHJ1ZTsKfQpib29sIGlzX2xvZ2luX2FuZF9wYXNzd29yZF9hcmVfY29ycmVjdChzdHJpbmcgJiBsb2dpbiwgc3RyaW5nICYgcGFzc3dvcmQpewogICAgaWYoIWlzX2xlbmdodF9jb3JyZWN0KGxvZ2luLCBwYXNzd29yZCkpeyAgIAogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIGlmKCFpc19sb2dpbl9jb250YWluX2lsbGVnYWxfY2hhcihsb2dpbikpeyAgICAgICAKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9CiAgICBpZighaXNfcGFzc3dvcmRfbWVldF9jcml0ZXJpYShwYXNzd29yZCkpewogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH0KICAgIHJldHVybiB0cnVlOwp9CnN0cmluZyBjaGFuZ2VfdG9fbG93ZXJfY2FzZShzdHJpbmcgJiB0ZXh0KXsKCiAgICBzdHJpbmcgbG93ZXJfdGV4dCA9IHRleHQ7CgogICAgRk9SKGksIDAsIHRleHQubGVuZ3RoKCkpewogICAgICAgIGxvd2VyX3RleHRbaV0gPSAgdG9sb3dlcihsb3dlcl90ZXh0W2ldKTsKICAgIH0gIAogICAgcmV0dXJuIGxvd2VyX3RleHQ7Cn0Kdm9pZCBjcmVhdGVfYWNjb3VudChtYXA8c3RyaW5nLCBzdHJpbmc+ICYgYWNjb3VudCwgc3RyaW5nICYgbG9naW4sIHN0cmluZyAmIHBhc3N3b3JkKXsKICAgIAogICAgc3RyaW5nIGxvd2VyQ2FzZUxvZ2luID0gY2hhbmdlX3RvX2xvd2VyX2Nhc2UobG9naW4pOyAvLyBjaGFuZ2luZyBsb2dpbiB0byBsb3dlciBjYXNlIGJlY2F1c2UgaXQgZG9lbnN0IG1ha2UgYW4gb2RkcwogICAgYWNjb3VudFtsb3dlckNhc2VMb2dpbl0gPSBwYXNzd29yZDsKICAgIAp9CmJvb2wgaXNfYWNjb3VudF9leGlzdChtYXA8c3RyaW5nLHN0cmluZz4gJiBhY2NvdW50cywgc3RyaW5nICYgbG9naW4pewogICAgc3RyaW5nIGxvd2VyQ2FzZUxvZ2luID0gY2hhbmdlX3RvX2xvd2VyX2Nhc2UobG9naW4pOwogICAgRk9SRUFDSChpdCwgYWNjb3VudHMpewogICAgICAgIGlmKChpdC0+Zmlyc3QuY29tcGFyZShsb3dlckNhc2VMb2dpbikpPT0wKXsKICAgICAgICAgICAKICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGZhbHNlOwp9Cgpib29sIGlzX3Bhc3N3b3JkX2NvcnJlY3QobWFwPHN0cmluZyxzdHJpbmc+ICYgYWNjb3VudHMsIHN0cmluZyAmIGxvZ2luLCBzdHJpbmcgJiBwYXNzd29yZCl7CiAgICBzdHJpbmcgbG93ZXJDYXNlTG9naW4gPSBjaGFuZ2VfdG9fbG93ZXJfY2FzZShsb2dpbik7CiAgICBGT1JFQUNIKGl0LCBhY2NvdW50cyl7CiAgICAgICAgaWYoKGl0LT5maXJzdC5jb21wYXJlKGxvd2VyQ2FzZUxvZ2luKSk9PTApewogICAgICAgICAgICBpZigoaXQtPnNlY29uZC5jb21wYXJlKHBhc3N3b3JkKSk9PTApewogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0=