



'''simple docstring'''

import argparse
import json
import math
import os
import time
import traceback
import zipfile
from collections import Counter

import requests






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						List[str]							,		_SCREAMING_SNAKE_CASE					:						Union[str, Any]=None							)      ->						Optional[Any]:







	"""simple docstring"""
	lowerCAmelCase   =     None
	if token is not None:
		lowerCAmelCase   =     {"""Accept""": """application/vnd.github+json""", """Authorization""": f'Bearer {token}'}

	lowerCAmelCase   =     f'https://api.github.com/repos/huggingface/transformers/actions/runs/{workflow_run_id}/jobs?per_page=100'
	lowerCAmelCase   =     requests.get(_SCREAMING_SNAKE_CASE							,		headers=_SCREAMING_SNAKE_CASE							).json()
	lowerCAmelCase   =     {}

	try:
		job_links.update({job["""name"""]: job["""html_url"""] for job in result["""jobs"""]}							)
		lowerCAmelCase   =     math.ceil((result["""total_count"""] - 100) / 100							)

		for i in range(_SCREAMING_SNAKE_CASE							):
			lowerCAmelCase   =     requests.get(url + f'&page={i + 2}'							,		headers=_SCREAMING_SNAKE_CASE							).json()
			job_links.update({job["""name"""]: job["""html_url"""] for job in result["""jobs"""]}							)

		return job_links
	except Exception:
		print(f'Unknown error, could not fetch links:\n{traceback.format_exc()}'							)

	return {}






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						Optional[int]							,		_SCREAMING_SNAKE_CASE					:						List[str]=None							)      ->						List[str]:







	"""simple docstring"""
	lowerCAmelCase   =     None
	if token is not None:
		lowerCAmelCase   =     {"""Accept""": """application/vnd.github+json""", """Authorization""": f'Bearer {token}'}

	lowerCAmelCase   =     f'https://api.github.com/repos/huggingface/transformers/actions/runs/{worflow_run_id}/artifacts?per_page=100'
	lowerCAmelCase   =     requests.get(_SCREAMING_SNAKE_CASE							,		headers=_SCREAMING_SNAKE_CASE							).json()
	lowerCAmelCase   =     {}

	try:
		artifacts.update({artifact["""name"""]: artifact["""archive_download_url"""] for artifact in result["""artifacts"""]}							)
		lowerCAmelCase   =     math.ceil((result["""total_count"""] - 100) / 100							)

		for i in range(_SCREAMING_SNAKE_CASE							):
			lowerCAmelCase   =     requests.get(url + f'&page={i + 2}'							,		headers=_SCREAMING_SNAKE_CASE							).json()
			artifacts.update({artifact["""name"""]: artifact["""archive_download_url"""] for artifact in result["""artifacts"""]}							)

		return artifacts
	except Exception:
		print(f'Unknown error, could not fetch links:\n{traceback.format_exc()}'							)

	return {}






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						Optional[int]							,		_SCREAMING_SNAKE_CASE					:						Optional[Any]							,		_SCREAMING_SNAKE_CASE					:						Dict							,		_SCREAMING_SNAKE_CASE					:						List[str]							)      ->						Any:







	"""simple docstring"""
	lowerCAmelCase   =     None
	if token is not None:
		lowerCAmelCase   =     {"""Accept""": """application/vnd.github+json""", """Authorization""": f'Bearer {token}'}

	lowerCAmelCase   =     requests.get(_SCREAMING_SNAKE_CASE							,		headers=_SCREAMING_SNAKE_CASE							,		allow_redirects=_SCREAMING_SNAKE_CASE							)
	lowerCAmelCase   =     result.headers["""Location"""]
	lowerCAmelCase   =     requests.get(_SCREAMING_SNAKE_CASE							,		allow_redirects=_SCREAMING_SNAKE_CASE							)
	lowerCAmelCase   =     os.path.join(_SCREAMING_SNAKE_CASE							,		f'{artifact_name}.zip'							)
	with open(_SCREAMING_SNAKE_CASE							,		"""wb"""							) as fp:
		fp.write(response.content							)






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						Optional[int]							,		_SCREAMING_SNAKE_CASE					:						Union[str, Any]=None							)      ->						Any:







	"""simple docstring"""
	lowerCAmelCase   =     []
	lowerCAmelCase   =     []
	lowerCAmelCase   =     None

	with zipfile.ZipFile(_SCREAMING_SNAKE_CASE							) as z:
		for filename in z.namelist():
			if not os.path.isdir(_SCREAMING_SNAKE_CASE							):
				# read the file
				if filename in ["failures_line.txt", "summary_short.txt", "job_name.txt"]:
					with z.open(_SCREAMING_SNAKE_CASE							) as f:
						for line in f:
							lowerCAmelCase   =     line.decode("""UTF-8"""							).strip()
							if filename == "failures_line.txt":
								try:
									# `error_line` is the place where `error` occurs
									lowerCAmelCase   =     line[: line.index(""": """							)]
									lowerCAmelCase   =     line[line.index(""": """							) + len(""": """							) :]
									errors.append([error_line, error]							)
								except Exception:
									# skip un-related lines
									pass
							elif filename == "summary_short.txt" and line.startswith("""FAILED """							):
								# `test` is the test method that failed
								lowerCAmelCase   =     line[len("""FAILED """							) :]
								failed_tests.append(_SCREAMING_SNAKE_CASE							)
							elif filename == "job_name.txt":
								lowerCAmelCase   =     line

	if len(_SCREAMING_SNAKE_CASE							) != len(_SCREAMING_SNAKE_CASE							):
		raise ValueError(
		    f'`errors` and `failed_tests` should have the same number of elements. Got {len(_SCREAMING_SNAKE_CASE							)} for `errors` '
		    f'and {len(_SCREAMING_SNAKE_CASE							)} for `failed_tests` instead. The test reports in {artifact_zip_path} have some'
		    """ problem."""							)

	lowerCAmelCase   =     None
	if job_name and job_links:
		lowerCAmelCase   =     job_links.get(_SCREAMING_SNAKE_CASE							,		_SCREAMING_SNAKE_CASE							)

	# A list with elements of the form (line of error, error, failed test)
	lowerCAmelCase   =     [x + [y] + [job_link] for x, y in zip(_SCREAMING_SNAKE_CASE							,		_SCREAMING_SNAKE_CASE							)]

	return result






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						Optional[Any]							,		_SCREAMING_SNAKE_CASE					:						Optional[int]=None							)      ->						Optional[Any]:







	"""simple docstring"""
	lowerCAmelCase   =     []

	lowerCAmelCase   =     [os.path.join(_SCREAMING_SNAKE_CASE							,		_SCREAMING_SNAKE_CASE							) for p in os.listdir(_SCREAMING_SNAKE_CASE							) if p.endswith(""".zip"""							)]
	for p in paths:
		errors.extend(get_errors_from_single_artifact(_SCREAMING_SNAKE_CASE							,		job_links=_SCREAMING_SNAKE_CASE							)							)

	return errors






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						Any							,		_SCREAMING_SNAKE_CASE					:						int=None							)      ->						Union[str, Any]:







	"""simple docstring"""
	lowerCAmelCase   =     Counter()
	counter.update([x[1] for x in logs]							)
	lowerCAmelCase   =     counter.most_common()
	lowerCAmelCase   =     {}
	for error, count in counts:
		if error_filter is None or error not in error_filter:
			lowerCAmelCase   =     {"""count""": count, """failed_tests""": [(x[2], x[0]) for x in logs if x[1] == error]}

	lowerCAmelCase   =     dict(sorted(r.items()							,		key=lambda _SCREAMING_SNAKE_CASE							: item[1]["count"]							,		reverse=_SCREAMING_SNAKE_CASE							)							)
	return r






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						str							)      ->						List[Any]:







	"""simple docstring"""
	lowerCAmelCase   =     test.split("""::"""							)[0]
	if test.startswith("""tests/models/"""							):
		lowerCAmelCase   =     test.split("""/"""							)[2]
	else:
		lowerCAmelCase   =     None

	return test






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						Optional[int]							,		_SCREAMING_SNAKE_CASE					:						Any=None							)      ->						Any:







	"""simple docstring"""
	lowerCAmelCase   =     [(x[0], x[1], get_model(x[2]							)) for x in logs]
	lowerCAmelCase   =     [x for x in logs if x[2] is not None]
	lowerCAmelCase   =     {x[2] for x in logs}

	lowerCAmelCase   =     {}
	for test in tests:
		lowerCAmelCase   =     Counter()
		# count by errors in `test`
		counter.update([x[1] for x in logs if x[2] == test]							)
		lowerCAmelCase   =     counter.most_common()
		lowerCAmelCase   =     {error: count for error, count in counts if (error_filter is None or error not in error_filter)}
		lowerCAmelCase   =     sum(error_counts.values()							)
		if n_errors > 0:
			lowerCAmelCase   =     {"""count""": n_errors, """errors""": error_counts}

	lowerCAmelCase   =     dict(sorted(r.items()							,		key=lambda _SCREAMING_SNAKE_CASE							: item[1]["count"]							,		reverse=_SCREAMING_SNAKE_CASE							)							)
	return r






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						Union[str, Any]							)      ->						str:







	"""simple docstring"""
	lowerCAmelCase   =     """| no. | error | status |"""
	lowerCAmelCase   =     """|-:|:-|:-|"""
	lowerCAmelCase   =     [header, sep]
	for error in reduced_by_error:
		lowerCAmelCase   =     reduced_by_error[error]["""count"""]
		lowerCAmelCase   =     f'| {count} | {error[:100]} |  |'
		lines.append(_SCREAMING_SNAKE_CASE							)

	return "\n".join(_SCREAMING_SNAKE_CASE							)






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						int							)      ->						Optional[Any]:







	"""simple docstring"""
	lowerCAmelCase   =     """| model | no. of errors | major error | count |"""
	lowerCAmelCase   =     """|-:|-:|-:|-:|"""
	lowerCAmelCase   =     [header, sep]
	for model in reduced_by_model:
		lowerCAmelCase   =     reduced_by_model[model]["""count"""]
		lowerCAmelCase,       lowerCAmelCase   =     list(reduced_by_model[model]["""errors"""].items()							)[0]
		lowerCAmelCase   =     f'| {model} | {count} | {error[:60]} | {_count} |'
		lines.append(_SCREAMING_SNAKE_CASE							)

	return "\n".join(_SCREAMING_SNAKE_CASE							)


if __name__ == "__main__":
				UpperCAmelCase     		=   argparse.ArgumentParser()
				# Required parameters
				parser.add_argument('--workflow_run_id', type=str, required=True, help='A GitHub Actions workflow run id.')
				parser.add_argument(
				    '--output_dir',
				    type=str,
				    required=True,
				    help='Where to store the downloaded artifacts and other result files.',
				)
				parser.add_argument('--token', default=None, type=str, help='A token that has actions:read permission.')
				UpperCAmelCase     		=   parser.parse_args()

				os.makedirs(args.output_dir, exist_ok=True)

				UpperCAmelCase     		=   get_job_links(args.workflow_run_id, token=args.token)
				UpperCAmelCase     		=   {}
				# To deal with `workflow_call` event, where a job name is the combination of the job names in the caller and callee.
				# For example, `PyTorch 1.11 / Model tests (models/albert, single-gpu)`.
				if _job_links:
								for k, v in _job_links.items():
												# This is how GitHub actions combine job names.
												if " / " in k:
																UpperCAmelCase     		=   k.find(' / ')
																UpperCAmelCase     		=   k[index + len(' / ') :]
												UpperCAmelCase     		=   v
				with open(os.path.join(args.output_dir, 'job_links.json'), 'w', encoding='UTF-8') as fp:
								json.dump(job_links, fp, ensure_ascii=False, indent=4)

				UpperCAmelCase     		=   get_artifacts_links(args.workflow_run_id, token=args.token)
				with open(os.path.join(args.output_dir, 'artifacts.json'), 'w', encoding='UTF-8') as fp:
								json.dump(artifacts, fp, ensure_ascii=False, indent=4)

				for idx, (name, url) in enumerate(artifacts.items()):
								download_artifact(name, url, args.output_dir, args.token)
								# Be gentle to GitHub
								time.sleep(1)

				UpperCAmelCase     		=   get_all_errors(args.output_dir, job_links=job_links)

				# `e[1]` is the error
				UpperCAmelCase     		=   Counter()
				counter.update([e[1] for e in errors])

				# print the top 30 most common test errors
				UpperCAmelCase     		=   counter.most_common(30)
				for item in most_common:
								print(item)

				with open(os.path.join(args.output_dir, 'errors.json'), 'w', encoding='UTF-8') as fp:
								json.dump(errors, fp, ensure_ascii=False, indent=4)

				UpperCAmelCase     		=   reduce_by_error(errors)
				UpperCAmelCase     		=   reduce_by_model(errors)

				UpperCAmelCase     		=   make_github_table(reduced_by_error)
				UpperCAmelCase     		=   make_github_table_per_model(reduced_by_model)

				with open(os.path.join(args.output_dir, 'reduced_by_error.txt'), 'w', encoding='UTF-8') as fp:
								fp.write(sa)
				with open(os.path.join(args.output_dir, 'reduced_by_model.txt'), 'w', encoding='UTF-8') as fp:
								fp.write(sa)




'''simple docstring'''

from __future__ import annotations






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						int | str							)      ->						bool:







	"""simple docstring"""
	lowerCAmelCase   =     str(_SCREAMING_SNAKE_CASE							)
	return n == n[::-1]






def 		_snake_case		( _SCREAMING_SNAKE_CASE					:						int = 1_000_000							)      ->						Dict:







	"""simple docstring"""
	lowerCAmelCase   =     0

	for i in range(1							,		_SCREAMING_SNAKE_CASE							):
		if is_palindrome(_SCREAMING_SNAKE_CASE							) and is_palindrome(bin(_SCREAMING_SNAKE_CASE							).split("""b"""							)[1]							):
			total += i
	return total


if __name__ == "__main__":
				print(solution(int(str(input().strip()))))