[
  {
    "path": ".gitignore",
    "content": "venv\n.idea\n*.pyc\n__pycache__\n\n"
  },
  {
    "path": "Day01-15/Day01/hello.py",
    "content": "\"\"\"\n\n第一个Python程序 - hello, world!\n向伟大的Dennis M. Ritchie先生致敬\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-26\n\n请将该文件命名为hello.py并在终端中通过下面的命令运行它\npython hello.py\n\n\"\"\"\n\nprint('hello, world!')\n# print(\"你好,世界！\")\nprint('你好', '世界')\nprint('hello', 'world', sep=', ', end='!')\nprint('goodbye, world', end='!\\n')\n"
  },
  {
    "path": "Day01-15/Day01/peppa_pig.py",
    "content": "from turtle import*\n\n\ndef nose(x,y):#鼻子\n    penup()#提起笔\n    goto(x,y)#定位\n    pendown()#落笔，开始画\n    setheading(-30)#将乌龟的方向设置为to_angle/为数字（0-东、90-北、180-西、270-南）\n    begin_fill()#准备开始填充图形\n    a=0.4\n    for i in range(120):\n        if 0<=i<30 or 60<=i<90:\n            a=a+0.08\n            left(3) #向左转3度\n            forward(a) #向前走a的步长\n        else:\n            a=a-0.08\n            left(3)\n            forward(a)\n    end_fill()#填充完成\n\n    penup()\n    setheading(90)\n    forward(25)\n    setheading(0)\n    forward(10)\n    pendown()\n    pencolor(255,155,192)#画笔颜色\n    setheading(10)\n    begin_fill()\n    circle(5)\n    color(160,82,45)#返回或设置pencolor和fillcolor\n    end_fill()\n\n    penup()\n    setheading(0)\n    forward(20)\n    pendown()\n    pencolor(255,155,192)\n    setheading(10)\n    begin_fill()\n    circle(5)\n    color(160,82,45)\n    end_fill()\n\n\ndef head(x,y):#头\n    color((255,155,192),\"pink\")\n    penup()\n    goto(x,y)\n    setheading(0)\n    pendown()\n    begin_fill()\n    setheading(180)\n    circle(300,-30)\n    circle(100,-60)\n    circle(80,-100)\n    circle(150,-20)\n    circle(60,-95)\n    setheading(161)\n    circle(-300,15)\n    penup()\n    goto(-100,100)\n    pendown()\n    setheading(-30)\n    a=0.4\n    for i in range(60):\n        if 0<=i<30 or 60<=i<90:\n            a=a+0.08\n            lt(3) #向左转3度\n            fd(a) #向前走a的步长\n        else:\n            a=a-0.08\n            lt(3)\n            fd(a)\n    end_fill()\n\n\ndef ears(x,y): #耳朵\n    color((255,155,192),\"pink\")\n    penup()\n    goto(x,y)\n    pendown()\n    begin_fill()\n    setheading(100)\n    circle(-50,50)\n    circle(-10,120)\n    circle(-50,54)\n    end_fill()\n\n    penup()\n    setheading(90)\n    forward(-12)\n    setheading(0)\n    forward(30)\n    pendown()\n    begin_fill()\n    setheading(100)\n    circle(-50,50)\n    circle(-10,120)\n    circle(-50,56)\n    end_fill()\n\n\ndef eyes(x,y):#眼睛\n    color((255,155,192),\"white\")\n    penup()\n    setheading(90)\n    forward(-20)\n    setheading(0)\n    forward(-95)\n    pendown()\n    begin_fill()\n    circle(15)\n    end_fill()\n\n    color(\"black\")\n    penup()\n    setheading(90)\n    forward(12)\n    setheading(0)\n    forward(-3)\n    pendown()\n    begin_fill()\n    circle(3)\n    end_fill()\n\n    color((255,155,192),\"white\")\n    penup()\n    seth(90)\n    forward(-25)\n    seth(0)\n    forward(40)\n    pendown()\n    begin_fill()\n    circle(15)\n    end_fill()\n\n    color(\"black\")\n    penup()\n    setheading(90)\n    forward(12)\n    setheading(0)\n    forward(-3)\n    pendown()\n    begin_fill()\n    circle(3)\n    end_fill()\n\n\ndef cheek(x,y):#腮\n    color((255,155,192))\n    penup()\n    goto(x,y)\n    pendown()\n    setheading(0)\n    begin_fill()\n    circle(30)\n    end_fill()\n\n\ndef mouth(x,y): #嘴\n    color(239,69,19)\n    penup()\n    goto(x,y)\n    pendown()\n    setheading(-80)\n    circle(30,40)\n    circle(40,80)\n\n\ndef setting():          #参数设置\n    pensize(4)\n    hideturtle()        #使乌龟无形（隐藏）\n    colormode(255)      #将其设置为1.0或255.随后 颜色三元组的r，g，b值必须在0 .. cmode范围内\n    color((255,155,192),\"pink\")\n    setup(840,500)\n    speed(10)\n\n\ndef main():\n    setting()           #画布、画笔设置\n    nose(-100,100)      #鼻子\n    head(-69,167)       #头\n    ears(0,160)         #耳朵\n    eyes(0,140)         #眼睛\n    cheek(80,10)        #腮\n    mouth(-20,30)       #嘴\n    done()\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day01/初识Python.md",
    "content": "## Day01 - 初识Python\n\n### Python简介\n\n#### Python的历史\n\n1. 1989年圣诞节：Guido von Rossum开始写Python语言的编译器。\n2. 1991年2月：第一个Python编译器（同时也是解释器）诞生，它是用C语言实现的（后面又出现了Java和C#实现的版本Jython和IronPython，以及PyPy、Brython、Pyston等其他实现），可以调用C语言的库函数。在最早的版本中，Python已经提供了对“类”，“函数”，“异常处理”等构造块的支持，同时提供了“列表”和“字典”等核心数据类型，同时支持以模块为基础的拓展系统。\n3. 1994年1月：Python 1.0正式发布。\n4. 2000年10月16日：Python 2.0发布，增加了实现完整的[垃圾回收](https://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8))，并且支持[Unicode](https://zh.wikipedia.org/wiki/Unicode)。与此同时，Python的整个开发过程更加透明，社区对开发进度的影响逐渐扩大，生态圈开始慢慢形成。\n5. 2008年12月3日：Python 3.0发布，此版不完全兼容之前的Python代码，不过很多新特性后来也被移植到旧的Python 2.6/2.7版本，因为目前还有公司在项目和运维中使用Python 2.x版本的代码。\n\n目前我们使用的Python 3.6.x的版本是在2016年的12月23日发布的，Python的版本号分为三段，形如A.B.C。其中A表示大版本号，一般当整体重写，或出现不向后兼容的改变时，增加A；B表示功能更新，出现新功能时增加B；C表示小的改动（如修复了某个Bug），只要有修改就增加C。如果对Python的历史感兴趣，可以查看一篇名为[《Python简史》](http://www.cnblogs.com/vamei/archive/2013/02/06/2892628.html)的博文。\n\n#### Python的优缺点\n\nPython的优点很多，简单的可以总结为以下几点。\n\n1. 简单和明确，做一件事只有一种方法。\n2. 学习曲线低，与其他很多语言比上手更容易。\n3. 开放源代码，拥有强大的社区和生态圈。\n4. 解释型语言，完美的平台可移植性。\n5. 支持两种主流的编程范式，可以使用面向对象和函数式编程。\n6. 可扩展性和可嵌入性，可以调用C/C++代码也可以在C/C++中调用。\n7. 代码规范程度高，可读性强，适合有代码洁癖和强迫症的人群。\n\nPython的缺点主要集中在以下几点。\n\n1. 执行效率低下，因此计算密集型任务可以由C/C++编写。\n2. 代码无法加密，但是现在的公司很多都不是卖软件而是卖服务，这个问题慢慢会淡化。\n3. 在开发时可以选择的框架太多，有选择的地方就有错误。\n\n#### Python的应用领域\n\n目前Python在云基础设施、DevOps、网络爬虫开发、数据分析挖掘、机器学习等领域都有着广泛的应用，因此也产生了服务器开发、数据接口开发、自动化运维、科学计算和数据可视化、聊天机器人开发、图像识别和处理等一系列的职位。\n\n### 搭建编程环境\n\n#### Windows环境\n\n可以在[Python的官方网站](https://www.python.org)下载到Python的Windows安装程序（exe文件），需要注意的是如果在Windows 7环境下安装需要先安装Service Pack 1补丁包（可以通过一些工具软件自动安装系统补丁的功能来安装），安装过程建议勾选“Add Python 3.6 to PATH”（将Python 3.6添加到PATH环境变量）并选择自定义安装，在设置“Optional Features”界面最好将“pip”、“tcl/tk”、“Python test suite”等项全部勾选上。强烈建议使用自定义的安装路径并保证路径中没有中文。安装完成会看到“Setup was successful”的提示，但是在启动Python环境时可能会因为缺失一些动态链接库文件而导致Python解释器无法运行，常见的问题主要是api-ms-win-crt\\*.dll缺失以及更新DirectX之后导致某些动态链接库文件缺失，前者可以参照[《api-ms-win-crt\\*.dll缺失原因分析和解决方法》]()一文讲解的方法进行处理或者直接在[微软官网](https://www.microsoft.com/zh-cn/download/details.aspx?id=48145)下载Visual C++ Redistributable for Visual Studio 2015文件进行修复，后者可以下载一个DirectX修复工具进行修复。\n\n#### Linux环境\n\nLinux环境自带了Python 2.x版本，但是如果要更新到3.x的版本，可以在[Python的官方网站](https://www.python.org)下载Python的源代码并通过源代码构建安装的方式进行安装，具体的步骤如下所示。\n\n安装依赖库（因为没有这些依赖库可能在源代码构件安装时因为缺失底层依赖库而失败）。\n\n```Shell\nyum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel\n```\n\n下载Python源代码并解压缩到指定目录。\n\n```Shell\nwget https://www.python.org/ftp/python/3.6.1/Python-3.6.1.tar.xz\nxz -d Python-3.6.1.tar.xz\ntar -xvf Python-3.6.1.tar\n```\n\n切换至Python源代码目录并执行下面的命令进行配置和安装。\n\n```Shell\ncd Python-3.6.1\n./configure --prefix=/usr/local/python3.6 --enable-optimizations\nmake && make install\n```\n\n创建软链接，这样就可以直接通过python3直接启动Python解释器。\n\n```Shell\nln -s /usr/local/python3.6/bin/python3 /usr/bin/python3\n```\n\n\n#### MacOS环境\n\nMacOS也是自带了Python 2.x版本的，可以通过[Python的官方网站](https://www.python.org)提供的安装文件（pkg文件）安装3.x的版本。默认安装完成后，可以通过在终端执行python命令来启动2.x版本的Python解释器，可以通过执行python3命令来启动3.x版本的Python解释器，当然也可以通过重新设置软链接来修改启动Python解释器的命令。\n\n### 从终端运行Python程序\n\n#### 确认Python的版本\n\n在终端或命令行提示符中键入下面的命令。\n\n```Shell\npython --version\n```\n当然也可以先输入python进入交互式环境，再执行以下的代码检查Python的版本。\n\n```Python\nimport sys\n\nprint(sys.version_info)\nprint(sys.version)\n```\n\n#### 编写Python源代码\n\n可以用文本编辑工具（推荐使用Sublime、Atom、TextMate、VSCode等高级文本编辑工具）编写Python源代码并将其命名为hello.py保存起来，代码内容如下所示。\n\n```Python\nprint('hello, world!')\n```\n\n#### 运行程序\n\n切换到源代码所在的目录并执行下面的命令，看看屏幕上是否输出了\"hello, world!\"。\n\n```Shell\npython hello.py\n```\n\n### 代码中的注释\n\n注释是编程语言的一个重要组成部分，用于在源代码中解释代码的作用从而增强程序的可读性和可维护性，当然也可以将源代码中不需要参与运行的代码段通过注释来去掉，这一点在调试程序的时候经常用到。注释在随源代码进入预处理器或编译时会被移除，不会在目标代码中保留也不会影响程序的执行结果。\n\n1. 单行注释 - 以#和空格开头的部分\n2. 多行注释 - 三个引号开头，三个引号结尾\n\n```Python\n\"\"\"\n\n第一个Python程序 - hello, world!\n向伟大的Dennis M. Ritchie先生致敬\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-26\n\n\"\"\"\n\nprint('hello, world!')\n# print(\"你好,世界！\")\nprint('你好', '世界')\nprint('hello', 'world', sep=', ', end='!')\nprint('goodbye, world', end='!\\n')\n```\n\n### 其他工具介绍\n\n#### IDLE - 自带的集成开发工具\n\nIDLE是安装Python环境时自带的集成开发工具，如下图所示。但是由于IDLE的用户体验并不是那么好所以很少在实际开发中被采用。\n\n![](./res/python-idle.png)\n\n#### IPython - 更好的交互式编程工具\n\nIPython是一种基于Python的交互式解释器。相较于原生的Python Shell，IPython提供了更为强大的编辑和交互功能。可以通过Python的包管理工具pip安装IPython和Jupyter，具体的操作如下所示。\n\n```Shell\npip install ipython jupyter\n```\n\n或者\n\n```Shell\npython -m pip install ipython jupyter\n```\n\n安装成功后，可以通过下面的ipython命令启动IPython，如下图所示。\n\n![](./res/python-ipython.png)\n\n当然我们也可以通过Jupyter运行名为notebook的项目在浏览器窗口中进行交互式操作。\n\n```Shell\njupyter notebook\n```\n\n![](./res/python-jupyter-1.png)\n\n![](./res/python-jupyter-2.png)\n\n#### Sublime - 文本编辑神器\n\n![](./res/python-sublime.png)\n\n- 首先可以通过[官方网站](https://www.sublimetext.com/)下载安装程序安装Sublime 3或Sublime 2。\n\n- 安装包管理工具。通过快捷键Ctrl+`或者在View菜单中选择Show Console打开控制台，输入下面的代码。\n\n  - Sublime 3\n\n  ```Python\n  import  urllib.request,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();urllib.request.install_opener(urllib.request.build_opener(urllib.request.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib.request.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read())\n  ```\n\n  - Sublime 2\n\n  ```Python\n  import  urllib2,os;pf='Package Control.sublime-package';ipp=sublime.installed_packages_path();os.makedirs(ipp)ifnotos.path.exists(ipp)elseNone;urllib2.install_opener(urllib2.build_opener(urllib2.ProxyHandler()));open(os.path.join(ipp,pf),'wb').write(urllib2.urlopen('http://sublime.wbond.net/'+pf.replace(' ','%20')).read());print('Please restart Sublime Text to finish installation')\n  ```\n\n- 安装插件。通过Preference菜单的Package Control或快捷键Ctrl+Shift+P打开命令面板，在面板中输入Install Package就可以找到安装插件的工具，然后再查找需要的插件。我们推荐大家安装以下几个插件。\n\n  - SublimeCodeIntel - 代码自动补全工具插件\n  - Emmet - 前端开发代码模板插件\n  - Git - 版本控制工具插件\n  - Python PEP8 Autoformat - PEP8规范自动格式化插件\n  - ConvertToUTF8 - 将本地编码转换为UTF-8\n\n#### PyCharm - Python开发神器\n\nPyCharm的安装、配置和使用我们在后面会进行介绍。\n\n![](./res/python-pycharm.png)\n\n### 练习\n\n1. 在Python交互环境中下面的代码查看结果并将内容翻译成中文。\n\n    ```Python\n    import this\n\n    Beautiful is better than ugly.\n    Explicit is better than implicit.\n    Simple is better than complex.\n    Complex is better than complicated.\n    Flat is better than nested.\n    Sparse is better than dense.\n    Readability counts.\n    Special cases aren't special enough to break the rules.\n    Although practicality beats purity.\n    Errors should never pass silently.\n    Unless explicitly silenced.\n    In the face of ambiguity, refuse the temptation to guess.\n    There should be one-- and preferably only one --obvious way to do it.\n    Although that way may not be obvious at first unless you're Dutch.\n    Now is better than never.\n    Although never is often better than *right* now.\n    If the implementation is hard to explain, it's a bad idea.\n    If the implementation is easy to explain, it may be a good idea.\n    Namespaces are one honking great idea -- let's do more of those!\n    ```\n\n2. 学习使用turtle在屏幕上绘制图形。\n\n    ```Python\n    import turtle\n\n    turtle.pensize(4)\n    turtle.pencolor('red')\n    turtle.forward(100)\n    turtle.right(90)\n    turtle.forward(100)\n    turtle.right(90)\n    turtle.forward(100)\n    turtle.right(90)\n    turtle.forward(100)\n    turtle.mainloop()\n    ```\n"
  },
  {
    "path": "Day01-15/Day02/centigrade.py",
    "content": "\"\"\"\n\n将华氏温度转换为摄氏温度\nF = 1.8C + 32\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\nf = float(input('请输入华氏温度: '))\nc = (f - 32) / 1.8\nprint('%.1f华氏度 = %.1f摄氏度' % (f, c))\n"
  },
  {
    "path": "Day01-15/Day02/circle.py",
    "content": "\"\"\"\n\n输入半径计算圆的周长和面积\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\nimport math\n\nradius = float(input('请输入圆的半径: '))\nperimeter = 2 * math.pi * radius\narea = math.pi * radius * radius\nprint('周长: %.2f' % perimeter)\nprint('面积: %.2f' % area)\n"
  },
  {
    "path": "Day01-15/Day02/leap.py",
    "content": "\"\"\"\n\n输入年份 如果是闰年输出True 否则输出False\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\nyear = int(input('请输入年份: '))\n# 如果代码太长写成一行不便于阅读 可以使用\\或()折行\nis_leap = (year % 4 == 0 and year % 100 != 0 or\n           year % 400 == 0)\nprint(is_leap)\n"
  },
  {
    "path": "Day01-15/Day02/operator.py",
    "content": "\"\"\"\n\n运算符的使用\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = 5\nb = 10\nc = 3\nd = 4\ne = 5\na += b\na -= c\na *= d\na /= e\nprint(\"a = \", a)\n\nflag1 = 3 > 2\nflag2 = 2 < 1\nflag3 = flag1 and flag2\nflag4 = flag1 or flag2\nflag5 = not flag1\nprint(\"flag1 = \", flag1)\nprint(\"flag2 = \", flag2)\nprint(\"flag3 = \", flag3)\nprint(\"flag4 = \", flag4)\nprint(\"flag5 = \", flag5)\nprint(flag1 is True)\nprint(flag2 is not False)\n"
  },
  {
    "path": "Day01-15/Day02/string.py",
    "content": "\"\"\"\n\n字符串常用操作\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\nstr1 = 'hello, world!'\nprint('字符串的长度是:', len(str1))\nprint('单词首字母大写: ', str1.title())\nprint('字符串变大写: ', str1.upper())\n# str1 = str1.upper()\nprint('字符串是不是大写: ', str1.isupper())\nprint('字符串是不是以hello开头: ', str1.startswith('hello'))\nprint('字符串是不是以hello结尾: ', str1.endswith('hello'))\nprint('字符串是不是以感叹号开头: ', str1.startswith('!'))\nprint('字符串是不是一感叹号结尾: ', str1.endswith('!'))\nstr2 = '- \\u9a86\\u660a'\nstr3 = str1.title() + ' ' + str2.lower()\nprint(str3)\n"
  },
  {
    "path": "Day01-15/Day02/variable1.py",
    "content": "\"\"\"\n\n使用变量保存数据并进行操作\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = 321\nb = 123\nprint(a + b)\nprint(a - b)\nprint(a * b)\nprint(a / b)\nprint(a // b)\nprint(a % b)\nprint(a ** b)\n"
  },
  {
    "path": "Day01-15/Day02/variable2.py",
    "content": "\"\"\"\n\n将input函数输入的数据保存在变量中并进行操作\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = int(input('a = '))\nb = int(input('b = '))\nprint(a + b)\nprint(a - b)\nprint(a * b)\nprint(a / b)\nprint(a // b)\nprint(a % b)\nprint(a ** b)\n"
  },
  {
    "path": "Day01-15/Day02/variable3.py",
    "content": "\"\"\"\n\n格式化输出\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = int(input('a = '))\nb = int(input('b = '))\nprint('%d + %d = %d' % (a, b, a + b))\nprint('%d - %d = %d' % (a, b, a - b))\nprint('%d * %d = %d' % (a, b, a * b))\nprint('%d / %d = %f' % (a, b, a / b))\nprint('%d // %d = %d' % (a, b, a // b))\nprint('%d %% %d = %d' % (a, b, a % b))\nprint('%d ** %d = %d' % (a, b, a ** b))\n"
  },
  {
    "path": "Day01-15/Day02/variable4.py",
    "content": "\"\"\"\n\n检查变量的类型\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = 100\nb = 1000000000000000000\nc = 12.345\nd = 1 + 5j\ne = 'A'\nf = 'hello, world'\ng = True\nprint(type(a))\nprint(type(b))\nprint(type(c))\nprint(type(d))\nprint(type(e))\nprint(type(f))\nprint(type(g))\n"
  },
  {
    "path": "Day01-15/Day02/variable5.py",
    "content": "\"\"\"\n\n类型转换\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = 100\nb = str(a)\nc = 12.345\nd = str(c)\ne = '123'\nf = int(e)\ng = '123.456'\nh = float(g)\ni = False\nj = str(i)\nk = 'hello'\nm = bool(k)\nprint(a)\nprint(type(a))\nprint(b)\nprint(type(b))\nprint(c)\nprint(type(c))\nprint(d)\nprint(type(d))\nprint(e)\nprint(type(e))\nprint(f)\nprint(type(f))\nprint(g)\nprint(type(g))\nprint(h)\nprint(type(h))\nprint(i)\nprint(type(i))\nprint(j)\nprint(type(j))\nprint(k)\nprint(type(k))\nprint(m)\nprint(type(m))\n"
  },
  {
    "path": "Day01-15/Day02/语言元素.md",
    "content": "## Day02 - 语言元素\n\n#### 指令和程序\n\n计算机的硬件系统通常由五大部件构成，包括：运算器、控制器、存储器、输入设备和输出设备。其中，运算器和控制器放在一起就是我们通常所说的中央处理器，它的功能是执行各种运算和控制指令以及处理计算机软件中的数据。我们通常所说的程序实际上就是指令的集合，我们程序就是将一系列的指令按照某种方式组织到一起，然后通过这些指令去控制计算机做我们想让它做的事情。今天我们使用的计算机虽然器件做工越来越精密，处理能力越来越强大，但究其本质来说仍然属于[“冯·诺依曼结构”](https://zh.wikipedia.org/wiki/%E5%86%AF%C2%B7%E8%AF%BA%E4%BC%8A%E6%9B%BC%E7%BB%93%E6%9E%84)的计算机。“冯·诺依曼结构”有两个关键点，一是提出了将存储设备与中央处理器分开，二是提出了将数据以二进制方式编码。二进制是一种“逢二进一”的计数法，跟我们人类使用的“逢十进一”的计数法没有实质性的区别，人类因为有十根手指所以使用了十进制（因为在数数时十根手指用完之后就只能进位了，当然凡事都有例外，玛雅人可能是因为长年光着脚的原因把脚趾头也算上了，于是他们使用了二十进制的计数法，在这种计数法的指导下玛雅人的历法就与我们的不太一致，而按照玛雅人的历法，2012年是上一个所谓的“太阳纪”的最后一年，而2013年则是新的“太阳纪”的开始，后来这件事情被以讹传讹的方式误传为2012年就是玛雅人预言的世界末日这种荒诞的说法，今天我们可以大胆的猜测，玛雅文明之所以发展缓慢估计也与使用了二十进制有关），对于计算机来说，二进制在物理器件上来说是最容易实现的（高电压表示1，低电压表示0），于是在“冯·诺依曼结构”的计算机都使用了二进制。虽然我们并不需要每个程序员都能够使用二进制的思维方式来工作，但是了解二进制以及它与我们生活中的十进制之间的转换关系，以及二进制与八进制和十六进制的转换关系还是有必要的。如果你对这一点不熟悉，可以自行使用[维基百科](https://zh.wikipedia.org/wiki/%E4%BA%8C%E8%BF%9B%E5%88%B6)或者[度娘](https://www.baidu.com)科普一下。\n\n### 变量和类型\n\n在程序设计中，变量是一种存储数据的载体。计算机中的变量是实际存在的数据或者说是存储器中存储数据的一块内存空间，变量的值可以被读取和修改，这是所有计算和控制的基础。计算机能处理的数据有很多中类型，除了数值之外还可以处理文本、图形、音频、视频等各种各样的数据，那么不同的数据就需要定义不同的存储类型。Python中的数据类型很多，而且也允许我们自定义新的数据类型（这一点在后面会讲到），我们先介绍几种常用的数据类型。\n\n- 整型：Python中可以处理任意大小的整数（Python 2.x中有int和long两种类型的整数，但这种区分对Python来说意义不大，因此在Python 3.x中整数只有int这一种了），而且支持二进制（如`0b100`，换算成十进制是4）、八进制（如`0o100`，换算成十进制是64）、十进制（`100`）和十六进制（`0x100`，换算成十进制是256）的表示法。\n- 浮点型：浮点数也就是小数，之所以称为浮点数，是因为按照科学记数法表示时，一个浮点数的小数点位置是可变的，浮点数除了数学写法（如`123.456`）之外还支持科学计数法（如`1.23456e2`）。\n- 字符串型：字符串是以单引号或双引号括起来的任意文本，比如`'hello'`和`\"hello\"`,字符串还有原始字符串表示法、字节字符串表示法、Unicode字符串表示法，而且可以书写成多行的形式（用三个单引号或三个双引号开头，三个单引号或三个双引号结尾）。\n- 布尔型：布尔值只有`True`、`False`两种值，要么是`True`，要么是`False`，在Python中，可以直接用`True`、`False`表示布尔值（请注意大小写），也可以通过布尔运算计算出来（例如`3 < 5`会产生布尔值`True`，而`2 == 1`会产生布尔值`False`）。\n- 复数型：形如`3+5j`，跟数学上的复数表示一样，唯一不同的是虚部的i换成了j。\n\n#### 变量命名\n\n对于每个变量我们需要给它取一个名字，就如同我们每个人都有属于自己的响亮的名字一样。在Python中，变量命名需要遵循以下这些必须遵守硬性规则和强烈建议遵守的非硬性规则。\n\n- 硬性规则：\n  - 变量名由字母（广义的Unicode字符，不包括特殊字符）、数字和下划线构成，数字不能开头。\n  - 大小写敏感（大写的`a`和小写的`A`是两个不同的变量）。\n  - 不要跟关键字（有特殊含义的单词，后面会讲到）和系统保留字（如函数、模块等的名字）冲突。\n- PEP 8要求：\n  - 用小写字母拼写，多个单词用下划线连接。\n  - 受保护的实例属性用单个下划线开头（后面会讲到）。\n  - 私有的实例属性用两个下划线开头（后面会讲到）。\n\n当然，作为一个专业的程序员，给变量（事实上应该是所有的标识符）命名做到见名知意也是非常重要的。\n\n#### 变量的使用\n\n下面通过几个例子来说明变量的类型和变量使用。\n\n```Python\n\"\"\"\n\n使用变量保存数据并进行算术运算\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = 321\nb = 123\nprint(a + b)\nprint(a - b)\nprint(a * b)\nprint(a / b)\nprint(a // b)\nprint(a % b)\nprint(a ** b)\n\n```\n\n```Python\n\"\"\"\n\n使用input函数输入\n使用int()进行类型转换\n用占位符格式化输出的字符串\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = int(input('a = '))\nb = int(input('b = '))\nprint('%d + %d = %d' % (a, b, a + b))\nprint('%d - %d = %d' % (a, b, a - b))\nprint('%d * %d = %d' % (a, b, a * b))\nprint('%d / %d = %f' % (a, b, a / b))\nprint('%d // %d = %d' % (a, b, a // b))\nprint('%d %% %d = %d' % (a, b, a % b))\nprint('%d ** %d = %d' % (a, b, a ** b))\n\n```\n\n```Python\n\"\"\"\n\n使用type()检查变量的类型\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = 100\nb = 12.345\nc = 1 + 5j\nd = 'hello, world'\ne = True\nprint(type(a))\nprint(type(b))\nprint(type(c))\nprint(type(d))\nprint(type(e))\n\n```\n\n在对变量类型进行转换时可以使用Python的内置函数（准确的说下面列出的并不是真正意义上的函数，而是后面我们要讲到的创建对象的构造方法）。\n\n- int()：将一个数值或字符串转换成整数，可以指定进制。\n- float()：将一个字符串转换成浮点数。\n- str()：将指定的对象转换成字符串形式，可以指定编码。\n- chr()：将整数转换成该编码对应的字符串（一个字符）。\n- ord()：将字符串（一个字符）转换成对应的编码（整数）。\n\n### 运算符\n\nPython支持多种运算符，下表大致按照优先级从高到低的顺序列出了所有的运算符，我们会陆续使用到它们。\n\n| 运算符                                                       | 描述                           |\n| ------------------------------------------------------------ | ------------------------------ |\n| `[]` `[:]`                                                   | 下标，切片                     |\n| `**`                                                         | 指数                           |\n| `~` `+` `-`                                                  | 按位取反, 正负号               |\n| `*` `/` `%` `//`                                             | 乘，除，模，整除               |\n| `+` `-`                                                      | 加，减                         |\n| `>>` `<<`                                                    | 右移，左移                     |\n| `&`                                                          | 按位与                         |\n| `^` `|`                                                      | 按位异或，按位或               |\n| `<=` `<` `>` `>=`                                            | 小于等于，小于，大于，大于等于 |\n| `==` `!=`                                                    | 等于，不等于                   |\n| `is`  `is not`                                               | 身份运算符                     |\n| `in` `not in`                                                | 成员运算符                     |\n| `not` `or` `and`                                             | 逻辑运算符                     |\n| `=` `+=` `-=` `*=` `/=` `%=` `//=` `**=` `&=` `|=` `^=` `>>=` `<<=` | （复合）赋值运算符             |\n\n>**说明：**在实际开发中，如果搞不清楚优先级可以使用括号来确保运算的执行顺序。\n\n下面的例子演示了运算符的使用。\n\n```Python\n\"\"\"\n\n运算符的使用\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\na = 5\nb = 10\nc = 3\nd = 4\ne = 5\na += b\na -= c\na *= d\na /= e\nprint(\"a = \", a)\n\nflag1 = 3 > 2\nflag2 = 2 < 1\nflag3 = flag1 and flag2\nflag4 = flag1 or flag2\nflag5 = not flag1\nprint(\"flag1 = \", flag1)\nprint(\"flag2 = \", flag2)\nprint(\"flag3 = \", flag3)\nprint(\"flag4 = \", flag4)\nprint(\"flag5 = \", flag5)\nprint(flag1 is True)\nprint(flag2 is not False)\n\n```\n\n### 练习\n\n#### 练习1：华氏温度转摄氏温度。\n\n```Python\n\"\"\"\n\n将华氏温度转换为摄氏温度\nF = 1.8C + 32\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\nf = float(input('请输入华氏温度: '))\nc = (f - 32) / 1.8\nprint('%.1f华氏度 = %.1f摄氏度' % (f, c))\n\n```\n\n#### 练习2：输入圆的半径计算计算周长和面积。\n\n```Python\n\"\"\"\n\n输入半径计算圆的周长和面积\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\nimport math\n\nradius = float(input('请输入圆的半径: '))\nperimeter = 2 * math.pi * radius\narea = math.pi * radius * radius\nprint('周长: %.2f' % perimeter)\nprint('面积: %.2f' % area)\n\n```\n\n#### 练习3：输入年份判断是不是闰年。\n\n```Python\n\"\"\"\n\n输入年份 如果是闰年输出True 否则输出False\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-27\n\n\"\"\"\n\nyear = int(input('请输入年份: '))\n# 如果代码太长写成一行不便于阅读 可以使用\\或()折行\nis_leap = (year % 4 == 0 and year % 100 != 0 or\n           year % 400 == 0)\nprint(is_leap)\n```\n\n"
  },
  {
    "path": "Day01-15/Day03/.py",
    "content": ""
  },
  {
    "path": "Day01-15/Day03/convert.py",
    "content": "\"\"\"\n\n英制单位英寸和公制单位厘米互换\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nvalue = float(input('请输入长度: '))\nunit = input('请输入单位: ')\nif unit == 'in' or unit == '英寸':\n\tprint('%f英寸 = %f厘米' % (value, value * 2.54))\nelif unit == 'cm' or unit == '厘米':\n\tprint('%f厘米 = %f英寸' % (value, value / 2.54))\nelse:\n\tprint('请输入有效的单位')\n"
  },
  {
    "path": "Day01-15/Day03/grade.py",
    "content": "\"\"\"\n\n百分制成绩转等级制成绩\n90分以上 \t \t--> A\n80分~89分 \t--> B\n70分~79分\t--> C\n60分~69分\t--> D\n60分以下\t\t--> E\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nscore = float(input('请输入成绩: '))\nif score >= 90:\n\tgrade = 'A'\nelif score >= 80:\n\tgrade = 'B'\nelif score >= 70:\n\tgrade = 'C'\nelif score >= 60:\n\tgrade = 'D'\nelse:\n\tgrade = 'E'\nprint('对应的等级是:', grade)\n"
  },
  {
    "path": "Day01-15/Day03/piecewise.py",
    "content": "\"\"\"\n\n分段函数求值\n\t\t3x - 5\t(x > 1)\nf(x) =\tx + 2\t(-1 <= x <= 1)\n\t\t5x + 3\t(x < -1)\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nx = float(input('x = '))\nif x > 1:\n\ty = 3 * x - 5\nelif x >= -1:\n\ty = x + 2\nelse:\n\ty = 5 * x + 3\nprint('f(%.2f) = %.2f' % (x, y))\n"
  },
  {
    "path": "Day01-15/Day03/rolldice.py",
    "content": "\"\"\"\n\n掷骰子决定做什么事情\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nfrom random import randint\n\nface = randint(1, 6)\nif face == 1:\n\tresult = '唱首歌'\nelif face == 2:\n\tresult = '跳个舞'\nelif face == 3:\n\tresult = '学狗叫'\nelif face == 4:\n\tresult = '做俯卧撑'\nelif face == 5:\n\tresult = '念绕口令'\nelse:\n\tresult = '讲冷笑话'\nprint(result)\n"
  },
  {
    "path": "Day01-15/Day03/tax.py",
    "content": "\"\"\"\n\n输入月收入和五险一金计算个人所得税\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nsalary = float(input('本月收入: '))\ninsurance = float(input('五险一金: '))\ndiff = salary - insurance - 3500\nif diff <= 0:\n\trate = 0\n\tdeduction = 0\nelif diff < 1500:\n\trate = 0.03\n\tdeduction = 0\nelif diff < 4500:\n\trate = 0.1\n\tdeduction = 105\nelif diff < 9000:\n\trate = 0.2\n\tdeduction = 555\nelif diff < 35000:\n\trate = 0.25\n\tdeduction = 1005\nelif diff < 55000:\n\trate = 0.3\n\tdeduction = 2755\nelif diff < 80000:\n\trate = 0.35\n\tdeduction = 5505\nelse:\n\trate = 0.45\n\tdeduction = 13505\ntax = abs(diff * rate - deduction)\nprint('个人所得税: ￥%.2f元' % tax)\nprint('实际到手收入: ￥%.2f元' % (diff + 3500 - tax))\n"
  },
  {
    "path": "Day01-15/Day03/triangle.py",
    "content": "\"\"\"\n\n判断输入的边长能否构成三角形\n如果能则计算出三角形的周长和面积\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nimport math\n\na = float(input('a = '))\nb = float(input('b = '))\nc = float(input('c = '))\nif a + b > c and a + c > b and b + c > a:\n\tprint('周长: %f' % (a + b + c))\n\tp = (a + b + c) / 2\n\tarea = math.sqrt(p * (p - a) * (p - b) * (p - c))\n\tprint('面积: %f' % (area))\nelse:\n\tprint('不能构成三角形')\n"
  },
  {
    "path": "Day01-15/Day03/verify.py",
    "content": "\"\"\"\n\n用户身份验证\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\n# import getpass\n# from getpass import getpass\n# from getpass import *\n\nusername = input('请输入用户名: ')\npassword = input('请输入口令: ')\n# 输入口令的时候终端中没有回显\n# password = getpass.getpass('请输入口令: ')\nif username == 'admin' and password == '123456':\n\tprint('身份验证成功!')\nelse:\n\tprint('身份验证失败!')\n"
  },
  {
    "path": "Day01-15/Day03/分支结构.md",
    "content": "## Day03 - 分支结构\n\n### 分支结构的应用场景\n\n迄今为止，我们写的Python代码都是一条一条语句顺序执行，这种结构的代码我们称之为顺序结构。然而仅有顺序结构并不能解决所有的问题，比如我们设计一个游戏，游戏第一关的通关条件是玩家获得1000分，那么在完成本局游戏后我们要根据玩家得到分数来决定究竟是进入第二关还是告诉玩家“Game Over”，这里就会产生两个分支，而且这两个分支只有一个会被执行，这就是程序中分支结构。类似的场景还有很多，给大家一分钟的时间，你应该可以想到至少5个以上这样的例子，赶紧试一试。\n\n### if语句的使用\n\n在Python中，要构造分支结构可以使用`if`、`elif`和`else`关键字。所谓关键字就是有特殊含义的单词，像`if`和`else`就是专门用于构造分支结构的关键字，很显然你不能够使用它作为变量名（事实上，用作其他的标识符也是不可以）。下面的例子中演示了如何构造一个分支结构。\n\n```Python\n\"\"\"\n\n用户身份验证\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nusername = input('请输入用户名: ')\npassword = input('请输入口令: ')\n# 如果希望输入口令时 终端中没有回显 可以使用getpass模块的getpass函数\n# import getpass\n# password = getpass.getpass('请输入口令: ')\nif username == 'admin' and password == '123456':\n\tprint('身份验证成功!')\nelse:\n\tprint('身份验证失败!')\n\n```\n\n唯一需要说明的是和C/C++、Java等语言不同，Python中没有用花括号来构造代码块而是使用了缩进的方式来设置代码的层次结构，如果`if`条件成立的情况下需要执行多条语句，只要保持多条语句具有相同的缩进就可以了，换句话说连续的代码如果又保持了相同的缩进那么它们属于同一个代码块，相当于是一个执行的整体。\n\n当然如果要构造出更多的分支，可以使用`if…elif…else…`结构，例如下面的分段函数求值。\n\n$$f(x)=\\begin{cases} 3x-5&\\text{(x>1)}\\\\x+2&\\text{(-1}\\leq\\text{x}\\leq\\text{1)}\\\\5x+3&\\text {(x<-1)}\\end{cases}$$\n\n```Python\n\"\"\"\n\n分段函数求值\n\n        3x - 5  (x > 1)\nf(x) =  x + 2   (-1 <= x <= 1)\n        5x + 3  (x < -1)\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nx = float(input('x = '))\nif x > 1:\n\ty = 3 * x - 5\nelif x >= -1:\n\ty = x + 2\nelse:\n\ty = 5 * x + 3\nprint('f(%.2f) = %.2f' % (x, y))\n\n```\n\n当然根据实际开发的需要，分支结构是可以嵌套的，例如判断是否通关以后还要根据你获得的宝物或者道具的数量对你的表现给出等级（比如点亮两颗或三颗星星），那么我们就需要在`if`的内部构造出一个新的分支结构，同理`elif`和`else`中也可以再构造新的分支，我们称之为嵌套的分支结构，也就是说上面的代码也可以写成下面的样子。\n\n```Python\n\"\"\"\n\n分段函数求值\n\t\t3x - 5\t(x > 1)\nf(x) =\tx + 2\t(-1 <= x <= 1)\n\t\t5x + 3\t(x < -1)\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nx = float(input('x = '))\nif x > 1:\n\ty = 3 * x - 5\nelse:\n\tif x >= -1:\n\t\ty = x + 2\n\telse:\n\t\ty = 5 * x + 3\nprint('f(%.2f) = %.2f' % (x, y))\n```\n\n> **说明：**大家可以自己感受一下这两种写法到底是哪一种更好。在之前我们提到的Python之禅中有这么一句话“Flat is bettern than nested.”，之所以提出这个观点是因为嵌套结构的嵌套层次多了之后会严重的影响代码的可读性，如果可以使用扁平化的结构就不要去用嵌套，因此之前的写法是更好的做法。\n\n### 练习\n\n#### 练习1：英制单位与公制单位互换\n\n```Python\n\"\"\"\n\n英制单位英寸和公制单位厘米互换\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nvalue = float(input('请输入长度: '))\nunit = input('请输入单位: ')\nif unit == 'in' or unit == '英寸':\n\tprint('%f英寸 = %f厘米' % (value, value * 2.54))\nelif unit == 'cm' or unit == '厘米':\n\tprint('%f厘米 = %f英寸' % (value, value / 2.54))\nelse:\n\tprint('请输入有效的单位')\n\n```\n\n#### 练习2：掷骰子决定做什么\n\n```Python\n\"\"\"\n\n掷骰子决定做什么事情\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nfrom random import randint\n\nface = randint(1, 6)\nif face == 1:\n\tresult = '唱首歌'\nelif face == 2:\n\tresult = '跳个舞'\nelif face == 3:\n\tresult = '学狗叫'\nelif face == 4:\n\tresult = '做俯卧撑'\nelif face == 5:\n\tresult = '念绕口令'\nelse:\n\tresult = '讲冷笑话'\nprint(result)\n\n```\n> **说明：**上面的代码中使用了random模块的randint函数生成指定范围的随机数来模拟掷骰子。\n\n#### 练习3：百分制成绩转等级制\n\n```Python\n\"\"\"\n\n百分制成绩转等级制成绩\n90分以上    --> A\n80分~89分    --> B\n70分~79分\t   --> C\n60分~69分    --> D\n60分以下    --> E\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nscore = float(input('请输入成绩: '))\nif score >= 90:\n\tgrade = 'A'\nelif score >= 80:\n\tgrade = 'B'\nelif score >= 70:\n\tgrade = 'C'\nelif score >= 60:\n\tgrade = 'D'\nelse:\n\tgrade = 'E'\nprint('对应的等级是:', grade)\n\n```\n#### 练习4：输入三条边长如果能构成三角形就计算周长和面积\n\n```Python\n\"\"\"\n\n判断输入的边长能否构成三角形\n如果能则计算出三角形的周长和面积\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nimport math\n\na = float(input('a = '))\nb = float(input('b = '))\nc = float(input('c = '))\nif a + b > c and a + c > b and b + c > a:\n\tprint('周长: %f' % (a + b + c))\n\tp = (a + b + c) / 2\n\tarea = math.sqrt(p * (p - a) * (p - b) * (p - c))\n\tprint('面积: %f' % (area))\nelse:\n\tprint('不能构成三角形')\n\n```\n> **说明：**上面的代码中使用了`math`模块的`sqrt`函数来计算平方根。用边长计算三角形面积的公式叫做[海伦公式](https://zh.wikipedia.org/zh-hans/海伦公式)。\n\n#### 练习5：实现一个个人所得税计算器。\n\n```Python\n\"\"\"\n\n输入月收入和五险一金计算个人所得税\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-02-28\n\n\"\"\"\n\nsalary = float(input('本月收入: '))\ninsurance = float(input('五险一金: '))\ndiff = salary - insurance - 3500\nif diff <= 0:\n\trate = 0\n\tdeduction = 0\nelif diff < 1500:\n\trate = 0.03\n\tdeduction = 0\nelif diff < 4500:\n\trate = 0.1\n\tdeduction = 105\nelif diff < 9000:\n\trate = 0.2\n\tdeduction = 555\nelif diff < 35000:\n\trate = 0.25\n\tdeduction = 1005\nelif diff < 55000:\n\trate = 0.3\n\tdeduction = 2755\nelif diff < 80000:\n\trate = 0.35\n\tdeduction = 5505\nelse:\n\trate = 0.45\n\tdeduction = 13505\ntax = abs(diff * rate - deduction)\nprint('个人所得税: ￥%.2f元' % tax)\nprint('实际到手收入: ￥%.2f元' % (diff + 3500 - tax))\n\n```\n>**说明：**上面的代码中使用了Python内置的`abs()`函数取绝对值来处理`-0`的问题。\n\n"
  },
  {
    "path": "Day01-15/Day04/for1.py",
    "content": "\"\"\"\n\n用for循环实现1~100求和\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nsum = 0\nfor x in range(1, 101):\n\tif x % 2 == 0:\n\t\tsum += x\nprint(sum)\n"
  },
  {
    "path": "Day01-15/Day04/for2.py",
    "content": "\"\"\"\n\n用for循环实现1~100之间的偶数求和\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nsum = 0\nfor x in range(2, 101, 2):\n\tsum += x\nprint(sum)\n"
  },
  {
    "path": "Day01-15/Day04/for3.py",
    "content": "\"\"\"\n\n输入非负整数n计算n!\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nn = int(input('n = '))\nresult = 1\nfor x in range(1, n + 1):\n\tresult *= x\nprint('%d! = %d' % (n, result))\n"
  },
  {
    "path": "Day01-15/Day04/for4.py",
    "content": "\"\"\"\n\n输入一个正整数判断它是不是素数\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nfrom math import sqrt\n\nnum = int(input('请输入一个正整数: '))\nend = int(sqrt(num))\nis_prime = True\nfor x in range(2, end + 1):\n\tif num % x == 0:\n\t\tis_prime = False\n\t\tbreak\nif is_prime and num != 1:\n\tprint('%d是素数' % num)\nelse:\n\tprint('%d不是素数' % num)\n"
  },
  {
    "path": "Day01-15/Day04/for5.py",
    "content": "\"\"\"\n\n输入两个正整数计算最大公约数和最小公倍数\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nx = int(input('x = '))\ny = int(input('y = '))\nif x > y:\n\t(x, y) = (y, x)\nfor factor in range(x, 0, -1):\n\tif x % factor == 0 and y % factor == 0:\n\t\tprint('%d和%d的最大公约数是%d' % (x, y, factor))\n\t\tprint('%d和%d的最小公倍数是%d' % (x, y, x * y // factor))\n\t\tbreak\n"
  },
  {
    "path": "Day01-15/Day04/for6.py",
    "content": "\"\"\"\n\n打印各种三角形图案\n\n*\n**\n***\n****\n*****\n\n    *\n   **\n  ***\n ****\n*****\n\n    *\n   ***\n  *****\n *******\n*********\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nrow = int(input('请输入行数: '))\nfor i in range(row):\n    for _ in range(i + 1):\n        print('*', end='')\n    print()\n\nfor i in range(row):\n    for j in range(row):\n        if j < row - i - 1:\n            print(' ', end='')\n        else:\n            print('*', end='')\n    print()\n\nfor i in range(row):\n    for _ in range(row - i - 1):\n        print(' ', end='')\n    for _ in range(2 * i + 1):\n        print('*', end='')\n    print()\n"
  },
  {
    "path": "Day01-15/Day04/while1.py",
    "content": "\"\"\"\n\n用while循环实现1~100求和\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nsum = 0\nnum = 1\nwhile num <= 100:\n\tsum += num\n\tnum += 1\nprint(sum)\n"
  },
  {
    "path": "Day01-15/Day04/while2.py",
    "content": "\"\"\"\n\n用while循环实现1~100之间的偶数求和\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nsum = 0\nnum = 2\nwhile num <= 100:\n\tsum += num\n\tnum += 2\nprint(sum)\n"
  },
  {
    "path": "Day01-15/Day04/循环结构.md",
    "content": "## Day04 - 循环结构\n\n### 循环结构的应用场景\n\n如果在程序中我们需要重复的执行某条或某些指令，例如用程序控制机器人踢足球，如果机器人持球而且还没有进入射门范围，那么我们就要一直发出让机器人向球门方向奔跑的指令。当然你可能已经注意到了，刚才的描述中其实不仅仅有需要重复的动作，还有我们上一个章节讲到的分支结构。再举一个简单的例子，比如在我们的程序中要实现每隔1秒中在屏幕上打印一个&quot;hello, world&quot;这样的字符串并持续一个小时，我们肯定不能够将`print('hello, world')`这句代码写上3600遍，如果真的需要这样做那么我们的工作就太无聊了。因此，我们需要循环结构，使用循环结构我们就可以轻松的控制某件事或者某些事重复、重复、再重复的发生。在Python中构造循环结构有两种做法，一种是`for-in`循环，一种是`while`循环。\n\n### for-in循环\n\n如果明确的知道循环执行的次数或者是要对一个容器进行迭代（后面会讲到），那么我们推荐使用`for-in`循环，例如下面代码中计算$\\sum_{n=1}^{100}n$。\n\n```Python\n\"\"\"\n\n用for循环实现1~100求和\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nsum = 0\nfor x in range(101):\n\tsum += x\nprint(sum)\n```\n\n需要说明的是上面代码中的`range`类型，`range`可以用来产生一个不变的数值序列，而且这个序列通常都是用在循环中的，例如：\n\n- `range(101)`可以产生一个0到100的整数序列。\n- `range(1, 100)`可以产生一个1到99的整数序列。\n- `range(1, 100, 2)`可以产生一个1到99的奇数序列，其中的2是步长，即数值序列的增量。\n\n知道了这一点，我们可以用下面的代码来实现1~100之间的偶数求和。\n\n```Python\n\"\"\"\n\n用for循环实现1~100之间的偶数求和\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nsum = 0\nfor x in range(2, 101, 2):\n\tsum += x\nprint(sum)\n```\n\n也可以通过在循环中使用分支结构的方式来实现相同的功能，代码如下所示。\n\n```Python\n\"\"\"\n\n用for循环实现1~100之间的偶数求和\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nsum = 0\nfor x in range(1, 101):\n\tif x % 2 == 0:\n\t\tsum += x\nprint(sum)\n\n```\n\n### while循环\n\n如果要构造不知道具体循环次数的循环结构，我们推荐使用`while`循环，`while`循环通过一个能够产生或转换出`bool`值的表达式来控制循环，表达式的值为`True`循环继续，表达式的值为`False`循环结束。下面我们通过一个“猜数字”的小游戏（计算机出一个1~100之间的随机数，人输入自己猜的数字，计算机给出对应的提示信息，直到人猜出计算机出的数字）来看看如何使用`while`循环。\n\n```Python\n\"\"\"\n\n猜数字游戏\n计算机出一个1~100之间的随机数由人来猜\n计算机根据人猜的数字分别给出提示大一点/小一点/猜对了\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nimport random\n\nanswer = random.randint(1, 100)\ncounter = 0\nwhile True:\n\tcounter += 1\n\tnumber = int(input('请输入: '))\n\tif number < answer:\n\t\tprint('大一点')\n\telif number > answer:\n\t\tprint('小一点')\n\telse:\n\t\tprint('恭喜你猜对了!')\n\t\tbreak\nprint('你总共猜了%d次' % counter)\nif counter > 7:\n\tprint('你的智商余额明显不足')\n\n```\n\n> **说明：**上面的代码中使用了`break`关键字来提前终止循环，需要注意的是`break`只能终止它所在的那个循环，这一点在使用嵌套的循环结构（下面会讲到）需要引起注意。除了`break`之外，还有另一个关键字是`continue`，它可以用来放弃本次循环后续的代码直接让循环进入下一轮。\n\n和分支结构一样，循环结构也是可以嵌套的，也就是说在循环中还可以构造循环结构。下面的例子演示了如何通过嵌套的循环来输出一个九九乘法表。\n\n```Python\n\"\"\"\n\n输出乘法口诀表(九九表)\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nfor i in range(1, 10):\n\tfor j in range(1, i + 1):\n\t\tprint('%d*%d=%d' % (i, j, i * j), end='\\t')\n\tprint()\n\n```\n\n### 练习\n\n#### 练习1：输入一个数判断是不是素数。\n\n```Python\n\"\"\"\n\n输入一个正整数判断它是不是素数\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nfrom math import sqrt\n\nnum = int(input('请输入一个正整数: '))\nend = int(sqrt(num))\nis_prime = True\nfor x in range(2, end + 1):\n\tif num % x == 0:\n\t\tis_prime = False\n\t\tbreak\nif is_prime and num != 1:\n\tprint('%d是素数' % num)\nelse:\n\tprint('%d不是素数' % num)\n\n```\n\n#### 练习2：输入两个正整数，计算最大公约数和最小公倍数。\n\n```Python\n\"\"\"\n\n输入两个正整数计算最大公约数和最小公倍数\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nx = int(input('x = '))\ny = int(input('y = '))\nif x > y:\n\t(x, y) = (y, x)\nfor factor in range(x, 0, -1):\n\tif x % factor == 0 and y % factor == 0:\n\t\tprint('%d和%d的最大公约数是%d' % (x, y, factor))\n\t\tprint('%d和%d的最小公倍数是%d' % (x, y, x * y // factor))\n\t\tbreak\n\n```\n\n#### 练习3：打印三角形图案。\n\n```Python\n\"\"\"\n\n打印各种三角形图案\n\n*\n**\n***\n****\n*****\n\n    *\n   **\n  ***\n ****\n*****\n\n    *\n   ***\n  *****\n *******\n*********\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-01\n\n\"\"\"\n\nrow = int(input('请输入行数: '))\nfor i in range(row):\n    for _ in range(i + 1):\n        print('*', end='')\n    print()\n\n\nfor i in range(row):\n    for j in range(row):\n        if j < row - i - 1:\n            print(' ', end='')\n        else:\n            print('*', end='')\n    print()\n\nfor i in range(row):\n    for _ in range(row - i - 1):\n        print(' ', end='')\n    for _ in range(2 * i + 1):\n        print('*', end='')\n    print()\n\n```\n\n"
  },
  {
    "path": "Day01-15/Day05/chicken.py",
    "content": "\"\"\"\n\n求解《百钱百鸡》问题\n1只公鸡5元 1只母鸡3元 3只小鸡1元 用100元买100只鸡\n问公鸡 母鸡 小鸡各有多少只\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\n\nfor x in range(0, 20):\n\tfor y in range(0, 33):\n\t\tz = 100 - x - y\n\t\tif 5 * x + 3 * y + z / 3 == 100:\n\t\t\tprint('公鸡: %d只, 母鸡: %d只, 小鸡: %d只' % (x, y, z))\n\n# 要理解程序背后的算法 - 穷举法\n"
  },
  {
    "path": "Day01-15/Day05/craps.py",
    "content": "\"\"\"\n\nCraps赌博游戏\n玩家摇两颗色子 如果第一次摇出7点或11点 玩家胜\n如果摇出2点 3点 12点 庄家胜 其他情况游戏继续\n玩家再次要色子 如果摇出7点 庄家胜\n如果摇出第一次摇的点数 玩家胜\n否则游戏继续 玩家继续摇色子\n玩家进入游戏时有1000元的赌注 全部输光游戏结束\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\n\nfrom random import randint\n\nmoney = 1000\nwhile money > 0:\n\tprint('你的总资产为:', money)\n\tneeds_go_on = False\n\twhile True:\n\t\tdebt = int(input('请下注: '))\n\t\tif debt > 0 and debt <= money:\n\t\t\tbreak\n\tfirst = randint(1, 6) + randint(1, 6)\n\tprint('玩家摇出了%d点' % first)\n\tif first == 7 or first == 11:\n\t\tprint('玩家胜!')\n\t\tmoney += debt\n\telif first == 2 or first == 3 or first == 12:\n\t\tprint('庄家胜!')\n\t\tmoney -= debt\n\telse:\n\t\tneeds_go_on = True\n\n\twhile needs_go_on:\n\t\tcurrent = randint(1, 6) + randint(1, 6)\n\t\tprint('玩家摇出了%d点' % current)\n\t\tif current == 7:\n\t\t\tprint('庄家胜')\n\t\t\tmoney -= debt\n\t\t\tneeds_go_on = False\n\t\telif current == first:\n\t\t\tprint('玩家胜')\n\t\t\tmoney += debt\n\t\t\tneeds_go_on = False\n\nprint('你破产了, 游戏结束!')\n"
  },
  {
    "path": "Day01-15/Day05/fibonacci.py",
    "content": "\"\"\"\n\n输出斐波那契数列的前20个数\n1 1 2 3 5 8 13 21 ...\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\n\na = 0\nb = 1\nfor _ in range(20):\n\t(a, b) = (b, a + b)\n\tprint(a, end=' ')\n"
  },
  {
    "path": "Day01-15/Day05/guess.py",
    "content": "\"\"\"\n\n猜数字游戏\n计算机出一个1~100之间的随机数由人来猜\n计算机根据人猜的数字分别给出提示大一点/小一点/猜对了\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\n\nimport random\n\nanswer = random.randint(1, 100)\ncounter = 0\nwhile True:\n\tcounter += 1\n\tnumber = int(input('请输入: '))\n\tif number < answer:\n\t\tprint('大一点')\n\telif number > answer:\n\t\tprint('小一点')\n\telse:\n\t\tprint('恭喜你猜对了!')\n\t\tbreak\nprint('你总共猜了%d次' % counter)\nif counter > 7:\n\tprint('你的智商余额明显不足')\n"
  },
  {
    "path": "Day01-15/Day05/lily.py",
    "content": "\"\"\"\n\n找出100~999之间的所有水仙花数\n水仙花数是各位立方和等于这个数本身的数\n如: 153 = 1**3 + 5**3 + 3**3\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\n\nfor num in range(100, 1000):\n\tlow = num % 10\n\tmid = num // 10 % 10\n\thigh = num // 100\n\tif num == low ** 3 + mid ** 3 + high ** 3:\n\t\tprint(num)\n"
  },
  {
    "path": "Day01-15/Day05/palindrome.py",
    "content": "\"\"\"\n\n判断输入的正整数是不是回文数\n回文数是指将一个正整数从左往右排列和从右往左排列值一样的数\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\n\nnum = int(input('请输入一个正整数: '))\ntemp = num\nnum2 = 0\nwhile temp > 0:\n\tnum2 *= 10\n\tnum2 += temp % 10\n\ttemp //= 10\nif num == num2:\n\tprint('%d是回文数' % num)\nelse:\n\tprint('%d不是回文数' % num)\n"
  },
  {
    "path": "Day01-15/Day05/perfect.py",
    "content": "\"\"\"\n\n找出1~9999之间的所有完美数\n完美数是除自身外其他所有因子的和正好等于这个数本身的数\n例如: 6 = 1 + 2 + 3, 28 = 1 + 2 + 4 + 7 + 14\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\nimport time\nimport math\n\nstart = time.clock()\nfor num in range(1, 10000):\n\tsum = 0\n\tfor factor in range(1, int(math.sqrt(num)) + 1):\n\t\tif num % factor == 0:\n\t\t\tsum += factor\n\t\t\tif factor > 1 and num / factor != factor:\n\t\t\t\tsum += num / factor\n\tif sum == num:\n\t\tprint(num)\nend = time.clock()\nprint(\"执行时间:\", (end - start), \"秒\")\n\n# 通过比较上面两种不同的解决方案的执行时间 意识到优化程序的重要性\n"
  },
  {
    "path": "Day01-15/Day05/prime.py",
    "content": "\"\"\"\n\n输出2~99之间的素数\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\n\nimport math\n\nfor num in range(2, 100):\n\tis_prime = True\n\tfor factor in range(2, int(math.sqrt(num)) + 1):\n\t\tif num % factor == 0:\n\t\t\tis_prime = False\n\t\t\tbreak\n\tif is_prime:\n\t\tprint(num, end=' ')\n"
  },
  {
    "path": "Day01-15/Day05/table.py",
    "content": "\"\"\"\n\n输出乘法口诀表(九九表)\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-02\n\n\"\"\"\n\nfor i in range(1, 10):\n\tfor j in range(1, i + 1):\n\t\tprint('%d*%d=%d' % (i, j, i * j), end='\\t')\n\tprint()\n"
  },
  {
    "path": "Day01-15/Day05/总结和练习.md",
    "content": "## 总结和练习\n"
  },
  {
    "path": "Day01-15/Day06/function1.py",
    "content": "\"\"\"\n\n函数的定义和使用 - 计算组合数C(7,3)\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-05\n\n\"\"\"\n\n\n# 将求阶乘的功能封装成一个函数\ndef factorial(n):\n\tresult = 1\n\tfor num in range(1, n + 1):\n\t\tresult *= num\n\treturn result\n\n\nprint(factorial(7) // factorial(3) // factorial(4))\n"
  },
  {
    "path": "Day01-15/Day06/function2.py",
    "content": "\"\"\"\n\n函数的定义和使用 - 求最大公约数和最小公倍数\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-05\n\n\"\"\"\n\n\ndef gcd(x, y):\n\tif x > y:\n\t\t(x, y) = (y, x)\n\tfor factor in range(x, 1, -1):\n\t\tif x % factor == 0 and y % factor == 0:\n\t\t\treturn factor\n\treturn 1\n\n\ndef lcm(x, y):\n\treturn x * y // gcd(x, y)\n\n\nprint(gcd(15, 27))\nprint(lcm(15, 27))\n"
  },
  {
    "path": "Day01-15/Day06/function3.py",
    "content": "\"\"\"\n\nPython的内置函数\n\t- 数学相关: abs / divmod / pow / round / min / max / sum\n\t- 序列相关: len / range / next / filter / map / sorted / slice / reversed\n\t- 类型转换: chr / ord / str / bool / int / float / complex / bin / oct / hex\n\t- 数据结构: dict / list / set / tuple\n\t- 其他函数: all / any / id / input / open / print / type\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-05\n\n\"\"\"\n\n\ndef myfilter(mystr):\n\treturn len(mystr) == 6\n\n\n# help()\nprint(chr(0x9a86))\nprint(hex(ord('骆')))\nprint(abs(-1.2345))\nprint(round(-1.2345))\nprint(pow(1.2345, 5))\nfruits = ['orange', 'peach', 'durian', 'watermelon']\nprint(fruits[slice(1, 3)])\nfruits2 = list(filter(myfilter, fruits))\nprint(fruits)\nprint(fruits2)\n"
  },
  {
    "path": "Day01-15/Day06/function4.py",
    "content": "\"\"\"\n\nPython常用模块\n\t- 运行时服务相关模块: copy / pickle / sys / ...\n\t- 数学相关模块: decimal / math / random / ...\n\t- 字符串处理模块: codecs / re / ...\n\t- 文件处理相关模块: shutil / gzip / ...\n\t- 操作系统服务相关模块: datetime / os / time / logging / io / ...\n\t- 进程和线程相关模块: multiprocessing / threading / queue\n\t- 网络应用相关模块: ftplib / http / smtplib / urllib / ...\n\t- Web编程相关模块: cgi / webbrowser\n\t- 数据处理和编码模块: base64 / csv / html.parser / json / xml / ...\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-05\n\n\"\"\"\n\nimport time\nimport shutil\nimport os\n\nseconds = time.time()\nprint(seconds)\nlocaltime = time.localtime(seconds)\nprint(localtime)\nprint(localtime.tm_year)\nprint(localtime.tm_mon)\nprint(localtime.tm_mday)\nasctime = time.asctime(localtime)\nprint(asctime)\nstrtime = time.strftime('%Y-%m-%d %H:%M:%S', localtime)\nprint(strtime)\nmydate = time.strptime('2018-1-1', '%Y-%m-%d')\nprint(mydate)\n\nshutil.copy('/Users/Hao/hello.py', '/Users/Hao/Desktop/first.py')\nos.system('ls -l')\nos.chdir('/Users/Hao')\nos.system('ls -l')\nos.mkdir('test')\n"
  },
  {
    "path": "Day01-15/Day06/function5.py",
    "content": "\"\"\"\n\n函数的参数\n\t- 默认参数\n\t- 可变参数\n\t- 关键字参数\n\t- 命名关键字参数\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-05\n\n\"\"\"\n\n\n# 参数默认值\ndef f1(a, b=5, c=10):\n\treturn a + b * 2 + c * 3\n\n\nprint(f1(1, 2, 3))\nprint(f1(100, 200))\nprint(f1(100))\nprint(f1(c=2, b=3, a=1))\n\n\n# 可变参数\ndef f2(*args):\n\tsum = 0\n\tfor num in args:\n\t\tsum += num\n\treturn sum\n\n\nprint(f2(1, 2, 3))\nprint(f2(1, 2, 3, 4, 5))\nprint(f2())\n\n\n# 关键字参数\ndef f3(**kw):\n\tif 'name' in kw:\n\t\tprint('欢迎你%s!' % kw['name'])\n\telif 'tel' in kw:\n\t\tprint('你的联系电话是: %s!' % kw['tel'])\n\telse:\n\t\tprint('没找到你的个人信息!')\n\n\nparam = {'name': '骆昊', 'age': 38}\nf3(**param)\nf3(name='骆昊', age=38, tel='13866778899')\nf3(user='骆昊', age=38, tel='13866778899')\nf3(user='骆昊', age=38, mobile='13866778899')\n"
  },
  {
    "path": "Day01-15/Day06/function6.py",
    "content": "\"\"\"\n\n作用域问题\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-05\n\n\"\"\"\n\n\n# 局部作用域\ndef foo1():\n\ta = 5\n\n\nfoo1()\n# print(a)\t# NameError\n\n# 全局作用域\nb = 10\n\n\ndef foo2():\n\tprint(b)\n\n\nfoo2()\n\n\ndef foo3():\n\tb = 100\t\t# 局部变量\n\tprint(b)\n\n\nfoo3()\nprint(b)\n\n\ndef foo4():\n\tglobal b\n\tb = 200\t\t# 全局变量\n\tprint(b)\n\n\nfoo4()\nprint(b)\n"
  },
  {
    "path": "Day01-15/Day06/函数和模块的使用.md",
    "content": "## 函数和模块的使用\n\n在讲解本章节的内容之前，我们先来研究一道数学题，请说出下面的方程有多少组正整数解。\n\n$$x_1 + x_2 + x_3 + x_4 = 8$$\n\n事实上，上面的问题等同于将8个苹果分成四组每组至少一个苹果有多少种方案。想到这一点问题的答案就呼之欲出了。\n\n$$C_M^N =\\frac{M!}{N!(M-N)!}, \\text{(M=7, N=3)} $$\n\n可以用Python的程序来计算出这个值，代码如下所示。\n\n```Python\n\"\"\"\n\n输入M和N计算C(M,N)\n\n\"\"\"\n\nm = int(input('m = '))\nn = int(input('n = '))\nfm = 1\nfor num in range(1, m + 1):\n    fm *= num\nfn = 1\nfor num in range(1, n + 1):\n    fn *= num\nfmn = 1\nfor num in range(1, m - n + 1):\n    fmn *= num\nprint(fm // fn // fmn)\n\n```\n\n### 函数的作用\n\n不知道大家是否注意到，在上面的代码中，我们做了3次求阶乘，这样的代码实际上就是重复代码。编程大师Martin Fowler先生曾经说过：“代码有很多种坏味道，重复是最坏的一种！”，要写出高质量的代码首先要解决的就是重复代码的问题。对于上面的代码来说，我们可以将计算阶乘的功能封装到一个称之为“函数”的功能模块中，在需要计算阶乘的地方，我们只需要“调用”这个“函数”就可以了。\n\n### 定义函数\n\n在Python中可以使用`def`关键字来定义函数，和变量一样每个函数也有一个响亮的名字，而且命名规则跟变量的命名规则是一致的。在函数名后面的圆括号中可以放置传递给函数的参数，这一点和数学上的函数非常相似，程序中函数的参数就相当于是数学上说的函数的自变量，而函数执行完成后我们可以通过`return`关键字来返回一个值，这相当于数学上说的函数的因变量。\n\n在了解了如何定义函数后，我们可以对上面的代码进行重构，所谓重构就是在不影响代码执行结果的前提下对代码的结构进行调整，重构之后的代码如下所示。\n\n```Python\ndef factorial(num):\n    \"\"\"\n    求阶乘\n    \n    :param num: 非负整数\n    \n    :return: num的阶乘\n    \"\"\"\n    result = 1\n    for n in range(1, num + 1):\n        result *= n\n    return result\n\n\nm = int(input('m = '))\nn = int(input('n = '))\n# 当需要计算阶乘的时候不用再写循环求阶乘而是直接调用已经定义好的函数\nprint(factorial(m) // factorial(n) // factorial(m - n))\n\n```\n\n> **说明：**Python的math模块中其实已经有一个factorial函数了，事实上要计算阶乘可以直接使用这个现成的函数而不用自己定义。下面例子中的某些函数其实Python中也是内置了，我们这里是为了讲解函数的定义和使用才把它们又实现了一遍，实际开发中不建议做这种低级的重复性的工作。\n\n\n### 函数的参数\n\n函数是绝大多数编程语言中都支持的一个代码的“构建块”，但是Python中的函数与其他语言中的函数还是有很多不太相同的地方，其中一个显著的区别就是Python对函数参数的处理。在Python中，函数的参数可以有默认值，也支持使用可变参数，所以Python并不需要像其他语言一样支持[函数的重载](https://zh.wikipedia.org/wiki/%E5%87%BD%E6%95%B0%E9%87%8D%E8%BD%BD)，因为我们在定义一个函数的时候可以让它有多种不同的使用方式，下面是两个小例子。\n\n```Python\nfrom random import randint\n\n\ndef roll_dice(n=2):\n    \"\"\"\n    摇色子\n    \n    :param n: 色子的个数\n    \n    :return: n颗色子点数之和\n    \"\"\"\n\ttotal = 0\n\tfor _ in range(n):\n\t\ttotal += randint(1, 6)\n\treturn total\n\n\ndef add(a=0, b=0, c=0):\n\treturn a + b + c\n\n\n# 如果没有指定参数那么使用默认值摇两颗色子\nprint(roll_dice())\n# 摇三颗色子\nprint(roll_dice(3))\nprint(add())\nprint(add(1))\nprint(add(1, 2))\nprint(add(1, 2, 3))\n# 传递参数时可以不按照设定的顺序进行传递\nprint(add(c=50, a=100, b=200))\n\n```\n\n我们给上面两个函数的参数都设定了默认值，这也就意味着如果在调用函数的时候如果没有传入对应参数的值时将使用该参数的默认值，所以在上面的代码中我们可以用各种不同的方式去调用`add`函数，这跟其他很多语言中函数重载的效果是一致的。\n\n其实上面的`add`函数还有更好的实现方案，因为我们可能会对0个或多个参数进行加法运算，而具体有多少个参数是由调用者来决定，我们作为函数的设计者对这一点是一无所知的，因此在不确定参数个数的时候，我们可以使用可变参数，代码如下所示。\n\n```Python\n# 在参数前使用*表示args是可变参数\n# 也就是说调用add函数时传入的参数个数可以是0个或多个\ndef add(*args):\n\ttotal = 0\n\tfor val in args:\n\t\ttotal += val\n\treturn total\n\n\nprint(add())\nprint(add(1))\nprint(add(1, 2))\nprint(add(1, 2, 3))\nprint(add(1, 3, 5, 7, 9))\n\n```\n\n### 用模块管理函数\n\n对于任何一种编程语言来说，给变量、函数这样的标识符起名字都是一个让人头疼的问题，因为我们会遇到命名冲突这种尴尬的情况。最简单的场景就是在同一个.py文件中定义了两个同名函数，由于Python没有函数重载的概念，那么后面的定义会覆盖之前的定义，也就意味着两个函数同名函数实际上只有一个是存在的。\n\n```Python\ndef foo():\n\tprint('hello, world!')\n\n\ndef foo():\n\tprint('goodbye, world!')\n\n\nfoo()\t# 输出goodbye, world!\n\n```\n\n当然上面的这种情况我们很容易就能避免，但是如果项目是由多人协作进行团队开发的时候，团队中可能有多个程序员都定义了名为`foo`的函数，那么怎么解决这种命名冲突呢？答案其实很简单，Python中每个文件就代表了一个模块（module），我们在不同的模块中可以有同名的函数，在使用函数的时候我们通过`import`关键字导入指定的模块就可以区分到底要使用的是哪个模块中的`foo`函数，代码如下所示。\n\nmodule1.py\n\n```Python\ndef foo():\n    print('hello, world!')\n```\n\nmodule2.py\n\n```Python\ndef foo():\n    print('goodbye, world!')\n```\n\ntest.py\n\n```Python\nfrom module1 import foo\n\nfoo()\t# 输出hello, world!\n\nfrom module2 import foo\n\nfoo()\t# 输出goodbye, world!\n\n```\n\n也可以按照如下所示的方式来区分到底要使用哪一个`foo`函数。\n\ntest.py\n\n```Python\nimport module1 as m1\nimport module2 as m2\n\nm1.foo()\nm2.foo()\n\n```\n\n但是如果将代码写成了下面的样子，那么程序中调用的是最后导入的那个`foo`，因为后导入的foo覆盖了之前导入的`foo`。\n\ntest.py\n\n```Python\nfrom module1 import foo\nfrom module2 import foo\n\nfoo()\t# 输出goodbye, world!\n\n```\n\ntest.py\n\n```Python\nfrom module2 import foo\nfrom module1 import foo\n\nfoo()\t# 输出hello, world!\n\n```\n\n需要说明的是，如果我们导入的模块除了定义函数之外还中有可以执行代码，那么Python解释器在导入这个模块时就会执行这些代码，事实上我们可能并不希望如此，因此如果我们在模块中编写了执行代码，最好是将这些执行代码放入如下所示的条件中，这样的话除非直接运行该模块，if条件下的这些代码是不会执行的，因为只有直接执行的模块的名字才是“\\_\\_main\\_\\_”。\n\nmodule3.py\n\n```Python\ndef foo():\n    pass\n\n\ndef bar():\n    pass\n\n\n# __name__是Python中一个隐含的变量它代表了模块的名字\n# 只有被Python解释器直接执行的模块的名字才是__main__\nif __name__ == '__main__':\n    print('call foo()')\n    foo()\n    print('call bar()')\n    bar()\n\n```\n\ntest.py\n\n```Python\nimport module3\n\n# 导入module3时 不会执行模块中if条件成立时的代码 因为模块的名字是module3而不是__main__\n\n```\n\n### 练习\n\n#### 练习1：实现计算求最大公约数和最小公倍数的函数。\n\n```Python\ndef gcd(x, y):\n\t(x, y) = (y, x) if x > y else (x, y)\n\tfor factor in range(x, 0, -1):\n\t\tif x % factor == 0 and y % factor == 0:\n\t\t\treturn factor\n\n\ndef lcm(x, y):\n\treturn x * y // gcd(x, y)\n```\n\n#### 练习2：实现判断一个数是不是回文数的函数。\n\n```Python\ndef is_palindrome(num):\n\ttemp = num\n\ttotal = 0\n\twhile temp > 0:\n\t\ttotal = total * 10 + temp % 10\n\t\ttemp //= 10\n\treturn total == num\n```\n\n#### 练习3：实现判断一个数是不是素数的函数。\n\n```Python\ndef is_prime(num):\n\tfor factor in range(2, num):\n\t\tif num % factor == 0:\n\t\t\treturn False\n\treturn True if num != 1 else False\n```\n\n#### 练习4：写一个程序判断输入的正整数是不是回文素数。\n\n```Python\nif __name__ == '__main__':\n\tnum = int(input('请输入正整数: '))\n\tif is_palindrome(num) and is_prime(num):\n\t\tprint('%d是回文素数' % num)\n\n```\n\n通过上面的程序可以看出，当我们将代码中重复出现的和相对独立的功能抽取成函数后，我们可以组合使用这些函数来解决更为复杂的问题，这也是我们为什么要定义和使用函数的一个非常重要的原因。\n\n最后，我们来讨论一下Python中有关变量作用域的问题。\n\n```Python\ndef foo():\n\tb = 'hello'\n\n\tdef bar():  # Python中可以在函数内部再定义函数\n        c = True\n\t\tprint(a)\n\t\tprint(b)\n        print(c)\n\n\tbar()\n    # print(c)  # NameError: name 'c' is not defined\n\n\nif __name__ == '__main__':\n\ta = 100\n    # print(b)  # NameError: name 'b' is not defined\n\tfoo()\n\n```\n\n上面的代码能够顺利的执行并且打印出100和“hello”，但我们注意到了，在`bar`函数的内部并没有定义`a`和`b`两个变量，那么`a`和`b`是从哪里来的。我们在上面代码的`if`分支中定义了一个变量`a`，这是一个全局变量（global variable），属于全局作用域，因为它没有定义在任何一个函数中。在上面的`foo`函数中我们定义了变量`b`，这是一个定义在函数中的局部变量（local variable），属于局部作用域，在`foo`函数的外部并不能访问到它；但对于`foo`函数内部的`bar`函数来说，变量`b`属于嵌套作用域，在`bar`函数中我们是可以访问到它的。`bar`函数中的变量`c`属于局部作用域，在`bar`函数之外是无法访问的。事实上，Python查找一个变量时会按照“局部作用域”、“嵌套作用域”、“全局作用域”和“内置作用域”的顺序进行搜索，前三者我们在上面的代码中已经看到了，所谓的“内置作用域”就是Python内置的那些隐含标识符`min`、`len`等都属于内置作用域）。\n\n再看看下面这段代码，我们希望通过函数调用修改全局变量`a`的值，但实际上下面的代码是做不到的。\n\n```Python\ndef foo():\n\ta = 200\n\tprint(a)  # 200\n\n\nif __name__ == '__main__':\n\ta = 100\n\tfoo()\n\tprint(a)  # 100\n\n```\n\n在调用`foo`函数后，我们发现`a`的值仍然是100，这是因为当我们在函数`foo`中写`a = 200`的时候，是重新定义了一个名字为`a`的局部变量，它跟全局作用域的`a`并不是同一个变量，因为局部作用域中有了自己的变量`a`，因此`foo`函数不再搜索全局作用域中的`a`。如果我们希望在`foo`函数中修改全局作用域中的`a`，代码如下所示。\n\n```Python\ndef foo():\n\tglobal a\n\ta = 200\n\tprint(a)  # 200\n\n\nif __name__ == '__main__':\n\ta = 100\n\tfoo()\n\tprint(a)  # 200\n\n```\n\n我们可以使用`global`关键字来指示`foo`函数中的变量`a`来自于全局作用域，如果全局作用域中没有`a`，那么下面一行的代码就会定义变量`a`并将其置于全局作用域。同理，如果我们希望函数内部的函数能够修改嵌套作用域中的变量，可以使用`nonlocal`关键字来指示变量来自于嵌套作用域，请大家自行试验。\n\n在实际开发中，我们应该尽量减少对全局变量的使用，因为全局变量的作用域和影响过于广泛，可能会发生意料之外的修改和使用，除此之外全局变量比局部变量拥有更长的生命周期，可能导致对象占用的内存长时间无法被[垃圾回收](https://zh.wikipedia.org/wiki/%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6_(%E8%A8%88%E7%AE%97%E6%A9%9F%E7%A7%91%E5%AD%B8))。事实上，减少对全局变量的使用，也是降低代码之间耦合度的一个重要举措，同时也是对[迪米特法则](https://zh.wikipedia.org/zh-hans/%E5%BE%97%E5%A2%A8%E5%BF%92%E8%80%B3%E5%AE%9A%E5%BE%8B)的践行。减少全局变量的使用就意味着我们应该尽量让变量的作用域在函数的内部，但是如果我们希望将一个局部变量的生命周期延长，使其在函数调用结束后依然可以访问，这时候就需要使用[闭包](https://zh.wikipedia.org/wiki/%E9%97%AD%E5%8C%85_(%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A7%91%E5%AD%A6))，这个我们在后续的内容中进行讲解。\n\n> **说明**：很多人经常会将“闭包”一词和[“匿名函数”](https://zh.wikipedia.org/wiki/%E5%8C%BF%E5%90%8D%E5%87%BD%E6%95%B0)混为一谈，但实际上它们是不同的概念，如果想提前了解这个概念，推荐看看[维基百科](https://zh.wikipedia.org/wiki/)或者[知乎](https://www.zhihu.com/)上对这个概念的讨论。\n\n说了那么多，其实结论很简单，从现在开始我们可以将Python代码按照下面的格式进行书写，这一点点的改进其实就是在我们理解了函数和作用域的基础上跨出的巨大的一步。\n\n```Python\ndef main():\n    # Todo: Add your code here\n    pass\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n"
  },
  {
    "path": "Day01-15/Day07/avgscore.py",
    "content": "\"\"\"\n\n输入学生考试成绩计算平均分\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tnumber = int(input('请输入学生人数: '))\n\tnames = [None] * number\n\tscores = [None] * number\n\tfor index in range(len(names)):\n\t\tnames[index] = input('请输入第%d个学生的名字: ' % (index + 1))\n\t\tscores[index] = float(input('请输入第%d个学生的成绩: ' % (index + 1)))\n\ttotal = 0\n\tfor index in range(len(names)):\n\t\tprint('%s: %.1f分' % (names[index], scores[index]))\n\t\ttotal += scores[index]\n\tprint('平均成绩是: %.1f分' % (total / number))\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/dict1.py",
    "content": "\"\"\"\n\n定义和使用字典\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tscores = {'骆昊': 95, '白元芳': 78, '狄仁杰': 82}\n\tprint(scores['骆昊'])\n\tprint(scores['狄仁杰'])\n\tfor elem in scores:\n\t\tprint('%s\\t--->\\t%d' % (elem, scores[elem]))\n\tscores['白元芳'] = 65\n\tscores['诸葛王朗'] = 71\n\tscores.update(冷面=67, 方启鹤=85)\n\tprint(scores)\n\tif '武则天' in scores:\n\t\tprint(scores['武则天'])\n\tprint(scores.get('武则天'))\n\tprint(scores.get('武则天', 60))\n\tprint(scores.popitem())\n\tprint(scores.popitem())\n\tprint(scores.pop('骆昊', 100))\n\tscores.clear()\n\tprint(scores)\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/dict2.py",
    "content": "\"\"\"\n\n字典的常用操作\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tstu = {'name': '骆昊', 'age': 38, 'gender': True}\n\tprint(stu)\n\tprint(stu.keys())\n\tprint(stu.values())\n\tprint(stu.items())\n\tfor elem in stu.items():\n\t\tprint(elem)\n\t\tprint(elem[0], elem[1])\n\tif 'age' in stu:\n\t\tstu['age'] = 20\n\tprint(stu)\n\tstu.setdefault('score', 60)\n\tprint(stu)\n\tstu.setdefault('score', 100)\n\tprint(stu)\n\tstu['score'] = 100\n\tprint(stu)\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/fibonacci.py",
    "content": "\"\"\"\n\n生成斐波拉切数列\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tf = [1 , 1]\n\tfor i in range(2, 20):\n\t\tf += [f[i - 1] + f[i - 2]]\n\t\t# f.append(f[i - 1] + f[i - 2])\n\tfor val in f:\n\t\tprint(val, end=' ')\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/findmax.py",
    "content": "\"\"\"\n\n找出列表中最大或最小的元素\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tfruits = ['grape', 'apple', 'strawberry', 'waxberry', 'pitaya']\n\t# 直接使用内置的max和min函数找出列表中最大和最小元素\n\t# print(max(fruits))\n\t# print(min(fruits))\n\tmax_value = min_value = fruits[0]\n\tfor index in range(1, len(fruits)):\n\t\tif fruits[index] > max_value:\n\t\t\tmax_value = fruits[index]\n\t\telif fruits[index] < min_value:\n\t\t\tmin_value = fruits[index]\n\tprint('Max:', max_value)\n\tprint('Min:', min_value)\n\n\nif __name__ == '__main__':\n\tmain()\n# 想一想如果最大的元素有两个要找出第二大的又该怎么做 \n"
  },
  {
    "path": "Day01-15/Day07/list1.py",
    "content": "\"\"\"\n\n定义和使用列表\n\t- 用下标访问元素\n\t- 添加元素\n\t- 删除元素\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tfruits = ['grape', '@pple', 'strawberry', 'waxberry']\n\tprint(fruits)\n\t# 通过下标访问元素\n\tprint(fruits[0])\n\tprint(fruits[1])\n\tprint(fruits[-1])\n\tprint(fruits[-2])\n\t# print(fruits[-5]) # IndexError\n\t# print(fruits[4])\t# IndexError\n\tfruits[1] = 'apple'\n\tprint(fruits)\n\t# 添加元素\n\tfruits.append('pitaya')\n\tfruits.insert(0, 'banana')\n\tprint(fruits)\n\t# 删除元素\n\tdel fruits[1]\n\tfruits.pop()\n\tfruits.pop(0)\n\tfruits.remove('apple')\n\tprint(fruits)\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/list2.py",
    "content": "\"\"\"\n\n列表常用操作\n\t- 列表连接\n\t- 获取长度\n\t- 遍历列表\n\t- 列表切片\n\t- 列表排序\n\t- 列表反转\n\t- 查找元素\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tfruits = ['grape', 'apple', 'strawberry', 'waxberry']\n\tfruits += ['pitaya', 'pear', 'mango']\n\t# 循环遍历列表元素\n\tfor fruit in fruits:\n\t\tprint(fruit.title(), end=' ')\n\tprint()\n\t# 列表切片\n\tfruits2 = fruits[1:4]\n\tprint(fruits2)\n\t# fruit3 = fruits  # 没有复制列表只创建了新的引用\n\tfruits3 = fruits[:]\n\tprint(fruits3)\n\tfruits4 = fruits[-3:-1]\n\tprint(fruits4)\n\tfruits5 = fruits[::-1]\n\tprint(fruits5)\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/list3.py",
    "content": "\"\"\"\n\n生成列表\n\t- 用range创建数字列表\n\t- 生成表达式\n\t- 生成器\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\n# 生成Fibonacci序列的生成器\ndef fib(n):\n\ta, b = 0, 1\n\tfor _ in range(n):\n\t\ta, b = b, a + b\n\t\tyield a\n\n\ndef main():\n\t# 用range创建数值列表\n\tlist1 = list(range(1, 11))\n\tprint(list1)\n\t# 生成表达式\n\tlist2 = [x * x for x in range(1, 11)]\n\tprint(list2)\n\tlist3 = [m + n for m in 'ABCDEFG' for n in '12345']\n\tprint(list3)\n\tprint(len(list3))\n\t# 生成器(节省空间但生成下一个元素时需要花费时间)\n\tgen = (m + n for m in 'ABCDEFG' for n in '12345')\n\tprint(gen)\n\tfor elem in gen:\n\t\tprint(elem, end=' ')\n\tprint()\n\tgen = fib(20)\n\tprint(gen)\n\tfor elem in gen:\n\t\tprint(elem, end=' ')\n\tprint()\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/lottery.py",
    "content": "\"\"\"\n\n双色球随机选号程序\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\nfrom random import randrange, randint, sample\n\n\ndef display(balls):\n\t\"\"\"\n\t输出列表中的双色球号码\n\t\"\"\"\n\tfor index, ball in enumerate(balls):\n\t\tif index == len(balls) - 1:\n\t\t\tprint('|', end=' ')\n\t\tprint('%02d' % ball, end=' ')\n\tprint()\n\n\ndef random_select():\n\t\"\"\"\n\t随机选择一组号码\n\t\"\"\"\n\tred_balls = [x for x in range(1, 34)]\n\tselected_balls = []\n\tfor _ in range(6):\n\t\tindex = randrange(len(red_balls))\n\t\tselected_balls.append(red_balls[index])\n\t\tdel red_balls[index]\n\t# 上面的for循环也可以写成下面这行代码\n\t# sample函数是random模块下的函数\n\t# selected_balls = sample(red_balls, 6)\n\tselected_balls.sort()\n\tselected_balls.append(randint(1, 16))\n\treturn selected_balls\n\n\ndef main():\n\tn = int(input('机选几注: '))\n\tfor _ in range(n):\n\t\tdisplay(random_select())\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/marquee.py",
    "content": "\"\"\"\n\n输入学生考试成绩计算平均分\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\nimport os\nimport time\n\n\ndef main():\n\tstr = 'Welcome to 1000 Phone Chengdu Campus      '\n\twhile True:\n\t\tprint(str)\n\t\ttime.sleep(0.2)\n\t\tstr = str[1:] + str[0:1]\n\t\t# for Windows use os.system('cls') instead\n\t\tos.system('clear')\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/scoretable.py",
    "content": "\"\"\"\n\n学生考试成绩表\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tnames = ['关羽', '张飞', '赵云', '马超', '黄忠']\n\tsubjs = ['语文', '数学', '英语']\n\tscores = [[0] * 3] * 5\n\tfor row, name in enumerate(names):\n\t\tprint('请输入%s的成绩' % name)\n\t\tfor col, subj in enumerate(subjs):\n\t\t\tscores[row][col] = float(input(subj + ': '))\n\tprint(scores)\n#\tfor row, name in enumerate(names):\n#\t\tprint('请输入%s的成绩' % name)\n#\t\tscores[row] = [None] * len(subjs)\n#\t\tfor col, subj in enumerate(subjs):\n#\t\t\tscore = float(input(subj + ': '))\n#\t\t\tscores[row][col] = score\n#\tprint(scores)\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/set1.py",
    "content": "\"\"\"\n\n定义和使用集合\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n    set1 = {1, 2, 3, 3, 3, 2}\n    print(set1)\n    print('Length =', len(set1))\n    set2 = set(range(1, 10))\n    print(set2)\n    set1.add(4)\n    set1.add(5)\n    set2.update([11, 12])\n    print(set1)\n    print(set2)\n    set2.discard(5)\n    # remove的元素如果不存在会引发KeyError\n    if 4 in set2:\n        set2.remove(4)\n    print(set2)\n    # 遍历集合容器\n    for elem in set2:\n        print(elem ** 2, end=' ')\n    print()\n    # 将元组转换成集合\n    set3 = set((1, 2, 3, 3, 2, 1))\n    print(set3.pop())\n    print(set3)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day07/set2.py",
    "content": "\"\"\"\n\n集合的常用操作\n\t- 交集\n\t- 并集\n\t- 差集\n\t- 子集\n\t- 超集\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\tset1 = set(range(1, 7))\n\tprint(set1)\n\tset2 = set(range(2, 11, 2))\n\tprint(set2)\n\tset3 = set(range(1, 5))\n\tprint(set1 & set2)\n\t# print(set1.intersection(set2))\n\tprint(set1 | set2)\n\t# print(set1.union(set2))\n\tprint(set1 - set2)\n\t# print(set1.difference(set2))\n\tprint(set1 ^ set2)\n\t# print(set1.symmetric_difference(set2))\n\tprint(set2 <= set1)\n\t# print(set2.issubset(set1))\n\tprint(set3 <= set1)\n\t# print(set3.issubset(set1))\n\tprint(set1 >= set2)\n\t# print(set1.issuperset(set2))\n\tprint(set1 >= set3)\n\t# print(set1.issuperset(set3))\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/tic-tac-toe.py",
    "content": "\"\"\"\n\n井字棋游戏\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\nimport os\n\n\n\ndef print_board(board):\n\tprint(board['TL'] + '|' + board['TM'] + '|' + board['TR'])\n\tprint('-+-+-')\n\tprint(board['ML'] + '|' + board['MM'] + '|' + board['MR'])\n\tprint('-+-+-')\n\tprint(board['BL'] + '|' + board['BM'] + '|' + board['BR'])\n\n\ndef main():\n\tinit_board = {\n\t\t'TL': ' ', 'TM': ' ', 'TR': ' ',\n\t\t'ML': ' ', 'MM': ' ', 'MR': ' ',\n\t\t'BL': ' ', 'BM': ' ', 'BR': ' '\n\t}\n\tbegin = True\n\twhile begin:\n\t\tcurr_board = init_board.copy()\n\t\tbegin = False\n\t\tturn = 'x'\n\t\tcounter = 0\n\t\tos.system('clear')\n\t\tprint_board(curr_board)\n\t\twhile counter < 9:\n\t\t\tmove = input('轮到%s走棋, 请输入位置: ' % turn)\n\t\t\tif curr_board[move] == ' ':\n\t\t\t\tcounter += 1\n\t\t\t\tcurr_board[move] = turn\n\t\t\t\tif turn == 'x':\n\t\t\t\t\tturn = 'o'\n\t\t\t\telse:\n\t\t\t\t\tturn = 'x'\n\t\t\tos.system('clear')\n\t\t\tprint_board(curr_board)\n\t\tchoice = input('再玩一局?(yes|no)')\n\t\tbegin = choice == 'yes'\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day07/tuple.py",
    "content": "\"\"\"\n\n元组的定义和使用\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n\t# 定义元组\n\tt = ('骆昊', 38, True, '四川成都')\n\tprint(t)\n\t# 获取元组中的元素\n\tprint(t[0])\n\tprint(t[1])\n\tprint(t[2])\n\tprint(t[3])\n\t# 遍历元组中的值\n\tfor member in t:\n\t\tprint(member)\n\t# 重新给元组赋值\n\t# t[0] = '王大锤'\t\t# TypeError\n\t# 变量t重新引用了新的元组 原来的元组被垃圾回收\n\tt = ('王大锤', 20, True, '云南昆明')\n\tprint(t)\n\t# 元组和列表的转换\n\tperson = list(t)\n\tprint(person)\n\tperson[0] = '李小龙'\n\tperson[1] = 25\n\tprint(person)\n\tfruits_list = ['apple', 'banana', 'orange']\n\tfruits_tuple = tuple(fruits_list)\n\tprint(fruits_tuple)\n\tprint(fruits_tuple[1])\n\n\nif __name__ == '__main__':\n\tmain()"
  },
  {
    "path": "Day01-15/Day07/yanghui.py",
    "content": "\"\"\"\n\n输出10行的杨辉三角 - 二项式的n次方展开系数\n1\n1 1\n1 2 1\n1 3 3 1\n1 4 6 4 1\n... ... ...\n\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-06\n\n\"\"\"\n\n\ndef main():\n    num = int(input('Number of rows: '))\n    yh = [[]] * num\n    for row in range(len(yh)):\n        yh[row] = [None] * (row + 1)\n        for col in range(len(yh[row])):\n            if col == 0 or col == row:\n                yh[row][col] = 1\n            else:\n                yh[row][col] = yh[row - 1][col] + yh[row - 1][col - 1]\n            print(yh[row][col], end='\\t')\n        print()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day07/字符串和常用数据结构.md",
    "content": "## 字符串和常用数据结构\n\n### 使用字符串\n\n第二次世界大战促使了现代电子计算机的诞生，当初的想法很简单，就是用计算机来计算导弹的弹道，因此在计算机刚刚诞生的那个年代，计算机处理的信息主要是数值，而世界上的第一台电子计算机ENIAC每秒钟能够完成约5000次浮点运算。随着时间的推移，虽然对数值运算仍然是计算机日常工作中最为重要的事情之一，但是今天的计算机处理得更多的数据都是以文本信息的方式存在的，而Python表示文本信息的方式我们在很早以前就说过了，那就是字符串类型。所谓**字符串**，就是由零个或多个字符组成的有限序列，一般记为[$${\\displaystyle s=a_{1}a_{2}\\dots a_{n}(0\\leq n \\leq \\infty)}$$](https://wikimedia.org/api/rest_v1/media/math/render/svg/e29bf631b090323edd6889f810e6cff29538b161)。\n\n我们可以通过下面的代码来了解字符串的使用。\n\n```Python\ndef main():\n    str1 = 'hello, world!'\n    # 通过len函数计算字符串的长度\n    print(len(str1))  # 13\n    # 获得字符串首字母大写的拷贝\n    print(str1.capitalize())  # Hello, world!\n    # 获得字符串变大写后的拷贝\n    print(str1.upper())  # HELLO, WORLD!\n    # 从字符串中查找子串所在位置\n    print(str1.find('or'))  # 8\n    print(str1.find('shit'))  # -1\n    # 与find类似但找不到子串时会引发异常\n    # print(str1.index('or'))\n    # print(str1.index('shit'))\n    # 检查字符串是否以指定的字符串开头\n    print(str1.startswith('He'))  # False\n    print(str1.startswith('hel'))  # True\n    # 检查字符串是否以指定的字符串结尾\n    print(str1.endswith('!'))  # True\n    # 将字符串以指定的宽度居中并在两侧填充指定的字符\n    print(str1.center(50, '*'))\n    # 将字符串以指定的宽度靠右放置左侧填充指定的字符\n    print(str1.rjust(50, ' '))\n    str2 = 'abc123456'\n    # 从字符串中取出指定位置的字符(下标运算)\n    print(str2[2])  # c\n    # 字符串切片(从指定的开始索引到指定的结束索引)\n    print(str2[2:5])  # c12\n    print(str2[2:])  # c123456\n    print(str2[2::2])  # c246\n    print(str2[::2])  # ac246\n    print(str2[::-1])  # 654321cba\n    print(str2[-3:-1])  # 45\n    # 检查字符串是否由数字构成\n    print(str2.isdigit())  # False\n    # 检查字符串是否以字母构成\n    print(str2.isalpha())  # False\n    # 检查字符串是否以数字和字母构成\n    print(str2.isalnum())  # True\n    str3 = '  jackfrued@126.com '\n    print(str3)\n    # 获得字符串修剪左右两侧空格的拷贝\n    print(str3.strip())\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n除了字符串，Python还内置了多种类型的数据结构，如果要在程序中保存和操作数据，绝大多数时候可以利用现有的数据结构来实现，最常用的包括列表、元组、集合和字典。\n\n### 使用列表\n\n下面的代码演示了如何定义列表、使用下标访问列表元素以及添加和删除元素的操作。\n\n```Python\ndef main():\n\tlist1 = [1, 3, 5, 7, 100]\n    print(list1)\n    list2 = ['hello'] * 5\n    print(list2)\n\t# 计算列表长度(元素个数)\n\tprint(len(list1))\n\t# 下标(索引)运算\n\tprint(list1[0])\n\tprint(list1[4])\n\t# print(list1[5])  # IndexError: list index out of range\n\tprint(list1[-1])\n\tprint(list1[-3])\n\tlist1[2] = 300\n\tprint(list1)\n\t# 添加元素\n\tlist1.append(200)\n\tlist1.insert(1, 400)\n\tlist1 += [1000, 2000]\n\tprint(list1)\n\tprint(len(list1))\n\t# 删除元素\n\tlist1.remove(3)\n\tif 1234 in list1:\n\t\tlist1.remove(1234)\n\tdel list1[0]\n\tprint(list1)\n\t# 清空列表元素\n\tlist1.clear()\n\tprint(list1)\n\t\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n和字符串一样，列表也可以做切片操作，通过切片操作我们可以实现对列表的复制或者将列表中的一部分取出来创建出新的列表，代码如下所示。\n\n```Python\ndef main():\n\tfruits = ['grape', 'apple', 'strawberry', 'waxberry']\n\tfruits += ['pitaya', 'pear', 'mango']\n\t# 循环遍历列表元素\n\tfor fruit in fruits:\n\t\tprint(fruit.title(), end=' ')\n\tprint()\n\t# 列表切片\n\tfruits2 = fruits[1:4]\n\tprint(fruits2)\n\t# fruit3 = fruits  # 没有复制列表只创建了新的引用\n    # 可以通过完整切片操作来复制列表\n\tfruits3 = fruits[:]\n\tprint(fruits3)\n\tfruits4 = fruits[-3:-1]\n\tprint(fruits4)\n    # 可以通过反向切片操作来获得倒转后的列表的拷贝\n\tfruits5 = fruits[::-1]\n\tprint(fruits5)\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n下面的代码实现了对列表的排序操作。\n\n```Python\ndef main():\n    list1 = ['orange', 'apple', 'zoo', 'internationalization', 'blueberry']\n    list2 = sorted(list1)\n    # sorted函数返回列表排序后的拷贝不会修改传入的列表\n    # 函数的设计就应该像sorted函数一样尽可能不产生副作用\n    list3 = sorted(list1, reverse=True)\n    # 通过key关键字参数指定根据字符串长度进行排序而不是默认的字母表顺序\n    list4 = sorted(list1, key=len)\n    print(list1)\n    print(list2)\n    print(list3)\n    print(list4)\n    # 给列表对象发出排序消息直接在列表对象上进行排序\n    list1.sort(reverse=True)\n    print(list1)\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n我们还可以使用列表的生成式语法来创建列表，代码如下所示。\n\n```Python\nimport sys\n\n\ndef main():\n    f = [x for x in range(1, 10)]\n    print(f)\n    f = [x + y for x in 'ABCDE' for y in '1234567']\n    print(f)\n    # 用列表的生成表达式语法创建列表容器\n    # 用这种语法创建列表之后元素已经准备就绪所以需要耗费较多的内存空间\n    f = [x ** 2 for x in range(1, 1000)]\n    print(sys.getsizeof(f))  # 查看对象占用内存的字节数\n    print(f)\n    # 请注意下面的代码创建的不是一个列表而是一个生成器对象\n    # 通过生成器可以获取到数据但它不占用额外的空间存储数据\n    # 每次需要数据的时候就通过内部的运算得到数据(需要花费额外的时间)\n    f = (x ** 2 for x in range(1, 1000))\n    print(sys.getsizeof(f))  # 相比生成式生成器不占用存储数据的空间\n    print(f)\n    for val in f:\n        print(val)\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n除了上面提到的生成器语法，Python中还有另外一种定义生成器的方式，就是通过`yield`关键字将一个普通函数改造成生成器函数。下面的代码演示了如何实现一个生成[斐波拉切数列](https://zh.wikipedia.org/wiki/%E6%96%90%E6%B3%A2%E9%82%A3%E5%A5%91%E6%95%B0%E5%88%97)的生成器。所谓斐波拉切数列可以通过下面[递归](https://zh.wikipedia.org/wiki/%E9%80%92%E5%BD%92)的方法来进行定义：\n\n$${\\displaystyle F_{0}=0}$$\n\n$${\\displaystyle F_{1}=1}$$\n\n$${\\displaystyle F_{n}=F_{n-1}+F_{n-2}}({n}\\geq{2})$$\n\n![](./res/fibonacci-blocks.png)\n\n```Python\ndef fib(n):\n    a, b = 0, 1\n    for _ in range(n):\n        a, b = b, a + b\n        yield a\n\n\ndef main():\n\tfor val in fib(20):\n\t    print(val)\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n### 使用元组\n\nPython 的元组与列表类似，不同之处在于元组的元素不能修改，在前面的代码中我们已经不止一次使用过元组了。顾名思义，我们把多个元素组合到一起就形成了一个元组，所以它和列表一样可以保存多条数据。下面的代码演示了如何定义和使用元组。\n\n```Python\ndef main():\n\t# 定义元组\n\tt = ('骆昊', 38, True, '四川成都')\n\tprint(t)\n\t# 获取元组中的元素\n\tprint(t[0])\n\tprint(t[3])\n\t# 遍历元组中的值\n\tfor member in t:\n\t\tprint(member)\n\t# 重新给元组赋值\n\t# t[0] = '王大锤'  # TypeError\n\t# 变量t重新引用了新的元组原来的元组将被垃圾回收\n\tt = ('王大锤', 20, True, '云南昆明')\n\tprint(t)\n\t# 将元组转换成列表\n\tperson = list(t)\n\tprint(person)\n    # 列表是可以修改它的元素的\n\tperson[0] = '李小龙'\n\tperson[1] = 25\n\tprint(person)\n    # 将列表转换成元组\n\tfruits_list = ['apple', 'banana', 'orange']\n\tfruits_tuple = tuple(fruits_list)\n\tprint(fruits_tuple)\n\n\nif __name__ == '__main__':\n\tmain()\n```\n\n这里有一个非常值得探讨的问题，我们已经有了列表这种数据结构，为什么还需要元组这样的类型呢？\n\n1. 元组中的元素是无法修改的，事实上我们在项目中尤其是[多线程](https://zh.wikipedia.org/zh-hans/%E5%A4%9A%E7%BA%BF%E7%A8%8B)环境（后面会讲到）中可能更喜欢使用的是那些不变对象（一方面因为对象状态不能修改，所以可以避免由此引起的不必要的程序错误，简单的说就是一个不变的对象要比可变的对象更加容易维护；另一方面因为没有任何一个线程能够修改不变对象的内部状态，一个不变对象自动就是线程安全的，这样就可以省掉处理同步化的开销。一个不变对象可以方便的被共享访问）。所以结论就是：如果不需要对元素进行添加、删除、修改的时候，可以考虑使用元组，当然如果一个方法要返回多个值，使用元组也是不错的选择。\n2. 元组在创建时间和占用的空间上面都优于列表。我们可以使用sys模块的getsizeof函数来检查存储同样的元素的元组和列表各自占用了多少内存空间，这个很容易做到。我们也可以在ipython中使用魔法指令%timeit来分析创建同样内容的元组和列表所花费的时间，下图是我的macOS系统上测试的结果。\n\n![](./res/ipython-timeit.png)\n\n### 使用集合\n\nPython中的集合跟数学上的集合是一致的，不允许有重复元素，而且可以进行交集、并集、差集等运算。\n\n![](./res/python-set.png)\n\n```Python\ndef main():\n    set1 = {1, 2, 3, 3, 3, 2}\n    print(set1)\n    print('Length =', len(set1))\n    set2 = set(range(1, 10))\n    print(set2)\n    set1.add(4)\n    set1.add(5)\n    set2.update([11, 12])\n    print(set1)\n    print(set2)\n    set2.discard(5)\n    # remove的元素如果不存在会引发KeyError\n    if 4 in set2:\n        set2.remove(4)\n    print(set2)\n    # 遍历集合容器\n    for elem in set2:\n        print(elem ** 2, end=' ')\n    print()\n    # 将元组转换成集合\n    set3 = set((1, 2, 3, 3, 2, 1))\n    print(set3.pop())\n    print(set3)\n    # 集合的交集、并集、差集、对称差运算\n    print(set1 & set2)\n    # print(set1.intersection(set2))\n    print(set1 | set2)\n    # print(set1.union(set2))\n    print(set1 - set2)\n    # print(set1.difference(set2))\n    print(set1 ^ set2)\n    # print(set1.symmetric_difference(set2))\n    # 判断子集和超集\n    print(set2 <= set1)\n    # print(set2.issubset(set1))\n    print(set3 <= set1)\n    # print(set3.issubset(set1))\n    print(set1 >= set2)\n    # print(set1.issuperset(set2))\n    print(set1 >= set3)\n    # print(set1.issuperset(set3))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n> **说明**：Python中允许通过一些特殊的方法来为某种类型或数据结构自定义运算符（后面的章节中会讲到），上面的代码中我们对集合进行运算的时候可以调用集合对象的方法，也可以直接使用对应的运算符，例如`&`运算符跟intersection方法的作用就是一样的，但是使用运算符让代码更加直观。\n\n### 使用字典\n\n字典是另一种可变容器模型，类似于我们生活中使用的字典，它可以存储任意类型对象，与列表、集合不同的是，字典的每个元素都是由一个键和一个值组成的“键值对”，键和值通过冒号分开。下面的代码演示了如何定义和使用字典。\n\n```Python\ndef main():\n\tscores = {'骆昊': 95, '白元芳': 78, '狄仁杰': 82}\n    # 通过键可以获取字典中对应的值\n\tprint(scores['骆昊'])\n\tprint(scores['狄仁杰'])\n    # 对字典进行遍历(遍历的其实是键再通过键取对应的值)\n\tfor elem in scores:\n\t\tprint('%s\\t--->\\t%d' % (elem, scores[elem]))\n    # 更新字典中的元素\n\tscores['白元芳'] = 65\n\tscores['诸葛王朗'] = 71\n\tscores.update(冷面=67, 方启鹤=85)\n\tprint(scores)\n\tif '武则天' in scores:\n\t\tprint(scores['武则天'])\n\tprint(scores.get('武则天'))\n    # get方法也是通过键获取对应的值但是可以设置默认值\n\tprint(scores.get('武则天', 60))\n    # 删除字典中的元素\n\tprint(scores.popitem())\n\tprint(scores.popitem())\n\tprint(scores.pop('骆昊', 100))\n    # 清空字典\n\tscores.clear()\n\tprint(scores)\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n### 练习\n\n#### 练习1：在屏幕上显示跑马灯文字\n\n```Python\nimport os\nimport time\n\n\ndef main():\n    content = '北京欢迎你为你开天辟地…………'\n    while True:\n        # 清理屏幕上的输出\n        os.system('cls')  # os.system('clear')\n        print(content)\n        # 休眠200毫秒\n        time.sleep(0.2)\n        content = content[1:] + content[0]\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n#### 练习2：设计一个函数产生指定长度的验证码，验证码由大小写字母和数字构成。\n\n```Python\nimport random\n\n\ndef generate_code(code_len=4):\n    \"\"\"\n    生成指定长度的验证码\n\n    :param code_len: 验证码的长度(默认4个字符)\n\n    :return: 由大小写英文字母和数字构成的随机验证码\n    \"\"\"\n    all_chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'\n    last_pos = len(all_chars) - 1\n    code = ''\n    for _ in range(code_len):\n        index = random.randint(0, last_pos)\n        code += all_chars[index]\n    return code\n```\n\n#### 练习3：设计一个函数返回给定文件名的后缀名。\n\n```Python\ndef get_suffix(filename, has_dot=False):\n    \"\"\"\n    获取文件名的后缀名\n\n    :param filename: 文件名\n    :param has_dot: 返回的后缀名是否需要带点\n\n    :return: 文件的后缀名\n    \"\"\"\n    pos = filename.rfind('.')\n    if 0 < pos < len(filename) - 1:\n        index = pos if has_dot else pos + 1\n        return filename[index:]\n    else:\n        return ''\n    \n```\n\n#### 练习4：设计一个函数返回传入的列表中最大和第二大的元素的值。\n\n```Python\ndef max2(x):\n    m1, m2 = (x[0], x[1]) if x[0] > x[1] else (x[1], x[0])\n    for index in range(2, len(x)):\n        if x[index] > m1:\n            m2 = m1\n            m1 = x[index]\n        elif x[index] > m2:\n            m2 = x[index]\n    return m1, m2\n```\n\n#### 练习5：计算指定的年月日是这一年的第几天\n\n```Python\ndef is_leap_year(year):\n    \"\"\"\n    判断指定的年份是不是闰年\n\n    :param year: 年份\n\n    :return: 闰年返回True平年返回False\n    \"\"\"\n    return year % 4 == 0 and year % 100 != 0 or year % 400 == 0\n\n\ndef which_day(year, month, date):\n    \"\"\"\n    计算传入的日期是这一年的第几天\n\n    :param year: 年\n    :param month: 月\n    :param date: 日\n\n    :return: 第几天\n    \"\"\"\n    days_of_month = [\n        [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],\n        [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]\n    ][is_leap_year(year)]\n    total = 0\n    for index in range(month - 1):\n        total += days_of_month[index]\n    return total + date\n\n\ndef main():\n    print(which_day(1980, 11, 28))\n    print(which_day(1981, 12, 31))\n    print(which_day(2018, 1, 1))\n    print(which_day(2016, 3, 1))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n#### 练习6：打印[杨辉三角](https://zh.wikipedia.org/wiki/%E6%9D%A8%E8%BE%89%E4%B8%89%E8%A7%92%E5%BD%A2)。\n\n```Python\ndef main():\n    num = int(input('Number of rows: '))\n    yh = [[]] * num\n    for row in range(len(yh)):\n        yh[row] = [None] * (row + 1)\n        for col in range(len(yh[row])):\n            if col == 0 or col == row:\n                yh[row][col] = 1\n            else:\n                yh[row][col] = yh[row - 1][col] + yh[row - 1][col - 1]\n            print(yh[row][col], end='\\t')\n        print()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n### 综合案例\n\n#### 案例1：双色球选号\n\n```Python\nfrom random import randrange, randint, sample\n\n\ndef display(balls):\n    \"\"\"\n    输出列表中的双色球号码\n    \"\"\"\n    for index, ball in enumerate(balls):\n        if index == len(balls) - 1:\n            print('|', end=' ')\n        print('%02d' % ball, end=' ')\n    print()\n\n\ndef random_select():\n    \"\"\"\n    随机选择一组号码\n    \"\"\"\n    red_balls = [x for x in range(1, 34)]\n    selected_balls = []\n    for _ in range(6):\n        index = randrange(len(red_balls))\n        selected_balls.append(red_balls[index])\n        del red_balls[index]\n    # 上面的for循环也可以写成下面这行代码\n    # sample函数是random模块下的函数\n    # selected_balls = sample(red_balls, 6)\n    selected_balls.sort()\n    selected_balls.append(randint(1, 16))\n    return selected_balls\n\n\ndef main():\n    n = int(input('机选几注: '))\n    for _ in range(n):\n        display(random_select())\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n> **说明**：可以使用random模块的sample函数来实现从列表中选择不重复的n个元素。\n\n#### 综合案例2：[约瑟夫环问题](https://zh.wikipedia.org/wiki/%E7%BA%A6%E7%91%9F%E5%A4%AB%E6%96%AF%E9%97%AE%E9%A2%98)\n\n```Python\n\"\"\"\n\n《幸运的基督徒》\n有15个基督徒和15个非基督徒在海上遇险，为了能让一部分人活下来不得不将其中15个人扔到海里面去，有个人想了个办法就是大家围成一个圈，由某个人开始从1报数，报到9的人就扔到海里面，他后面的人接着从1开始报数，报到9的人继续扔到海里面，直到扔掉15个人。由于上帝的保佑，15个基督徒都幸免于难，问这些人最开始是怎么站的，哪些位置是基督徒哪些位置是非基督徒。\n\n\"\"\"\n\n\ndef main():\n    persons = [True] * 30\n    counter, index, number = 0, 0, 0\n    while counter < 15:\n        if persons[index]:\n            number += 1\n            if number == 9:\n                persons[index] = False\n                counter += 1\n                number = 0\n        index += 1\n        index %= 30\n    for person in persons:\n        print('基' if person else '非', end='')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n#### 综合案例3：[井字棋](https://zh.wikipedia.org/wiki/%E4%BA%95%E5%AD%97%E6%A3%8B)游戏\n\n```Python\nimport os\n\n\ndef print_board(board):\n\tprint(board['TL'] + '|' + board['TM'] + '|' + board['TR'])\n\tprint('-+-+-')\n\tprint(board['ML'] + '|' + board['MM'] + '|' + board['MR'])\n\tprint('-+-+-')\n\tprint(board['BL'] + '|' + board['BM'] + '|' + board['BR'])\n\n\ndef main():\n\tinit_board = {\n\t\t'TL': ' ', 'TM': ' ', 'TR': ' ',\n\t\t'ML': ' ', 'MM': ' ', 'MR': ' ',\n\t\t'BL': ' ', 'BM': ' ', 'BR': ' '\n\t}\n\tbegin = True\n\twhile begin:\n\t\tcurr_board = init_board.copy()\n\t\tbegin = False\n\t\tturn = 'x'\n\t\tcounter = 0\n\t\tos.system('clear')\n\t\tprint_board(curr_board)\n\t\twhile counter < 9:\n\t\t\tmove = input('轮到%s走棋, 请输入位置: ' % turn)\n\t\t\tif curr_board[move] == ' ':\n\t\t\t\tcounter += 1\n\t\t\t\tcurr_board[move] = turn\n\t\t\t\tif turn == 'x':\n\t\t\t\t\tturn = 'o'\n\t\t\t\telse:\n\t\t\t\t\tturn = 'x'\n\t\t\tos.system('clear')\n\t\t\tprint_board(curr_board)\n\t\tchoice = input('再玩一局?(yes|no)')\n\t\tbegin = choice == 'yes'\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n>**说明**：最后这个案例来自[《Python编程快速上手:让繁琐工作自动化》](https://item.jd.com/11943853.html)一书（这本书对有编程基础想迅速使用Python将日常工作自动化的人来说还是不错的教材），对代码做了一点点的调整。"
  },
  {
    "path": "Day01-15/Day08/access.py",
    "content": "class Test:\n\n\tdef __init__(self, foo):\n\t\tself.__foo = foo\n\n\tdef __bar(self):\n\t\tprint(self.__foo)\n\t\tprint('__bar')\n\n\ndef main():\n\ttest = Test('hello')\n\ttest._Test__bar()\n\tprint(test._Test__foo)\n\n\nif __name__ == \"__main__\":\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day08/circle.py",
    "content": "\"\"\"\n\n练习\n修一个游泳池 半径(以米为单位)在程序运行时输入 游泳池外修一条3米宽的过道\n过道的外侧修一圈围墙 已知过道的造价为25元每平米 围墙的造价为32.5元每米\n输出围墙和过道的总造价分别是多少钱(精确到小数点后2位)\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-08\n\n\"\"\"\n\nimport math\n\n\nclass Circle(object):\n\n\tdef __init__(self, radius):\n\t\tself._radius = radius\n\n\t@property\n\tdef radius(self):\n\t\treturn self._radius\n\n\t@radius.setter\n\tdef radius(self, radius):\n\t\tself._radius = radius if radius > 0 else 0\n\n\t@property\n\tdef perimeter(self):\n\t\treturn 2 * math.pi * self._radius\n\n\t@property\n\tdef area(self):\n\t\treturn math.pi * self._radius * self._radius\n\n\nif __name__ == '__main__':\t\n\tradius = float(input('请输入游泳池的半径: '))\n\tsmall = Circle(radius)\n\tbig = Circle(radius + 3)\n\tprint('围墙的造价为: ￥%.1f元' % (big.perimeter * 115))\n\tprint('过道的造价为: ￥%.1f元' % ((big.area - small.area) * 65))\n"
  },
  {
    "path": "Day01-15/Day08/clock.py",
    "content": "\"\"\"\n\n定义和使用时钟类\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-08\n\n\"\"\"\n\nimport time\nimport os\n\n\nclass Clock(object):\n\n\t# Python中的函数是没有重载的概念的\n\t# 因为Python中函数的参数没有类型而且支持缺省参数和可变参数\n\t# 用关键字参数让构造器可以传入任意多个参数来实现其他语言中的构造器重载\n\tdef __init__(self, **kw):\n\t\tif 'hour' in kw and 'minute' in kw and 'second' in kw:\n\t\t\tself._hour = kw['hour']\n\t\t\tself._minute = kw['minute']\n\t\t\tself._second = kw['second']\n\t\telse:\n\t\t\ttm = time.localtime(time.time())\n\t\t\tself._hour = tm.tm_hour\n\t\t\tself._minute = tm.tm_min\n\t\t\tself._second = tm.tm_sec\n\n\tdef run(self):\n\t\tself._second += 1\n\t\tif self._second == 60:\n\t\t\tself._second = 0\n\t\t\tself._minute += 1\n\t\t\tif self._minute == 60:\n\t\t\t\tself._minute = 0\n\t\t\t\tself._hour += 1\n\t\t\t\tif self._hour == 24:\n\t\t\t\t\tself._hour = 0\n\n\tdef show(self):\n\t\treturn '%02d:%02d:%02d' % (self._hour, self._minute, self._second)\n\n\nif __name__ == '__main__':\n\t# clock = Clock(hour=10, minute=5, second=58)\n\tclock = Clock()\n\twhile True:\n\t\tos.system('clear')\n\t\tprint(clock.show())\n\t\ttime.sleep(1)\n\t\tclock.run()\n"
  },
  {
    "path": "Day01-15/Day08/guess.py",
    "content": "\"\"\"\n\n面向对象版本的猜数字游戏\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-08\n\n\"\"\"\n\nfrom random import randint\n\n\nclass GuessMachine(object):\n\n\tdef __init__(self):\n\t\tself._answer = None\n\t\tself._counter = None\n\t\tself._hint = None\n\n\tdef reset(self):\n\t\tself._answer = randint(1, 100)\n\t\tself._counter = 0\n\t\tself._hint = None\n\n\tdef guess(self, your_answer):\n\t\tself._counter += 1\n\t\tif your_answer > self._answer:\n\t\t\tself._hint = '小一点'\n\t\telif your_answer < self._answer:\n\t\t\tself._hint = '大一点'\n\t\telse:\n\t\t\tself._hint = '恭喜你猜对了'\n\t\t\treturn True\n\t\treturn False\n\n\t@property\n\tdef counter(self):\n\t\treturn self._counter\n\n\t@property\n\tdef hint(self):\n\t\treturn self._hint\n\n\nif __name__ == '__main__':\n\tgm = GuessMachine()\n\tplay_again = True\n\twhile play_again:\n\t\tgame_over = False\n\t\tgm.reset()\n\t\twhile not game_over:\n\t\t\tyour_answer = int(input('请输入: '))\n\t\t\tgame_over = gm.guess(your_answer)\n\t\t\tprint(gm.hint)\n\t\tif gm.counter > 7:\n\t\t\tprint('智商余额不足!')\n\t\tplay_again = input('再玩一次?(yes|no)') == 'yes'\n"
  },
  {
    "path": "Day01-15/Day08/hack.py",
    "content": "\"\"\"\n\n另一种创建类的方式\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-08\n\n\"\"\"\n\n\ndef bar(self, name):\n\tself._name = name\n\n\ndef foo(self, course_name):\n\tprint('%s正在学习%s.' % (self._name, course_name))\n\n\ndef main():\n\tStudent = type('Student', (object,), dict(__init__=bar, study=foo))\n\tstu1 = Student('骆昊')\n\tstu1.study('Python程序设计')\n\n\nif __name__ == '__main__':\n\tmain()\t\n"
  },
  {
    "path": "Day01-15/Day08/rect.py",
    "content": "\"\"\"\n\n定义和使用矩形类\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-08\n\n\"\"\"\n\n\nclass Rect(object):\n\t\"\"\"矩形类\"\"\"\n\n\tdef __init__(self, width=0, height=0):\n\t\t\"\"\"构造器\"\"\"\n\t\tself.__width = width\n\t\tself.__height = height\n\n\tdef perimeter(self):\n\t\t\"\"\"计算周长\"\"\"\n\t\treturn (self.__width + self.__height) * 2\n\n\tdef area(self):\n\t\t\"\"\"计算面积\"\"\"\n\t\treturn self.__width * self.__height\n\n\tdef __str__(self):\n\t\t\"\"\"矩形对象的字符串表达式\"\"\"\n\t\treturn '矩形[%f,%f]' % (self.__width, self.__height)\n\n\tdef __del__(self):\n\t\t\"\"\"析构器\"\"\"\n\t\tprint('销毁矩形对象')\n\n\nif __name__ == '__main__':\n\trect1 = Rect()\n\tprint(rect1)\n\tprint(rect1.perimeter())\n\tprint(rect1.area())\n\trect2 = Rect(3.5, 4.5)\n\tprint(rect2)\n\tprint(rect2.perimeter())\n\tprint(rect2.area())\n"
  },
  {
    "path": "Day01-15/Day08/student.py",
    "content": "\"\"\"\n\n定义和使用学生类\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-08\n\n\"\"\"\n\n\ndef _foo():\n\tprint('test')\n\n\nclass Student(object):\n\n\t# __init__是一个特殊方法用于在创建对象时进行初始化操作\n\t# 通过这个方法我们可以为学生对象绑定name和age两个属性\n\tdef __init__(self, name, age):\n\t\tself.name = name\n\t\tself.age = age\n\n\tdef study(self, course_name):\n\t\tprint('%s正在学习%s.' % (self.name, course_name))\n\n\t# PEP 8要求标识符的名字用全小写多个单词用下划线连接\n\t# 但是很多程序员和公司更倾向于使用驼峰命名法(驼峰标识)\n\tdef watch_av(self):\n\t\tif self.age < 18:\n\t\t\tprint('%s只能观看《熊出没》.' % self.name)\n\t\telse:\n\t\t\tprint('%s正在观看岛国爱情动作片.' % self.name)\n\n\ndef main():\n\tstu1 = Student('骆昊', 38)\n\tstu1.study('Python程序设计')\n\tstu1.watch_av()\n\tstu2 = Student('王大锤', 15)\n\tstu2.study('思想品德')\n\tstu2.watch_av()\n\n\nif __name__ == '__main__':\n\tmain()"
  },
  {
    "path": "Day01-15/Day08/test.py",
    "content": ""
  },
  {
    "path": "Day01-15/Day08/面向对象编程基础.md",
    "content": "## 面向对象编程基础\n\n活在当下的程序员应该都听过“面向对象编程”一词，也经常有人问能不能用一句话解释下什么是“面向对象编程”，我们先来看看比较正式的说法。\n\n> 把一组数据结构和处理它们的方法组成对象（object），把相同行为的对象归纳为类（class），通过类的封装（encapsulation）隐藏内部细节，通过继承（inheritance）实现类的特化（specialization）和泛化（generalization），通过多态（polymorphism）实现基于对象类型的动态分派。\n\n这样一说是不是更不明白了。所以我们还是看看更通俗易懂的说法，下面这段内容来自于[知乎](https://www.zhihu.com/)。\n\n![](./res/oop-zhihu.png)\n\n> **说明**：以上的内容来自于网络，不代表作者本人的观点和看法，与作者本人立场无关，相关责任不由作者承担。（终于有机会享受一下把这段话反过来说的乐趣了，乐得牙都快碎了。）\n\n之前我们说过“程序是指令的集合”，我们在程序中书写的语句在执行时会变成一条或多条指令然后由CPU去执行。当然为了简化程序的设计，我们引入了函数的概念，把相对独立且经常重复使用的代码放置到函数中，在需要使用这些功能的时候只要调用函数即可；如果一个函数的功能过于复杂和臃肿，我们又可以进一步将函数继续切分为子函数来降低系统的复杂性。但是说了这么多，不知道大家是否发现，所谓编程就是程序员按照计算机的工作方式控制计算机完成各种任务。但是，计算机的工作方式与正常人类的思维模式是不同的，如果编程就必须得抛弃人类正常的思维方式去迎合计算机，编程的乐趣就少了很多，“每个人都应该学习编程”这样的豪言壮语就只能说说而已。当然，这些还不是最重要的，最重要的是当我们需要开发一个复杂的系统时，代码的复杂性会让开发和维护工作都变得举步维艰，所以在上世纪60年代末期，“[软件危机](https://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E5%8D%B1%E6%9C%BA)”、“[软件工程](https://zh.wikipedia.org/wiki/%E8%BD%AF%E4%BB%B6%E5%B7%A5%E7%A8%8B)”等一系列的概念开始在行业中出现。\n\n当然，程序员圈子内的人都知道，现实中并没有解决上面所说的这些问题的“[银弹](https://zh.wikipedia.org/wiki/%E6%B2%A1%E6%9C%89%E9%93%B6%E5%BC%B9)”，真正让软件开发者看到希望的是上世纪70年代诞生的[Smalltalk](https://zh.wikipedia.org/wiki/Smalltalk)编程语言中引入的面向对象的编程思想（面向对象编程的雏形可以追溯到更早期的[Simula](https://zh.wikipedia.org/wiki/Simula)语言）。按照这种编程理念，程序中的数据和操作数据的函数是一个逻辑上的整体，我们称之为“对象”，而我们解决问题的方式就是创建出需要的对象并向对象发出各种各样的消息，多个对象的协同工作最终可以让我们构造出复杂的系统来解决现实中的问题。\n\n> **说明**：当然面向对象也不是解决软件开发中所有问题的最后的“银弹”，所以今天的高级程序设计语言几乎都提供了对多种编程范式的支持，Python也不例外。\n\n### 类和对象\n\n简单的说，类是对象的蓝图和模板，而对象是类的实例。这个解释虽然有点像用概念在解释概念，但是从这句话我们至少可以看出，类是抽象的概念，而对象是具体的东西。在面向对象编程的世界中，一切皆为对象，对象都有属性和行为，每个对象都是独一无二的，而且对象一定属于某个类（型）。当我们把一大堆拥有共同特征的对象的静态特征（属性）和动态特征（行为）都抽取出来后，就可以定义出一个叫做“类”的东西。\n\n![](./res/object-feature.png)\n\n### 定义类\n\n在Python中可以使用`class`关键字定义类，然后在类中通过之前学习过的函数来定义方法，这样就可以将对象的动态特征描述出来，代码如下所示。\n\n```Python\nclass Student(object):\n\n\t# __init__是一个特殊方法用于在创建对象时进行初始化操作\n\t# 通过这个方法我们可以为学生对象绑定name和age两个属性\n\tdef __init__(self, name, age):\n\t\tself.name = name\n\t\tself.age = age\n\n\tdef study(self, course_name):\n\t\tprint('%s正在学习%s.' % (self.name, course_name))\n\n\t# PEP 8要求标识符的名字用全小写多个单词用下划线连接\n\t# 但是很多程序员和公司更倾向于使用驼峰命名法(驼峰标识)\n\tdef watch_av(self):\n\t\tif self.age < 18:\n\t\t\tprint('%s只能观看《熊出没》.' % self.name)\n\t\telse:\n\t\t\tprint('%s正在观看岛国爱情动作片.' % self.name)\n```\n\n> **说明**：写在类中的函数，我们通常称之为（对象的）方法，这些方法就是对象可以接收的消息。\n\n### 创建和使用对象\n\n当我们定义好一个类之后，可以通过下面的方式来创建对象并给对象发消息。\n\n```Python\ndef main():\n    # 创建学生对象并指定姓名和年龄\n\tstu1 = Student('骆昊', 38)\n    # 给对象发study消息\n\tstu1.study('Python程序设计')\n    # 给对象发watch_av消息\n\tstu1.watch_av()\n\tstu2 = Student('王大锤', 15)\n\tstu2.study('思想品德')\n\tstu2.watch_av()\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n### 访问可见性问题\n\n对于上面的代码，有C++、Java、C#等编程经验的程序员可能会问，我们给`Student`对象绑定的`name`和`age`属性到底具有怎样的访问权限（也称为可见性）。因为在很多面向对象编程语言中，我们通常会将对象的属性设置为私有的（private）或受保护的（protected），简单的说就是不允许外界访问，而对象的方法通常都是公开的（public），因为公开的方法就是对象能够接受的消息。在Python中，属性和方法的访问权限只有两种，也就是公开的和私有的，如果希望属性是私有的，在给属性命名时可以用两个下划线作为开头，下面的代码可以验证这一点。\n\n```Python\nclass Test:\n\n\tdef __init__(self, foo):\n\t\tself.__foo = foo\n\n\tdef __bar(self):\n\t\tprint(self.__foo)\n\t\tprint('__bar')\n\n\ndef main():\n\ttest = Test('hello')\n\t# AttributeError: 'Test' object has no attribute '__bar'\n\ttest.__bar()\n\t# AttributeError: 'Test' object has no attribute '__foo'\n\tprint(test.__foo)\n\n\nif __name__ == \"__main__\":\n\tmain()\n\n```\n\n但是，Python并没有从语法上严格保证私有属性或方法的私密性，它只是给私有的属性和方法换了一个名字来“妨碍”对它们的访问，事实上如果你知道更换名字的规则仍然可以访问到它们，下面的代码就可以验证这一点。之所以这样设定，可以用这样一句名言加以解释，就是“We are all consenting adults here”。因为绝大多数程序员都认为开放比封闭要好，而且程序员要自己为自己的行为负责。\n\n```Python\nclass Test:\n\n\tdef __init__(self, foo):\n\t\tself.__foo = foo\n\n\tdef __bar(self):\n\t\tprint(self.__foo)\n\t\tprint('__bar')\n\n\ndef main():\n\ttest = Test('hello')\n\ttest._Test__bar()\n\tprint(test._Test__foo)\n\n\nif __name__ == \"__main__\":\n\tmain()\n\n```\n\n在实际开发中，我们并不建议将属性设置为私有的，因为这会导致子类无法访问（后面会讲到）。所以大多数Python程序员会遵循一种命名惯例就是让属性名以单下划线开头来表示属性是受保护的，本类之外的代码在访问这样的属性时应该要保持慎重。这种做法并不是语法上的规则，单下划线开头的属性和方法外界仍然是可以访问的，所以更多的时候它是一种暗示或隐喻，关于这一点可以看看我的[《Python - 那些年我们踩过的那些坑》](http://blog.csdn.net/jackfrued/article/details/79521404)文章中的讲解。\n\n### 面向对象的支柱\n\n面向对象有三大支柱：封装、继承和多态。后面两个概念在下一个章节中进行详细的说明，这里我们先说一下什么是封装。我自己对封装的理解是“隐藏一切可以隐藏的实现细节，只向外界暴露（提供）简单的编程接口”。我们在类中定义的方法其实就是把数据和对数据的操作封装起来了，在我们创建了对象之后，只需要给对象发送一个消息（调用方法）就可以执行方法中的代码，也就是说我们只需要知道方法的名字和传入的参数（方法的外部视图），而不需要知道方法内部的实现细节（方法的内部视图）。\n\n### 练习\n\n#### 练习1：定义一个类描述数字时钟\n\n```Python\nclass Clock(object):\n    \"\"\"\n    数字时钟\n    \"\"\"\n\n    def __init__(self, hour=0, minute=0, second=0):\n        \"\"\"\n        构造器\n\n        :param hour: 时\n        :param minute: 分\n        :param second: 秒\n        \"\"\"\n        self._hour = hour\n        self._minute = minute\n        self._second = second\n\n    def run(self):\n        \"\"\"走字\"\"\"\n        self._second += 1\n        if self._second == 60:\n            self._second = 0\n            self._minute += 1\n            if self._minute == 60:\n                self._minute = 0\n                self._hour += 1\n                if self._hour == 24:\n                    self._hour = 0\n\n    def __str__(self):\n        \"\"\"显示时间\"\"\"\n        return '%02d:%02d:%02d' % \\\n               (self._hour, self._minute, self._second)\n\n\ndef main():\n    clock = Clock(23, 59, 58)\n    while True:\n        print(clock)\n        sleep(1)\n        clock.run()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n#### 练习2：定义一个类描述平面上的点并提供移动点和计算到另一个点距离的方法。\n\n```Python\nfrom math import sqrt\n\n\nclass Point(object):\n\n    def __init__(self, x=0, y=0):\n        \"\"\"\n        构造器\n        \n        :param x: 横坐标\n        :param y: 纵坐标\n        \"\"\"\n        self.x = x\n        self.y = y\n\n    def move_to(self, x, y):\n        \"\"\"\n        移动到指定位置\n        \n        :param x: 新的横坐标\n        \"param y: 新的纵坐标\n        \"\"\"\n        self.x = x\n        self.y = y\n\n    def move_by(self, dx, dy):\n        \"\"\"\n        移动指定的增量\n        \n        :param dx: 横坐标的增量\n        \"param dy: 纵坐标的增量\n        \"\"\"\n        self.x += dx\n        self.y += dy\n\n    def distance_to(self, other):\n        \"\"\"\n        计算与另一个点的距离\n        \n        :param other: 另一个点\n        \"\"\"\n        dx = self.x - other.x\n        dy = self.y - other.y\n        return sqrt(dx ** 2 + dy ** 2)\n\n    def __str__(self):\n        return '(%s, %s)' % (str(self.x), str(self.y))\n\n\ndef main():\n    p1 = Point(3, 5)\n    p2 = Point()\n    print(p1)\n    print(p2)\n    p2.move_by(-1, 2)\n    print(p2)\n    print(p1.distance_to(p2))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n> **说明**：本章中的插图来自于Grady Booch等著作的[《面向对象分析与设计》](https://item.jd.com/20476561918.html)一书，该书是讲解面向对象编程的经典著作，有兴趣的读者可以购买和阅读这本书来了解更多的面向对象的相关知识。"
  },
  {
    "path": "Day01-15/Day09/association.py",
    "content": "\"\"\"\n\n对象之间的关联关系\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\nfrom math import sqrt\n\n\nclass Point(object):\n\n\tdef __init__(self, x=0, y=0):\n\t\tself._x = x\n\t\tself._y = y\n\n\tdef move_to(self, x, y):\n\t\tself._x = x\n\t\tself._y = y\n\n\tdef move_by(self, dx, dy):\n\t\tself._x += dx\n\t\tself._y += dy\n\n\tdef distance_to(self, other):\n\t\tdx = self._x - other._x\n\t\tdy = self._y - other._y\n\t\treturn sqrt(dx ** 2 + dy ** 2)\n\n\tdef __str__(self):\n\t\treturn '(%s, %s)' % (str(self._x), str(self._y))\n\n\nclass Line(object):\n\n\tdef __init__(self, start=Point(0, 0), end=Point(0, 0)):\n\t\tself._start = start\n\t\tself._end = end\n\n\t@property\n\tdef start(self):\n\t\treturn self._start\n\n\t@start.setter\n\tdef start(self, start):\n\t\tself._start = start\n\n\t@property\n\tdef end(self):\n\t\treturn self.end\n\n\t@end.setter\n\tdef end(self, end):\n\t\tself._end = end\n\n\t@property\n\tdef length(self):\n\t\treturn self._start.distance_to(self._end)\n\n\nif __name__ == '__main__':\n\tp1 = Point(3, 5)\n\tprint(p1)\n\tp2 = Point(-2, -1.5)\n\tprint(p2)\n\tline = Line(p1, p2)\n\tprint(line.length)\n\tline.start.move_to(2, 1)\n\tline.end = Point(1, 2)\n\tprint(line.length)\n"
  },
  {
    "path": "Day01-15/Day09/car1.py",
    "content": "\"\"\"\n\n属性的使用\n\t- 访问器/修改器/删除器\n\t- 使用__slots__对属性加以限制\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\n\nclass Car(object):\n\n\t__slots__ = ('_brand', '_max_speed')\n\n\tdef __init__(self, brand, max_speed):\n\t\tself._brand = brand\n\t\tself._max_speed = max_speed\n\n\t@property\n\tdef brand(self):\n\t\treturn self._brand\n\n\t@brand.setter\n\tdef brand(self, brand):\n\t\tself._brand = brand\n\n\t@brand.deleter\n\tdef brand(self):\n\t\tdel self._brand\n\n\t@property\n\tdef max_speed(self):\n\t\treturn self._max_speed\n\n\t@max_speed.setter\n\tdef max_speed(self, max_speed):\n\t\tif max_speed < 0:\n\t\t\traise ValueError('Invalid max speed for car')\n\t\tself._max_speed = max_speed\n\n\tdef __str__(self):\n\t\treturn 'Car: [品牌=%s, 最高时速=%d]' % (self._brand, self._max_speed)\n\n\ncar = Car('QQ', 120)\nprint(car)\n# ValueError\n# car.max_speed = -100\ncar.max_speed = 320\ncar.brand = \"Benz\"\n# 使用__slots__属性限制后下面的代码将产生异常\n# car.current_speed = 80\nprint(car)\n# 如果提供了删除器可以执行下面的代码\n# del car.brand\n# 属性的实现\nprint(Car.brand)\nprint(Car.brand.fget)\nprint(Car.brand.fset)\nprint(Car.brand.fdel)\n# 通过上面的代码帮助学生理解之前提到的包装器的概念\n# Python中有很多类似的语法糖后面还会出现这样的东西\n"
  },
  {
    "path": "Day01-15/Day09/car2.py",
    "content": "\"\"\"\n\n属性的使用\n\t- 使用已有方法定义访问器/修改器/删除器\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\n\nclass Car(object):\n\n\tdef __init__(self, brand, max_speed):\n\t\tself.set_brand(brand)\n\t\tself.set_max_speed(max_speed)\n\n\tdef get_brand(self):\n\t\treturn self._brand\n\n\tdef set_brand(self, brand):\n\t\tself._brand = brand\n\n\tdef get_max_speed(self):\n\t\treturn self._max_speed\n\n\tdef set_max_speed(self, max_speed):\n\t\tif max_speed < 0:\n\t\t\traise ValueError('Invalid max speed for car')\n\t\tself._max_speed = max_speed\n\n\tdef __str__(self):\n\t\treturn 'Car: [品牌=%s, 最高时速=%d]' % (self._brand, self._max_speed)\n\n\t# 用已有的修改器和访问器定义属性\n\tbrand = property(get_brand, set_brand)\n\tmax_speed = property(get_max_speed, set_max_speed)\n\n\ncar = Car('QQ', 120)\nprint(car)\n# ValueError\n# car.max_speed = -100\ncar.max_speed = 320\ncar.brand = \"Benz\"\nprint(car)\nprint(Car.brand)\nprint(Car.brand.fget)\nprint(Car.brand.fset)\n"
  },
  {
    "path": "Day01-15/Day09/clock.py",
    "content": "from time import time, localtime, sleep\n\n\nclass Clock(object):\n    \"\"\"数字时钟\"\"\"\n\n    def __init__(self, hour=0, minute=0, second=0):\n        self._hour = hour\n        self._minute = minute\n        self._second = second\n\n    @classmethod\n    def now(cls):\n        ctime = localtime(time())\n        return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)\n\n    def run(self):\n        \"\"\"走字\"\"\"\n        self._second += 1\n        if self._second == 60:\n            self._second = 0\n            self._minute += 1\n            if self._minute == 60:\n                self._minute = 0\n                self._hour += 1\n                if self._hour == 24:\n                    self._hour = 0\n\n    def show(self):\n        \"\"\"显示时间\"\"\"\n        return '%02d:%02d:%02d' % \\\n               (self._hour, self._minute, self._second)\n\n\ndef main():\n    clock = Clock.now()\n    while True:\n        print(clock.show())\n        sleep(1)\n        clock.run()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day09/dependency.py",
    "content": "\"\"\"\n\n对象之间的依赖关系和运算符重载\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\n\nclass Car(object):\n\n\tdef __init__(self, brand, max_speed):\n\t\tself._brand = brand\n\t\tself._max_speed = max_speed\n\t\tself._current_speed = 0\n\n\t@property\n\tdef brand(self):\n\t\treturn self._brand\n\n\tdef accelerate(self, delta):\n\t\tself._current_speed += delta\n\t\tif self._current_speed > self._max_speed:\n\t\t\tself._current_speed = self._max_speed\n\n\tdef brake(self):\n\t\tself._current_speed = 0\n\n\tdef __str__(self):\n\t\treturn '%s当前时速%d' % (self._brand, self._current_speed)\n\n\nclass Student(object):\n\n\tdef __init__(self, name, age):\n\t\tself._name = name\n\t\tself._age = age\n\n\t@property\n\tdef name(self):\n\t\treturn self._name\n\n\t# 学生和车之间存在依赖关系 - 学生使用了汽车\n\tdef drive(self, car):\n\t\tprint('%s驾驶着%s欢快的行驶在去西天的路上' % (self._name, car._brand))\n\t\tcar.accelerate(30)\n\t\tprint(car)\n\t\tcar.accelerate(50)\n\t\tprint(car)\n\t\tcar.accelerate(50)\n\t\tprint(car)\n\n\tdef study(self, course_name):\n\t\tprint('%s正在学习%s.' % (self._name, course_name))\n\n\tdef watch_av(self):\n\t\tif self._age < 18:\n\t\t\tprint('%s只能观看《熊出没》.' % self._name)\n\t\telse:\n\t\t\tprint('%s正在观看岛国爱情动作片.' % self._name)\n\n\t# 重载大于(>)运算符\n\tdef __gt__(self, other):\n\t\treturn self._age > other._age\n\n\t# 重载小于(<)运算符\n\tdef __lt__(self, other):\n\t\treturn self._age < other._age\n\n\nif __name__ == '__main__':\n\tstu1 = Student('骆昊', 38)\n\tstu1.study('Python程序设计')\n\tstu1.watch_av()\n\tstu2 = Student('王大锤', 15)\n\tstu2.study('思想品德')\n\tstu2.watch_av()\n\tcar = Car('QQ', 120)\n\tstu2.drive(car)\n\tprint(stu1 > stu2)\n\tprint(stu1 < stu2)\n"
  },
  {
    "path": "Day01-15/Day09/diamond.py",
    "content": "\"\"\"\n\n多重继承\n\t- 菱形继承(钻石继承)\n\t- C3算法(替代DFS的算法)\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\n\nclass A(object):\n\n\tdef foo(self):\n\t\tprint('foo of A')\n\n\nclass B(A):\n\tpass\n\n\nclass C(A):\n\n\tdef foo(self):\n\t\tprint('foo fo C')\n\n\nclass D(B, C):\n\tpass\n\n\nclass E(D):\n\n\tdef foo(self):\n\t\tprint('foo in E')\n\t\tsuper().foo()\n\t\tsuper(B, self).foo()\n\t\tsuper(C, self).foo()\n\n\nif __name__ == '__main__':\n\td = D()\n\td.foo()\n\te = E()\n\te.foo()\n"
  },
  {
    "path": "Day01-15/Day09/employee.py",
    "content": "\"\"\"\n\n抽象类 / 方法重写 / 多态\n实现一个工资结算系统 公司有三种类型的员工\n\t- 部门经理固定月薪12000元/月\n\t- 程序员按本月工作小时数每小时100元\n\t- 销售员1500元/月的底薪加上本月销售额5%的提成\n输入员工的信息 输出每位员工的月薪信息\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\nfrom abc import ABCMeta, abstractmethod\n\n\nclass Employee(object, metaclass=ABCMeta):\n\n\tdef __init__(self, name):\n\t\tself._name = name\n\n\t@property\n\tdef name(self):\n\t\treturn self._name\n\n\t@abstractmethod\n\tdef get_salary(self):\n\t\tpass\n\n\nclass Manager(Employee):\n\n\t# 想一想: 如果不定义构造方法会怎么样\n\tdef __init__(self, name):\n\t\t# 想一想: 如果不调用父类构造器会怎么样\n\t\tsuper().__init__(name)\n\n\tdef get_salary(self):\n\t\treturn 12000\n\n\nclass Programmer(Employee):\n\n\tdef __init__(self, name):\n\t\tsuper().__init__(name)\n\n\tdef set_working_hour(self, working_hour):\n\t\tself._working_hour = working_hour\n\n\tdef get_salary(self):\n\t\treturn 100 * self._working_hour\n\n\nclass Salesman(Employee):\n\n\tdef __init__(self, name):\n\t\tsuper().__init__(name)\n\n\tdef set_sales(self, sales):\n\t\tself._sales = sales\n\n\tdef get_salary(self):\n\t\treturn 1500 + self._sales * 0.05\n\n\nif __name__ == '__main__':\n\temps = [Manager('武则天'), Programmer('狄仁杰'), Salesman('白元芳')]\n\tfor emp in emps:\n\t\tif isinstance(emp, Programmer):\n\t\t\tworking_hour = int(input('请输入%s本月工作时间: ' % emp.name))\n\t\t\temp.set_working_hour(working_hour)\n\t\telif isinstance(emp, Salesman):\n\t\t\tsales = float(input('请输入%s本月销售额: ' % emp.name))\n\t\t\temp.set_sales(sales)\n\t\tprint('%s本月月薪为: ￥%.2f元' % (emp.name, emp.get_salary()))\n"
  },
  {
    "path": "Day01-15/Day09/multi.py",
    "content": "\"\"\"\n\n多重继承\n\t- 通过多重继承可以给一个类的对象具备多方面的能力\n\t- 这样在设计类的时候可以避免设计太多层次的复杂的继承关系\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\n\nclass Father(object):\n\n\tdef __init__(self, name):\n\t\tself._name = name\n\n\tdef gamble(self):\n\t\tprint('%s在打麻将.' % self._name)\n\n\tdef eat(self):\n\t\tprint('%s在大吃大喝.' % self._name)\n\n\nclass Monk(object):\n\n\tdef __init__(self, name):\n\t\tself._name = name\n\n\tdef eat(self):\n\t\tprint('%s在吃斋.' % self._name)\n\n\tdef chant(self):\n\t\tprint('%s在念经.' % self._name)\n\n\nclass Musician(object):\n\n\tdef __init__(self, name):\n\t\tself._name = name\n\n\tdef eat(self):\n\t\tprint('%s在细嚼慢咽.' % self._name)\n\n\tdef play_piano(self):\n\t\tprint('%s在弹钢琴.' % self._name)\n\n\n# 试一试下面的代码看看有什么区别\n# class Son(Monk, Father, Musician):\n# class Son(Musician, Father, Monk):\n\n\nclass Son(Father, Monk, Musician):\n\n\tdef __init__(self, name):\n\t\tFather.__init__(self, name)\n\t\tMonk.__init__(self, name)\n\t\tMusician.__init__(self, name)\n\n\nson = Son('王大锤')\nson.gamble()\n# 调用继承自Father的eat方法\nson.eat()\nson.chant()\nson.play_piano()\n"
  },
  {
    "path": "Day01-15/Day09/pet.py",
    "content": "from abc import ABCMeta, abstractmethod\n\n\nclass Pet(object, metaclass=ABCMeta):\n\n    def __init__(self, nickname):\n        self._nickname = nickname\n\n    @abstractmethod\n    def make_voice(self):\n        pass\n\n\nclass Dog(Pet):\n\n    def make_voice(self):\n        print('%s: 汪汪汪...' % self._nickname)\n\n\nclass Cat(Pet):\n\n    def make_voice(self):\n        print('%s: 喵...喵...' % self._nickname)\n\n\ndef main():\n    pets = [Dog('旺财'), Cat('凯蒂'), Dog('大黄')]\n    for pet in pets:\n        pet.make_voice()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day09/rational.py",
    "content": "\"\"\"\n\n运算符重载 - 自定义分数类\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\nfrom math import gcd\n\n\nclass Rational(object):\n\n\tdef __init__(self, num, den=1):\n\t\tif den == 0:\n\t\t\traise ValueError('分母不能为0')\n\t\tself._num = num\n\t\tself._den = den\n\t\tself.normalize()\n\n\tdef simplify(self):\n\t\tx = abs(self._num)\n\t\ty = abs(self._den)\n\t\tfactor = gcd(x, y)\n\t\tif factor > 1:\n\t\t\tself._num //= factor\n\t\t\tself._den //= factor\n\t\treturn self\n\n\tdef normalize(self):\n\t\tif self._den < 0:\n\t\t\tself._den = -self._den\n\t\t\tself._num = -self._num\n\t\treturn self\n\n\tdef __add__(self, other):\n\t\tnew_num = self._num * other._den + other._num * self._den\n\t\tnew_den = self._den * other._den\n\t\treturn Rational(new_num, new_den).simplify().normalize()\n\n\tdef __sub__(self, other):\n\t\tnew_num = self._num * other._den - other._num * self._den\n\t\tnew_den = self._den * other._den\n\t\treturn Rational(new_num, new_den).simplify().normalize()\n\n\tdef __mul__(self, other):\n\t\tnew_num = self._num * other._num\n\t\tnew_den = self._den * other._den\n\t\treturn Rational(new_num, new_den).simplify().normalize()\n\n\tdef __truediv__(self, other):\n\t\tnew_num = self._num * other._den\n\t\tnew_den = self._den * other._num\n\t\treturn Rational(new_num, new_den).simplify().normalize()\n\n\tdef __str__(self):\n\t\tif self._num == 0:\n\t\t\treturn '0'\n\t\telif self._den == 1:\n\t\t\treturn str(self._num)\n\t\telse:\n\t\t\treturn '(%d/%d)' % (self._num, self._den)\n\n\nif __name__ == '__main__':\n\tr1 = Rational(2, 3)\n\tprint(r1)\n\tr2 = Rational(6, -8)\n\tprint(r2)\n\tprint(r2.simplify())\n\tprint('%s + %s = %s' % (r1, r2, r1 + r2))\n\tprint('%s - %s = %s' % (r1, r2, r1 - r2))\n\tprint('%s * %s = %s' % (r1, r2, r1 * r2))\n\tprint('%s / %s = %s' % (r1, r2, r1 / r2))\n"
  },
  {
    "path": "Day01-15/Day09/res/uml-example.gliffy",
    "content": "{\"contentType\":\"application/gliffy+json\",\"version\":\"1.1\",\"metadata\":{\"title\":\"untitled\",\"revision\":0,\"exportBorder\":false},\"embeddedResources\":{\"index\":0,\"resources\":[]},\"stage\":{\"objects\":[{\"x\":211,\"y\":179.5,\"rotation\":0,\"id\":79,\"uid\":\"com.gliffy.shape.basic.basic_v1.default.text\",\"width\":60,\"height\":28,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":71,\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"middle\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">继承关系</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null,\"linkMap\":[]},{\"x\":702,\"y\":249,\"rotation\":0,\"id\":78,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.generalization\",\"width\":100,\"height\":100,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":70,\"graphic\":{\"type\":\"Line\",\"Line\":{\"strokeWidth\":1,\"strokeColor\":\"#000000\",\"fillColor\":\"none\",\"dashStyle\":null,\"startArrow\":0,\"endArrow\":4,\"startArrowRotation\":\"auto\",\"endArrowRotation\":\"auto\",\"ortho\":true,\"interpolationType\":\"linear\",\"cornerRadius\":null,\"controlPath\":[[82,-4],[50,-4],[50,-69.32485578727801],[18,-69.32485578727801]],\"lockSegments\":{}}},\"children\":null,\"constraints\":{\"constraints\":[],\"startConstraint\":{\"type\":\"StartPositionConstraint\",\"StartPositionConstraint\":{\"nodeId\":70,\"px\":0,\"py\":0.5}},\"endConstraint\":{\"type\":\"EndPositionConstraint\",\"EndPositionConstraint\":{\"nodeId\":32,\"px\":0.9999999999999998,\"py\":0.7071067811865475}}},\"linkMap\":[]},{\"x\":615,\"y\":70,\"rotation\":0,\"id\":77,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.generalization\",\"width\":100,\"height\":100,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":69,\"graphic\":{\"type\":\"Line\",\"Line\":{\"strokeWidth\":1,\"strokeColor\":\"#000000\",\"fillColor\":\"none\",\"dashStyle\":null,\"startArrow\":0,\"endArrow\":4,\"startArrowRotation\":\"auto\",\"endArrowRotation\":\"auto\",\"ortho\":true,\"interpolationType\":\"linear\",\"cornerRadius\":null,\"controlPath\":[[169,6.75],[137,6.75],[137,70.32485578727798],[105,70.32485578727798]],\"lockSegments\":{}}},\"children\":null,\"constraints\":{\"constraints\":[],\"startConstraint\":{\"type\":\"StartPositionConstraint\",\"StartPositionConstraint\":{\"nodeId\":63,\"px\":0,\"py\":0.5}},\"endConstraint\":{\"type\":\"EndPositionConstraint\",\"EndPositionConstraint\":{\"nodeId\":32,\"px\":1,\"py\":0.29289321881345237}}},\"linkMap\":[]},{\"x\":228,\"y\":356,\"rotation\":0,\"id\":55,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.association\",\"width\":100,\"height\":100,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":0,\"graphic\":{\"type\":\"Line\",\"Line\":{\"strokeWidth\":1,\"strokeColor\":\"#000000\",\"fillColor\":\"none\",\"dashStyle\":null,\"startArrow\":0,\"endArrow\":0,\"startArrowRotation\":\"auto\",\"endArrowRotation\":\"auto\",\"ortho\":true,\"interpolationType\":\"linear\",\"cornerRadius\":null,\"controlPath\":[[202,-46],[202,-22.666666666666686],[202,0.6666666666666856],[202,24]],\"lockSegments\":{}}},\"children\":null,\"constraints\":{\"constraints\":[],\"startConstraint\":{\"type\":\"StartPositionConstraint\",\"StartPositionConstraint\":{\"nodeId\":24,\"px\":0.5,\"py\":1}},\"endConstraint\":{\"type\":\"EndPositionConstraint\",\"EndPositionConstraint\":{\"nodeId\":48,\"px\":0.5,\"py\":0}}},\"linkMap\":[]},{\"x\":667,\"y\":225,\"rotation\":0,\"id\":47,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.aggregation\",\"width\":100,\"height\":100,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":40,\"graphic\":{\"type\":\"Line\",\"Line\":{\"strokeWidth\":1,\"strokeColor\":\"#000000\",\"fillColor\":\"none\",\"dashStyle\":null,\"startArrow\":0,\"endArrow\":5,\"startArrowRotation\":\"auto\",\"endArrowRotation\":\"auto\",\"ortho\":true,\"interpolationType\":\"linear\",\"cornerRadius\":null,\"controlPath\":[[-17,-17.5],[-17,8.333333333333343],[-17,34.166666666666686],[-17,60]],\"lockSegments\":{}}},\"children\":null,\"constraints\":{\"constraints\":[],\"startConstraint\":{\"type\":\"StartPositionConstraint\",\"StartPositionConstraint\":{\"nodeId\":32,\"px\":0.5,\"py\":1}},\"endConstraint\":{\"type\":\"EndPositionConstraint\",\"EndPositionConstraint\":{\"nodeId\":56,\"px\":0.5,\"py\":0}}},\"linkMap\":[]},{\"x\":403,\"y\":390,\"rotation\":0,\"id\":39,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.dependency\",\"width\":100,\"height\":100,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":39,\"graphic\":{\"type\":\"Line\",\"Line\":{\"strokeWidth\":1,\"strokeColor\":\"#000000\",\"fillColor\":\"none\",\"dashStyle\":\"8.0,2.0\",\"startArrow\":0,\"endArrow\":6,\"startArrowRotation\":\"auto\",\"endArrowRotation\":\"auto\",\"ortho\":true,\"interpolationType\":\"linear\",\"cornerRadius\":null,\"controlPath\":[[97,-125],[137,-125],[137,-230],[177,-230]],\"lockSegments\":{}}},\"children\":null,\"constraints\":{\"constraints\":[],\"startConstraint\":{\"type\":\"StartPositionConstraint\",\"StartPositionConstraint\":{\"nodeId\":24,\"px\":1,\"py\":0.5}},\"endConstraint\":{\"type\":\"EndPositionConstraint\",\"EndPositionConstraint\":{\"nodeId\":32,\"px\":0,\"py\":0.5}}},\"linkMap\":[]},{\"x\":289,\"y\":219,\"rotation\":0,\"id\":31,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.generalization\",\"width\":100,\"height\":100,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":31,\"graphic\":{\"type\":\"Line\",\"Line\":{\"strokeWidth\":1,\"strokeColor\":\"#000000\",\"fillColor\":\"none\",\"dashStyle\":null,\"startArrow\":0,\"endArrow\":4,\"startArrowRotation\":\"auto\",\"endArrowRotation\":\"auto\",\"ortho\":true,\"interpolationType\":\"linear\",\"cornerRadius\":null,\"controlPath\":[[141,1],[141,-124],[51,-124]],\"lockSegments\":{}}},\"children\":null,\"constraints\":{\"constraints\":[],\"startConstraint\":{\"type\":\"StartPositionConstraint\",\"StartPositionConstraint\":{\"nodeId\":24,\"px\":0.5,\"py\":0}},\"endConstraint\":{\"type\":\"EndPositionConstraint\",\"EndPositionConstraint\":{\"nodeId\":0,\"px\":1,\"py\":0.5}}},\"linkMap\":[]},{\"x\":325,\"y\":185,\"rotation\":0,\"id\":22,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.generalization\",\"width\":100,\"height\":100,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":23,\"graphic\":{\"type\":\"Line\",\"Line\":{\"strokeWidth\":1,\"strokeColor\":\"#000000\",\"fillColor\":\"none\",\"dashStyle\":null,\"startArrow\":0,\"endArrow\":4,\"startArrowRotation\":\"auto\",\"endArrowRotation\":\"auto\",\"ortho\":true,\"interpolationType\":\"linear\",\"cornerRadius\":null,\"controlPath\":[[-55,35],[-55,11.666666666666657],[-55,-11.666666666666657],[-55,-35]],\"lockSegments\":{}}},\"children\":null,\"constraints\":{\"constraints\":[],\"startConstraint\":{\"type\":\"StartPositionConstraint\",\"StartPositionConstraint\":{\"nodeId\":14,\"px\":0.5,\"py\":0}},\"endConstraint\":{\"type\":\"EndPositionConstraint\",\"EndPositionConstraint\":{\"nodeId\":0,\"px\":0.5,\"py\":1}}},\"linkMap\":[]},{\"x\":98,\"y\":173,\"rotation\":0,\"id\":21,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.generalization\",\"width\":100,\"height\":100,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":22,\"graphic\":{\"type\":\"Line\",\"Line\":{\"strokeWidth\":1,\"strokeColor\":\"#000000\",\"fillColor\":\"none\",\"dashStyle\":null,\"startArrow\":0,\"endArrow\":4,\"startArrowRotation\":\"auto\",\"endArrowRotation\":\"auto\",\"ortho\":true,\"interpolationType\":\"linear\",\"cornerRadius\":null,\"controlPath\":[[12,47],[12,-78],[102,-78]],\"lockSegments\":{}}},\"children\":null,\"constraints\":{\"constraints\":[],\"startConstraint\":{\"type\":\"StartPositionConstraint\",\"StartPositionConstraint\":{\"nodeId\":7,\"px\":0.5,\"py\":0}},\"endConstraint\":{\"type\":\"EndPositionConstraint\",\"EndPositionConstraint\":{\"nodeId\":0,\"px\":0,\"py\":0.5}}},\"linkMap\":[]},{\"x\":200,\"y\":220,\"rotation\":0,\"id\":14,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":75,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":15,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":15,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":16,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Teacher</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":16,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":17,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":18,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">title</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":15,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":18,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":36,\"rotation\":0,\"id\":19,\"uid\":null,\"width\":140,\"height\":39,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":20,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">teach</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":14,\"magnitude\":1},{\"id\":15,\"magnitude\":-1},{\"id\":17,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":17,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":15,\"magnitude\":1},{\"id\":17,\"magnitude\":1},{\"id\":20,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":40,\"y\":220,\"rotation\":0,\"id\":7,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":75,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":8,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":8,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":9,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Student</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":9,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":10,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":11,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">grade</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":8,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":11,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":36,\"rotation\":0,\"id\":12,\"uid\":null,\"width\":140,\"height\":39,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":13,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">study</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":7,\"magnitude\":1},{\"id\":8,\"magnitude\":-1},{\"id\":10,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":10,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":8,\"magnitude\":1},{\"id\":10,\"magnitude\":1},{\"id\":13,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":200,\"y\":40,\"rotation\":0,\"id\":0,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":110,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":1,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":1,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":2,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Person</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":2,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":3,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":4,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">name\\n</span></p><p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">age</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":1,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":4,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":50,\"rotation\":0,\"id\":5,\"uid\":null,\"width\":140,\"height\":60,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":6,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">eat\\n</span></p><p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">play</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":0,\"magnitude\":1},{\"id\":1,\"magnitude\":-1},{\"id\":3,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":3,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":1,\"magnitude\":1},{\"id\":3,\"magnitude\":1},{\"id\":6,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":360,\"y\":220,\"rotation\":0,\"id\":24,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":90,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":24,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":25,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":26,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Driver</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":26,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":27,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":28,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">work_experience\\n</span></p><p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">license</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":25,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":28,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":50,\"rotation\":0,\"id\":29,\"uid\":null,\"width\":140,\"height\":40,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":30,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">drive</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":24,\"magnitude\":1},{\"id\":25,\"magnitude\":-1},{\"id\":27,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":27,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":25,\"magnitude\":1},{\"id\":27,\"magnitude\":1},{\"id\":30,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":580,\"y\":112.5,\"rotation\":0,\"id\":32,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":95,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":32,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":33,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":34,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Vehicle</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":34,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":35,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":36,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">brand\\n</span></p><p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">engine</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":33,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":36,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":50,\"rotation\":0,\"id\":37,\"uid\":null,\"width\":140,\"height\":45,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":38,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">accelerate\\n</span></p><p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">slow_down</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":32,\"magnitude\":1},{\"id\":33,\"magnitude\":-1},{\"id\":35,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":35,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":33,\"magnitude\":1},{\"id\":35,\"magnitude\":1},{\"id\":38,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":360,\"y\":380,\"rotation\":0,\"id\":48,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":75,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":41,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":49,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":50,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">License</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":50,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":51,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":52,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align: left;\\\"><span class=\\\"gliffy-placeholder-text\\\" style=\\\"font-family: Arial; font-size: 12px; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Attribute</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":49,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":52,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":36,\"rotation\":0,\"id\":53,\"uid\":null,\"width\":140,\"height\":39,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":54,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align: left;\\\"><span class=\\\"gliffy-placeholder-text\\\" style=\\\"font-family: Arial; font-size: 12px; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Method</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":48,\"magnitude\":1},{\"id\":49,\"magnitude\":-1},{\"id\":51,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":51,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":49,\"magnitude\":1},{\"id\":51,\"magnitude\":1},{\"id\":54,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":580,\"y\":285,\"rotation\":0,\"id\":56,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":75,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":48,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":57,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":58,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Engine</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":58,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":59,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":60,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">number</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":57,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":60,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":36,\"rotation\":0,\"id\":61,\"uid\":null,\"width\":140,\"height\":39,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":62,\"uid\":null,\"width\":140,\"height\":4,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\"></span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":56,\"magnitude\":1},{\"id\":57,\"magnitude\":-1},{\"id\":59,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":59,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":57,\"magnitude\":1},{\"id\":59,\"magnitude\":1},{\"id\":62,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":784,\"y\":41,\"rotation\":0,\"id\":63,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":71.5,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":55,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":64,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":65,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Car</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":65,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":66,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":67,\"uid\":null,\"width\":140,\"height\":32,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">seats\\n</span></p><p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">displacement</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":64,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":67,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":50,\"rotation\":0,\"id\":68,\"uid\":null,\"width\":140,\"height\":21.5,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":69,\"uid\":null,\"width\":140,\"height\":4,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\"></span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":63,\"magnitude\":1},{\"id\":64,\"magnitude\":-1},{\"id\":66,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":66,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":64,\"magnitude\":1},{\"id\":66,\"magnitude\":1},{\"id\":69,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":784,\"y\":207.5,\"rotation\":0,\"id\":70,\"uid\":\"com.gliffy.shape.uml.uml_v1.default.class\",\"width\":140,\"height\":75,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":62,\"graphic\":null,\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":71,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":72,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:center;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: bold; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">Truck</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":72,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":18,\"rotation\":0,\"id\":73,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":74,\"uid\":null,\"width\":140,\"height\":18,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">capacity</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":71,\"px\":0,\"py\":1}},{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":74,\"magnitude\":1}],\"growParent\":true,\"padding\":0}}]}},{\"x\":0,\"y\":36,\"rotation\":0,\"id\":75,\"uid\":null,\"width\":140,\"height\":39,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Shape\",\"Shape\":{\"tid\":\"com.gliffy.stencil.rectangle.basic_v1\",\"strokeWidth\":2,\"strokeColor\":\"#000000\",\"fillColor\":\"#FFFFFF\",\"gradient\":false,\"dropShadow\":true,\"state\":0,\"shadowX\":4,\"shadowY\":4,\"opacity\":1}},\"children\":[{\"x\":0,\"y\":0,\"rotation\":0,\"id\":76,\"uid\":null,\"width\":140,\"height\":4,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":\"auto\",\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"top\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\"></span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":false,\"heightInfo\":[{\"id\":70,\"magnitude\":1},{\"id\":71,\"magnitude\":-1},{\"id\":73,\"magnitude\":-1}],\"growParent\":false,\"padding\":0}},{\"type\":\"PositionConstraint\",\"PositionConstraint\":{\"nodeId\":73,\"px\":0,\"py\":1}}]}}],\"constraints\":{\"constraints\":[{\"type\":\"HeightConstraint\",\"HeightConstraint\":{\"isMin\":true,\"heightInfo\":[{\"id\":71,\"magnitude\":1},{\"id\":73,\"magnitude\":1},{\"id\":76,\"magnitude\":1}],\"growParent\":false,\"padding\":0}}]},\"linkMap\":[]},{\"x\":371,\"y\":346,\"rotation\":0,\"id\":81,\"uid\":\"com.gliffy.shape.basic.basic_v1.default.text\",\"width\":60,\"height\":14,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":72,\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"middle\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">关联关系</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null,\"linkMap\":[]},{\"x\":490,\"y\":186.5,\"rotation\":0,\"id\":82,\"uid\":\"com.gliffy.shape.basic.basic_v1.default.text\",\"width\":60,\"height\":14,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":73,\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"middle\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">依赖关系</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null,\"linkMap\":[]},{\"x\":591,\"y\":238,\"rotation\":0,\"id\":83,\"uid\":\"com.gliffy.shape.basic.basic_v1.default.text\",\"width\":60,\"height\":14,\"lockAspectRatio\":false,\"lockShape\":false,\"order\":74,\"graphic\":{\"type\":\"Text\",\"Text\":{\"tid\":null,\"valign\":\"middle\",\"overflow\":\"none\",\"vposition\":\"none\",\"hposition\":\"none\",\"html\":\"<p style=\\\"text-align:left;\\\"><span style=\\\"font-size: 12px; font-family: Arial; white-space: pre-wrap; font-weight: normal; text-decoration: none; line-height: 14px; color: rgb(0, 0, 0);\\\">聚合关系</span></p>\",\"paddingLeft\":2,\"paddingRight\":2,\"paddingBottom\":2,\"paddingTop\":2}},\"children\":null,\"linkMap\":[]}],\"background\":\"#FFFFFF\",\"width\":926,\"height\":455,\"maxWidth\":5000,\"maxHeight\":5000,\"nodeIndex\":84,\"autoFit\":true,\"exportBorder\":false,\"gridOn\":true,\"snapToGrid\":true,\"drawingGuidesOn\":true,\"pageBreaksOn\":false,\"printGridOn\":false,\"printPaper\":\"LETTER\",\"printShrinkToFit\":false,\"printPortrait\":true,\"shapeStyles\":{},\"lineStyles\":{},\"textStyles\":{},\"themeData\":null}}"
  },
  {
    "path": "Day01-15/Day09/shape.py",
    "content": "\"\"\"\n\n继承的应用\n\t- 抽象类\n\t- 抽象方法\n\t- 方法重写\n\t- 多态\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\nfrom abc import ABCMeta, abstractmethod\nfrom math import pi\n\n\nclass Shape(object, metaclass=ABCMeta):\n\n\t@abstractmethod\n\tdef perimeter(self):\n\t\tpass\n\n\t@abstractmethod\n\tdef area(self):\n\t\tpass\n\n\nclass Circle(Shape):\n\n\tdef __init__(self, radius):\n\t\tself._radius = radius\n\n\tdef perimeter(self):\n\t\treturn 2 * pi * self._radius\n\n\tdef area(self):\n\t\treturn pi * self._radius ** 2\n\n\tdef __str__(self):\n\t\treturn '我是一个圆'\n\n\nclass Rect(Shape):\n\n\tdef __init__(self, width, height):\n\t\tself._width = width\n\t\tself._height = height\n\n\tdef perimeter(self):\n\t\treturn 2 * (self._width + self._height)\n\n\tdef area(self):\n\t\treturn self._width * self._height\n\n\tdef __str__(self):\n\t\treturn '我是一个矩形'\n\n\nif __name__ == '__main__':\n\tshapes = [Circle(5), Circle(3.2), Rect(3.2, 6.3)]\n\tfor shape in shapes:\n\t\tprint(shape)\n\t\tprint('周长:', shape.perimeter())\n\t\tprint('面积:', shape.area())\n"
  },
  {
    "path": "Day01-15/Day09/triangle.py",
    "content": "\"\"\"\n\n实例方法和类方法的应用\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-12\n\n\"\"\"\n\nfrom math import sqrt\n\n\nclass Triangle(object):\n\n\tdef __init__(self, a, b, c):\n\t\tself._a = a\n\t\tself._b = b\n\t\tself._c = c\n\n\t# 静态方法\n\t@staticmethod\n\tdef is_valid(a, b, c):\n\t\treturn a + b > c and b + c > a and c + a > b\n\n\t# 实例方法\n\tdef perimeter(self):\n\t\treturn self._a + self._b + self._c\n\n\t# 实例方法\n\tdef area(self):\n\t\tp = self.perimeter() / 2\n\t\treturn sqrt(p * (p - self._a) * (p - self._b) * (p - self._c))\n\n\nif __name__ == '__main__':\n\t# 用字符串的split方法将字符串拆分成一个列表\n\t# 再通过map函数对列表中的每个字符串进行映射处理成小数\n\ta, b, c = map(float, input('请输入三条边: ').split())\n\t# 先判断给定长度的三条边能否构成三角形\n\t# 如果能才创建三角形对象\n\tif Triangle.is_valid(a, b, c):\n\t\ttri = Triangle(a, b, c)\n\t\tprint('周长:', tri.perimeter())\n\t\tprint('面积:', tri.area())\n\t\t# 如果传入对象作为方法参数也可以通过类调用实例方法\n\t\t# print('周长:', Triangle.perimeter(tri))\n\t\t# print('面积:', Triangle.area(tri))\n\t\t# 看看下面的代码就知道其实二者本质上是一致的\n\t\t# print(type(tri.perimeter))\n\t\t# print(type(Triangle.perimeter))\n\telse:\n\t\tprint('不能构成三角形.')\n"
  },
  {
    "path": "Day01-15/Day09/面向对象进阶.md",
    "content": "## 面向对象进阶\n\n在前面的章节我们已经了解了面向对象的入门知识，知道了如何定义类，如何创建对象以及如何给对象发消息。为了能够更好的使用面向对象编程思想进行程序开发，我们还需要对Python中的面向对象编程进行更为深入的了解。\n\n### @property装饰器\n\n之前我们讨论过Python中属性和方法访问权限的问题，虽然我们不建议将属性设置为私有的，但是如果直接将属性暴露给外界也是有问题的，比如我们没有办法检查赋给属性的值是否有效。我们之前的建议是将属性命名以单下划线开头，通过这种方式来暗示属性是受保护的，不建议外界直接访问，那么如果想访问属性可以通过属性的getter（访问器）和setter（修改器）方法进行对应的操作。如果要做到这点，就可以考虑使用@property包装器来包装getter和setter方法，使得对属性的访问既安全又方便，代码如下所示。\n\n```Python\nclass Person(object):\n\n    def __init__(self, name, age):\n        self._name = name\n        self._age = age\n\n    # 访问器 - getter方法\n    @property\n    def name(self):\n        return self._name\n\n    # 访问器 - getter方法\n    @property\n    def age(self):\n        return self._age\n\n    # 修改器 - setter方法\n    @age.setter\n    def age(self, age):\n        self._age = age\n\n    def play(self):\n        if self._age <= 16:\n            print('%s正在玩飞行棋.' % self._name)\n        else:\n            print('%s正在玩斗地主.' % self._name)\n\n\ndef main():\n    person = Person('王大锤', 12)\n    person.play()\n    person.age = 22\n    person.play()\n    # person.name = '白元芳'  # AttributeError: can't set attribute\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n### \\_\\_slots\\_\\_魔法\n\n我们讲到这里，不知道大家是否已经意识到，Python是一门[动态语言](https://zh.wikipedia.org/wiki/%E5%8A%A8%E6%80%81%E8%AF%AD%E8%A8%80)。通常，动态语言允许我们在程序运行时给对象绑定新的属性或方法，当然也可以对已经绑定的属性和方法进行解绑定。但是如果我们需要限定自定义类型的对象只能绑定某些属性，可以通过在类中定义\\_\\_slots\\_\\_变量来进行限定。需要注意的是\\_\\_slots\\_\\_的限定只对当前类的对象生效，对子类并不起任何作用。\n\n```Python\nclass Person(object):\n\n    # 限定Person对象只能绑定_name, _age和_gender属性\n    __slots__ = ('_name', '_age', '_gender')\n\n    def __init__(self, name, age):\n        self._name = name\n        self._age = age\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def age(self):\n        return self._age\n\n    @age.setter\n    def age(self, age):\n        self._age = age\n\n    def play(self):\n        if self._age <= 16:\n            print('%s正在玩飞行棋.' % self._name)\n        else:\n            print('%s正在玩斗地主.' % self._name)\n\n\ndef main():\n    person = Person('王大锤', 22)\n    person.play()\n    person._gender = '男'\n    # AttributeError: 'Person' object has no attribute '_is_gay'\n    # person._is_gay = True\n\n```\n\n### 静态方法和类方法\n\n之前，我们在类中定义的方法都是对象方法，也就是说这些方法都是发送给对象的消息。实际上，我们写在类中的方法并不需要都是对象方法，例如我们定义一个“三角形”类，通过传入三条边长来构造三角形，并提供计算周长和面积的方法，但是传入的三条边长未必能构造出三角形对象，因此我们可以先写一个方法来验证三条边长是否可以构成三角形，这个方法很显然就不是对象方法，因为在调用这个方法时三角形对象尚未创建出来（因为都不知道三条边能不能构成三角形），所以这个方法是属于三角形类而并不属于三角形对象的。我们可以使用静态方法来解决这类问题，代码如下所示。\n\n```Python\nfrom math import sqrt\n\n\nclass Triangle(object):\n\n    def __init__(self, a, b, c):\n        self._a = a\n        self._b = b\n        self._c = c\n\n    @staticmethod\n    def is_valid(a, b, c):\n        return a + b > c and b + c > a and a + c > b\n\n    def perimeter(self):\n        return self._a + self._b + self._c\n\n    def area(self):\n        half = self.perimeter() / 2\n        return sqrt(half * (half - self._a) *\n                    (half - self._b) * (half - self._c))\n\n\ndef main():\n    a, b, c = 3, 4, 5\n    # 静态方法和类方法都是通过给类发消息来调用的\n    if Triangle.is_valid(a, b, c):\n        t = Triangle(a, b, c)\n        print(t.perimeter())\n        # 也可以通过给类发消息来调用对象方法但是要传入接收消息的对象作为参数\n        # print(Triangle.perimeter(t))\n        print(t.area())\n        # print(Triangle.area(t))\n    else:\n        print('无法构成三角形.')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n和静态方法比较类似，Python还可以在类中定义类方法，类方法的第一个参数约定名为cls，它代表的是当前类相关的信息的对象（类本身也是一个对象，有的地方也称之为类的元数据对象），通过这个参数我们可以获取和类相关的信息并且可以创建出类的对象，代码如下所示。\n\n```Python\nfrom time import time, localtime, sleep\n\n\nclass Clock(object):\n    \"\"\"数字时钟\"\"\"\n\n    def __init__(self, hour=0, minute=0, second=0):\n        self._hour = hour\n        self._minute = minute\n        self._second = second\n\n    @classmethod\n    def now(cls):\n        ctime = localtime(time())\n        return cls(ctime.tm_hour, ctime.tm_min, ctime.tm_sec)\n\n    def run(self):\n        \"\"\"走字\"\"\"\n        self._second += 1\n        if self._second == 60:\n            self._second = 0\n            self._minute += 1\n            if self._minute == 60:\n                self._minute = 0\n                self._hour += 1\n                if self._hour == 24:\n                    self._hour = 0\n\n    def show(self):\n        \"\"\"显示时间\"\"\"\n        return '%02d:%02d:%02d' % \\\n               (self._hour, self._minute, self._second)\n\n\ndef main():\n    # 通过类方法创建对象并获取系统时间\n    clock = Clock.now()\n    while True:\n        print(clock.show())\n        sleep(1)\n        clock.run()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n### 类之间的关系\n\n简单的说，类和类之间的关系有三种：is-a、has-a和use-a关系。\n\n- is-a关系也叫继承或泛化，比如学生和人的关系、手机和电子产品的关系都属于继承关系。\n- has-a关系通常称之为关联，比如部门和员工的关系，汽车和引擎的关系都属于关联关系；关联关系如果是整体和部分的关联，那么我们称之为聚合关系；如果整体进一步负责了部分的生命周期（整体和部分是不可分割的，同时同在也同时消亡），那么这种就是最强的关联关系，我们称之为合成关系。\n- use-a关系通常称之为依赖，比如司机有一个驾驶的行为（方法），其中（的参数）使用到了汽车，那么司机和汽车的关系就是依赖关系。\n\n我们可以使用一种叫做[UML](https://zh.wikipedia.org/wiki/%E7%BB%9F%E4%B8%80%E5%BB%BA%E6%A8%A1%E8%AF%AD%E8%A8%80)（统一建模语言）的东西来进行面向对象建模，其中一项重要的工作就是把类和类之间的关系用标准化的图形符号描述出来。关于UML我们在这里不做详细的介绍，有兴趣的读者可以自行阅读[《UML面向对象设计基础》](https://e.jd.com/30392949.html)一书。\n\n![](./res/uml-components.png)\n\n![](./res/uml-example.png)\n\n利用类之间的这些关系，我们可以在已有类的基础上来完成某些操作，也可以在已有类的基础上创建新的类，这些都是实现代码复用的重要手段。复用现有的代码不仅可以减少开发的工作量，也有利于代码的管理和维护，这是我们在日常工作中都会使用到的技术手段。\n\n### 继承和多态\n\n刚才我们提到了，可以在已有类的基础上创建新类，这其中的一种做法就是让一个类从另一个类那里将属性和方法直接继承下来，从而减少重复代码的编写。提供继承信息的我们称之为父类，也叫超类或基类；得到继承信息的我们称之为子类，也叫派生类或衍生类。子类除了继承父类提供的属性和方法，还可以定义自己特有的属性和方法，所以子类比父类拥有的更多的能力，在实际开发中，我们经常会用子类对象去替换掉一个父类对象，这是面向对象编程中一个常见的行为，对应的原则称之为[里氏替换原则](https://zh.wikipedia.org/wiki/%E9%87%8C%E6%B0%8F%E6%9B%BF%E6%8D%A2%E5%8E%9F%E5%88%99)。下面我们先看一个继承的例子。\n\n```Python\nclass Person(object):\n    \"\"\"人\"\"\"\n\n    def __init__(self, name, age):\n        self._name = name\n        self._age = age\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def age(self):\n        return self._age\n\n    @age.setter\n    def age(self, age):\n        self._age = age\n\n    def play(self):\n        print('%s正在愉快的玩耍.' % self._name)\n\n    def watch_av(self):\n        if self._age >= 18:\n            print('%s正在观看爱情动作片.' % self._name)\n        else:\n            print('%s只能观看《熊出没》.' % self._name)\n\n\nclass Student(Person):\n    \"\"\"学生\"\"\"\n\n    def __init__(self, name, age, grade):\n        super().__init__(name, age)\n        self._grade = grade\n\n    @property\n    def grade(self):\n        return self._grade\n\n    @grade.setter\n    def grade(self, grade):\n        self._grade = grade\n\n    def study(self, course):\n        print('%s的%s正在学习%s.' % (self._grade, self._name, course))\n\n\nclass Teacher(Person):\n    \"\"\"老师\"\"\"\n\n    def __init__(self, name, age, title):\n        super().__init__(name, age)\n        self._title = title\n\n    @property\n    def title(self):\n        return self._title\n\n    @title.setter\n    def title(self, title):\n        self._title = title\n\n    def teach(self, course):\n        print('%s%s正在讲%s.' % (self._name, self._title, course))\n\n\ndef main():\n    stu = Student('王大锤', 15, '初三')\n    stu.study('数学')\n    stu.watch_av()\n    t = Teacher('骆昊', 38, '老叫兽')\n    t.teach('Python程序设计')\n    t.watch_av()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n子类在继承了父类的方法后，可以对父类已有的方法给出新的实现版本，这个动作称之为方法重写（override）。通过方法重写我们可以让父类的同一个行为在子类中拥有不同的实现版本，当我们调用这个经过子类重写的方法时，不同的子类对象会表现出不同的行为，这个就是多态（poly-morphism）。\n\n```Python\nfrom abc import ABCMeta, abstractmethod\n\n\nclass Pet(object, metaclass=ABCMeta):\n    \"\"\"宠物\"\"\"\n\n    def __init__(self, nickname):\n        self._nickname = nickname\n\n    @abstractmethod\n    def make_voice(self):\n        \"\"\"发出声音\"\"\"\n        pass\n\n\nclass Dog(Pet):\n    \"\"\"狗\"\"\"\n\n    def make_voice(self):\n        print('%s: 汪汪汪...' % self._nickname)\n\n\nclass Cat(Pet):\n    \"\"\"猫\"\"\"\n\n    def make_voice(self):\n        print('%s: 喵...喵...' % self._nickname)\n\n\ndef main():\n    pets = [Dog('旺财'), Cat('凯蒂'), Dog('大黄')]\n    for pet in pets:\n        pet.make_voice()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n在上面的代码中，我们将`Pet`类处理成了一个抽象类，所谓抽象类就是不能够创建对象的类，这种类的存在就是专门为了让其他类去继承它。Python从语法层面并没有像Java或C#那样提供对抽象类的支持，但是我们可以通过`abc`模块的`ABCMeta`元类和`abstractmethod`包装器来达到抽象类的效果，如果一个类中存在抽象方法那么这个类就不能够实例化（创建对象）。上面的代码中，`Dog`和`Cat`两个子类分别对`Pet`类中的`make_voice`抽象方法进行了重写并给出了不同的实现版本，当我们在`main`函数中调用该方法时，这个方法就表现出了多态行为（同样的方法做了不同的事情）。\n\n### 综合案例\n\n#### 案例1：奥特曼打小怪兽\n\n```Python\nfrom abc import ABCMeta, abstractmethod\nfrom random import randint, randrange\n\n\nclass Fighter(object, metaclass=ABCMeta):\n    \"\"\"战斗者\"\"\"\n\n    # 通过__slots__魔法限定对象可以绑定的成员变量\n    __slots__ = ('_name', '_hp')\n\n    def __init__(self, name, hp):\n        \"\"\"\n        初始化方法\n\n        :param name: 名字\n        :param hp: 生命值\n        \"\"\"\n        self._name = name\n        self._hp = hp\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def hp(self):\n        return self._hp\n\n    @hp.setter\n    def hp(self, hp):\n        self._hp = hp if hp >= 0 else 0\n\n    @property\n    def alive(self):\n        return self._hp > 0\n\n    @abstractmethod\n    def attack(self, other):\n        \"\"\"\n        攻击\n\n        :param other: 被攻击的对象\n        \"\"\"\n        pass\n\n\nclass Ultraman(Fighter):\n    \"\"\"奥特曼\"\"\"\n\n    __slots__ = ('_name', '_hp', '_mp')\n\n    def __init__(self, name, hp, mp):\n        \"\"\"\n        初始化方法\n\n        :param name: 名字\n        :param hp: 生命值\n        :param mp: 魔法值\n        \"\"\"\n        super().__init__(name, hp)\n        self._mp = mp\n\n    def attack(self, other):\n        other.hp -= randint(15, 25)\n\n    def huge_attack(self, other):\n        \"\"\"\n        究极必杀技(打掉对方至少50点或四分之三的血)\n\n        :param other: 被攻击的对象\n\n        :return: 使用成功返回True否则返回False\n        \"\"\"\n        if self._mp >= 50:\n            self._mp -= 50\n            injury = other.hp * 3 // 4\n            injury = injury if injury >= 50 else 50\n            other.hp -= injury\n            return True\n        else:\n            self.attack(other)\n            return False\n\n    def magic_attack(self, others):\n        \"\"\"\n        魔法攻击\n\n        :param others: 被攻击的群体\n\n        :return: 使用魔法成功返回True否则返回False\n        \"\"\"\n        if self._mp >= 20:\n            self._mp -= 20\n            for temp in others:\n                if temp.alive:\n                    temp.hp -= randint(10, 15)\n            return True\n        else:\n            return False\n\n    def resume(self):\n        \"\"\"恢复魔法值\"\"\"\n        incr_point = randint(1, 10)\n        self._mp += incr_point\n        return incr_point\n\n    def __str__(self):\n        return '~~~%s奥特曼~~~\\n' % self._name + \\\n            '生命值: %d\\n' % self._hp + \\\n            '魔法值: %d\\n' % self._mp\n\n\nclass Monster(Fighter):\n    \"\"\"小怪兽\"\"\"\n\n    __slots__ = ('_name', '_hp')\n\n    def attack(self, other):\n        other.hp -= randint(10, 20)\n\n    def __str__(self):\n        return '~~~%s小怪兽~~~\\n' % self._name + \\\n            '生命值: %d\\n' % self._hp\n\n\ndef is_any_alive(monsters):\n    \"\"\"判断有没有小怪兽是活着的\"\"\"\n    for monster in monsters:\n        if monster.alive > 0:\n            return True\n    return False\n\n\ndef select_alive_one(monsters):\n    \"\"\"选中一只活着的小怪兽\"\"\"\n    monsters_len = len(monsters)\n    while True:\n        index = randrange(monsters_len)\n        monster = monsters[index]\n        if monster.alive > 0:\n            return monster\n\n\ndef display_info(ultraman, monsters):\n    \"\"\"显示奥特曼和小怪兽的信息\"\"\"\n    print(ultraman)\n    for monster in monsters:\n        print(monster, end='')\n\n\ndef main():\n    u = Ultraman('骆昊', 1000, 120)\n    m1 = Monster('舒小玲', 250)\n    m2 = Monster('白元芳', 500)\n    m3 = Monster('王大锤', 750)\n    ms = [m1, m2, m3]\n    fight_round = 1\n    while u.alive and is_any_alive(ms):\n        print('========第%02d回合========' % fight_round)\n        m = select_alive_one(ms)  # 选中一只小怪兽\n        skill = randint(1, 10)   # 通过随机数选择使用哪种技能\n        if skill <= 6:  # 60%的概率使用普通攻击\n            print('%s使用普通攻击打了%s.' % (u.name, m.name))\n            u.attack(m)\n            print('%s的魔法值恢复了%d点.' % (u.name, u.resume()))\n        elif skill <= 9:  # 30%的概率使用魔法攻击(可能因魔法值不足而失败)\n            if u.magic_attack(ms):\n                print('%s使用了魔法攻击.' % u.name)\n            else:\n                print('%s使用魔法失败.' % u.name)\n        else:  # 10%的概率使用究极必杀技(如果魔法值不足则使用普通攻击)\n            if u.huge_attack(m):\n                print('%s使用究极必杀技虐了%s.' % (u.name, m.name))\n            else:\n                print('%s使用普通攻击打了%s.' % (u.name, m.name))\n                print('%s的魔法值恢复了%d点.' % (u.name, u.resume()))\n        if m.alive > 0:  # 如果选中的小怪兽没有死就回击奥特曼\n            print('%s回击了%s.' % (m.name, u.name))\n            m.attack(u)\n        display_info(u, ms)  # 每个回合结束后显示奥特曼和小怪兽的信息\n        fight_round += 1\n    print('\\n========战斗结束!========\\n')\n    if u.alive > 0:\n        print('%s奥特曼胜利!' % u.name)\n    else:\n        print('小怪兽胜利!')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n#### 案例2：扑克游戏\n\n```Python\nfrom random import randrange\n\n\nclass Card(object):\n    \"\"\"一张牌\"\"\"\n\n    def __init__(self, suite, face):\n        self._suite = suite\n        self._face = face\n\n    @property\n    def face(self):\n        return self._face\n\n    @property\n    def suite(self):\n        return self._suite\n\n    def __str__(self):\n        all_suites = ('♠', '♥', '♣', '♦')\n        if self._face == 1:\n            face_str = 'A'\n        elif self._face == 11:\n            face_str = 'J'\n        elif self._face == 12:\n            face_str = 'Q'\n        elif self._face == 13:\n            face_str = 'K'\n        else:\n            face_str = str(self._face)\n        return '%s%s' % (all_suites[self._suite], face_str)\n\n\nclass Poker(object):\n    \"\"\"一副牌\"\"\"\n\n    def __init__(self):\n        self._cards = []\n        self._current = 0\n        for suite in range(4):\n            for face in range(1, 14):\n                card = Card(suite, face)\n                self._cards.append(card)\n\n    @property\n    def cards(self):\n        return self._cards\n\n    def shuffle(self):\n        \"\"\"洗牌(随机乱序)\"\"\"\n        self._current = 0\n        cards_len = len(self._cards)\n        for index in range(cards_len):\n            pos = randrange(cards_len)\n            self._cards[index], self._cards[pos] = \\\n                self._cards[pos], self._cards[index]\n\n    @property\n    def next(self):\n        \"\"\"发牌\"\"\"\n        card = self._cards[self._current]\n        self._current += 1\n        return card\n\n    @property\n    def has_next(self):\n        \"\"\"还有没有牌\"\"\"\n        return self._current < len(self._cards)\n\n\nclass Player(object):\n    \"\"\"玩家\"\"\"\n\n    def __init__(self, name):\n        self._name = name\n        self._cards_on_hand = []\n\n    @property\n    def name(self):\n        return self._name\n\n    @property\n    def cards_on_hand(self):\n        return self._cards_on_hand\n\n    def get(self, card):\n        \"\"\"摸牌\"\"\"\n        self._cards_on_hand.append(card)\n\n    def arrange(self, card_key):\n        \"\"\"玩家整理手上的牌\"\"\"\n        self._cards_on_hand.sort(key=card_key)\n\n\n# 排序规则-先根据花色再根据点数排序\ndef get_key(card):\n    return (card.suite, card.face)\n\n\ndef main():\n    p = Poker()\n    p.shuffle()\n    players = [Player('东邪'), Player('西毒'), Player('南帝'), Player('北丐')]\n    for _ in range(13):\n        for player in players:\n            player.get(p.next)\n    for player in players:\n        print(player.name + ':', end=' ')\n        player.arrange(get_key)\n        for card in player.cards_on_hand:\n            print(card, end=' ')\n        print()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n>**说明**：大家可以自己尝试在上面代码的基础上写一个简单的扑克游戏，例如21点(Black Jack)，游戏的规则可以自己在网上找一找。\n\n#### 案例3：工资结算系统\n\n```Python\n\"\"\"\n\n某公司有三种类型的员工 分别是部门经理、程序员和销售员\n需要设计一个工资结算系统 根据提供的员工信息来计算月薪\n部门经理的月薪是每月固定15000元\n程序员的月薪按本月工作时间计算 每小时150元\n销售员的月薪是1200元的底薪加上销售额5%的提成\n\n\"\"\"\nfrom abc import ABCMeta, abstractmethod\n\n\nclass Employee(object, metaclass=ABCMeta):\n    \"\"\"员工\"\"\"\n\n    def __init__(self, name):\n        \"\"\"\n        初始化方法\n\n        :param name: 姓名\n        \"\"\"\n        self._name = name\n\n    @property\n    def name(self):\n        return self._name\n\n    @abstractmethod\n    def get_salary(self):\n        \"\"\"\n        获得月薪\n\n        :return: 月薪\n        \"\"\"\n        pass\n\n\nclass Manager(Employee):\n    \"\"\"部门经理\"\"\"\n\n    def get_salary(self):\n        return 15000.0\n\n\nclass Programmer(Employee):\n    \"\"\"程序员\"\"\"\n\n    def __init__(self, name, working_hour=0):\n        super().__init__(name)\n        self._working_hour = working_hour\n\n    @property\n    def working_hour(self):\n        return self._working_hour\n\n    @working_hour.setter\n    def working_hour(self, working_hour):\n        self._working_hour = working_hour if working_hour > 0 else 0\n\n    def get_salary(self):\n        return 150.0 * self._working_hour\n\n\nclass Salesman(Employee):\n    \"\"\"销售员\"\"\"\n\n    def __init__(self, name, sales=0):\n        super().__init__(name)\n        self._sales = sales\n\n    @property\n    def sales(self):\n        return self._sales\n\n    @sales.setter\n    def sales(self, sales):\n        self._sales = sales if sales > 0 else 0\n\n    def get_salary(self):\n        return 1200.0 + self._sales * 0.05\n\n\ndef main():\n    emps = [\n        Manager('刘备'), Programmer('诸葛亮'),\n        Manager('曹操'), Salesman('荀彧'),\n        Salesman('吕布'), Programmer('张辽'),\n        Programmer('赵云')\n    ]\n    for emp in emps:\n        if isinstance(emp, Programmer):\n            emp.working_hour = int(input('请输入%s本月工作时间: ' % emp.name))\n        elif isinstance(emp, Salesman):\n            emp.sales = float(input('请输入%s本月销售额: ' % emp.name))\n        # 同样是接收get_salary这个消息但是不同的员工表现出了不同的行为(多态)\n        print('%s本月工资为: ￥%s元' %\n              (emp.name, emp.get_salary()))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n"
  },
  {
    "path": "Day01-15/Day10/ball.py",
    "content": "from enum import Enum, unique\nfrom math import sqrt\nfrom random import randint\n\nimport pygame\n\n\n@unique\nclass Color(Enum):\n    \"\"\"颜色\"\"\"\n\n    RED = (255, 0, 0)\n    GREEN = (0, 255, 0)\n    BLUE = (0, 0, 255)\n    BLACK = (0, 0, 0)\n    WHITE = (255, 255, 255)\n    GRAY = (242, 242, 242)\n\n    @staticmethod\n    def random_color():\n        \"\"\"获得随机颜色\"\"\"\n        r = randint(0, 255)\n        g = randint(0, 255)\n        b = randint(0, 255)\n        return (r, g, b)\n\n\nclass Ball(object):\n    \"\"\"球\"\"\"\n\n    def __init__(self, x, y, radius, sx, sy, color=Color.RED):\n        \"\"\"初始化方法\"\"\"\n        self.x = x\n        self.y = y\n        self.radius = radius\n        self.sx = sx\n        self.sy = sy\n        self.color = color\n        self.alive = True\n\n    def move(self, screen):\n        \"\"\"移动\"\"\"\n        self.x += self.sx\n        self.y += self.sy\n        if self.x - self.radius <= 0 or self.x + self.radius >= screen.get_width():\n            self.sx = -self.sx\n        if self.y - self.radius <= 0 or self.y + self.radius >= screen.get_height():\n            self.sy = -self.sy\n\n    def eat(self, other):\n        \"\"\"吃其他球\"\"\"\n        if self.alive and other.alive and self != other:\n            dx, dy = self.x - other.x, self.y - other.y\n            distance = sqrt(dx ** 2 + dy ** 2)\n            if distance < self.radius + other.radius \\\n                    and self.radius > other.radius:\n                other.alive = False\n               \tself.radius = self.radius + int(other.radius * 0.146)\n\n    def draw(self, screen):\n        \"\"\"在窗口上绘制球\"\"\"\n        pygame.draw.circle(screen, self.color,\n                           (self.x, self.y), self.radius, 0)\n\n\ndef main():\n    # 定义用来装所有球的容器\n    balls = []\n    # 初始化导入的pygame中的模块\n    pygame.init()\n    # 初始化用于显示的窗口并设置窗口尺寸\n    screen = pygame.display.set_mode((800, 600))\n    print(screen.get_width())\n    print(screen.get_height())\n    # 设置当前窗口的标题\n    pygame.display.set_caption('大球吃小球')\n    # 定义变量来表示小球在屏幕上的位置\n    x, y = 50, 50\n    running = True\n    # 开启一个事件循环处理发生的事件\n    while running:\n        # 从消息队列中获取事件并对事件进行处理\n        for event in pygame.event.get():\n            if event.type == pygame.QUIT:\n                running = False\n            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:\n                x, y = event.pos\n                radius = randint(10, 100)\n                sx, sy = randint(-10, 10), randint(-10, 10)\n                color = Color.random_color()\n                ball = Ball(x, y, radius, sx, sy, color)\n                balls.append(ball)\n        screen.fill((255, 255, 255))\n        for ball in balls:\n            if ball.alive:\n                ball.draw(screen)\n            else:\n                balls.remove(ball)\n        pygame.display.flip()\n        # 每隔50毫秒就改变小球的位置再刷新窗口\n        pygame.time.delay(50)\n        for ball in balls:\n            ball.move(screen)\n            for other in balls:\n                ball.eat(other)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day10/gui1.py",
    "content": "\"\"\"\n\n使用tkinter创建GUI\n\t- 顶层窗口\n\t- 控件\n\t- 布局\n\t- 事件回调\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-14\n\n\"\"\"\n\nimport tkinter\nimport tkinter.messagebox\n\n\ndef main():\n\tflag = True\n\n\t# 修改标签上的文字\n\tdef change_label_text():\n\t\tnonlocal flag\n\t\tflag = not flag\n\t\tcolor, msg = ('red', 'Hello, world!')\\\n\t\t\tif flag else ('blue', 'Goodbye, world!')\n\t\tlabel.config(text=msg, fg=color)\n\n\t# 确认退出\n\tdef confirm_to_quit():\n\t\tif tkinter.messagebox.askokcancel('温馨提示', '确定要退出吗?'):\n\t\t\ttop.quit()\n\n\t# 创建顶层窗口\n\ttop = tkinter.Tk()\n\t# 设置窗口大小\n\ttop.geometry('240x160')\n\t# 设置窗口标题\n\ttop.title('小游戏')\n\t# 创建标签对象\n\tlabel = tkinter.Label(top, text='Hello, world!', font='Arial -32', fg='red')\n\tlabel.pack(expand=1)\n\t# 创建一个装按钮的容器\n\tpanel = tkinter.Frame(top)\n\t# 创建按钮对象\n\tbutton1 = tkinter.Button(panel, text='修改', command=change_label_text)\n\tbutton1.pack(side='left')\n\tbutton2 = tkinter.Button(panel, text='退出', command=confirm_to_quit)\n\tbutton2.pack(side='right')\n\tpanel.pack(side='bottom')\n\t# 开启主事件循环\n\ttkinter.mainloop()\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day10/gui2.py",
    "content": "\"\"\"\n\n使用tkinter创建GUI\n\t- 使用画布绘图\n\t- 处理鼠标事件\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-14\n\n\"\"\"\n\nimport tkinter\n\n\ndef mouse_evt_handler(evt=None):\n\trow = round((evt.y - 20) / 40)\n\tcol = round((evt.x - 20) / 40)\n\tpos_x = 40 * col\n\tpos_y = 40 * row\n\tcanvas.create_oval(pos_x, pos_y, 40 + pos_x, 40 + pos_y, fill='black')\n\n\ntop = tkinter.Tk()\n# 设置窗口尺寸\ntop.geometry('620x620')\n# 设置窗口标题\ntop.title('五子棋')\n# 设置窗口大小不可改变\ntop.resizable(False, False)\n# 设置窗口置顶\ntop.wm_attributes('-topmost', 1)\ncanvas = tkinter.Canvas(top, width=600, height=600, bd=0, highlightthickness=0)\ncanvas.bind('<Button-1>', mouse_evt_handler)\ncanvas.create_rectangle(0, 0, 600, 600, fill='yellow', outline='white')\nfor index in range(15):\n\tcanvas.create_line(20, 20 + 40 * index, 580, 20 + 40 * index, fill='black')\n\tcanvas.create_line(20 + 40 * index, 20, 20 + 40 * index, 580, fill='black')\ncanvas.create_rectangle(15, 15, 585, 585, outline='black', width=4)\ncanvas.pack()\ntkinter.mainloop()\n\n# 请思考如何用面向对象的编程思想对上面的代码进行封装\n"
  },
  {
    "path": "Day01-15/Day10/gui3.py",
    "content": "\"\"\"\n\n使用tkinter创建GUI\n\t- 在窗口上制作动画\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-14\n\n\"\"\"\n\nimport tkinter\nimport time\n\n\n# 播放动画效果的函数\ndef play_animation():\n\tcanvas.move(oval, 2, 2)\n\tcanvas.update()\n\ttop.after(50, play_animation)\n\n\nx = 10\ny = 10\ntop = tkinter.Tk()\ntop.geometry('600x600')\ntop.title('动画效果')\ntop.resizable(False, False)\ntop.wm_attributes('-topmost', 1)\ncanvas = tkinter.Canvas(top, width=600, height=600, bd=0, highlightthickness=0)\ncanvas.create_rectangle(0, 0, 600, 600, fill='gray')\noval = canvas.create_oval(10, 10, 60, 60, fill='red')\ncanvas.pack()\ntop.update()\nplay_animation()\ntkinter.mainloop()\n\n# 请思考如何让小球碰到屏幕的边界就弹回\n# 请思考如何用面向对象的编程思想对上面的代码进行封装\n"
  },
  {
    "path": "Day01-15/Day10/turtle1.py",
    "content": "\"\"\"\n\n用turtle模块绘图\n这是一个非常有趣的模块 它模拟一只乌龟在窗口上爬行的方式来进行绘图\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-14\n\n\"\"\"\n\nimport turtle\n\nturtle.pensize(3)\nturtle.penup()\nturtle.goto(-180, 150)\nturtle.pencolor('red')\nturtle.fillcolor('yellow')\nturtle.pendown()\nturtle.begin_fill()\nfor _ in range(36):\n\tturtle.forward(200)\n\tturtle.right(170)\nturtle.end_fill()\nturtle.mainloop()\n"
  },
  {
    "path": "Day01-15/Day10/图形用户界面和游戏开发.md",
    "content": "## 图形用户界面和游戏开发\n\n### 基于tkinter模块的GUI\n\nGUI是图形用户界面的缩写，图形化的用户界面对使用过计算机的人来说应该都不陌生，在此也无需进行赘述。Python默认的GUI开发模块是tkinter（在Python 3以前的版本中名为Tkinter），从这个名字就可以看出它是基于Tk的，Tk是一个工具包，最初是为Tcl设计的，后来被移植到很多其他的脚本语言中，它提供了跨平台的GUI控件。当然Tk并不是最新和最好的选择，也没有功能特别强大的GUI控件，事实上，开发GUI应用并不是Python最擅长的工作，如果真的需要使用Python开发GUI应用，wxPython、PyQt、PyGTK等模块都是不错的选择。\n\n基本上使用tkinter来开发GUI应用需要以下5个步骤：\n\n1. 导入tkinter模块中我们需要的东西。\n2. 创建一个顶层窗口对象并用它来承载整个GUI应用。\n3. 在顶层窗口对象上添加GUI组件。\n4. 通过代码将这些GUI组件的功能组织起来。\n5. 进入主事件循环(main loop)。\n\n下面的代码演示了如何使用tkinter做一个简单的GUI应用。\n\n```Python\nimport tkinter\nimport tkinter.messagebox\n\n\ndef main():\n\tflag = True\n\n\t# 修改标签上的文字\n\tdef change_label_text():\n\t\tnonlocal flag\n\t\tflag = not flag\n\t\tcolor, msg = ('red', 'Hello, world!')\\\n\t\t\tif flag else ('blue', 'Goodbye, world!')\n\t\tlabel.config(text=msg, fg=color)\n\n\t# 确认退出\n\tdef confirm_to_quit():\n\t\tif tkinter.messagebox.askokcancel('温馨提示', '确定要退出吗?'):\n\t\t\ttop.quit()\n\n\t# 创建顶层窗口\n\ttop = tkinter.Tk()\n\t# 设置窗口大小\n\ttop.geometry('240x160')\n\t# 设置窗口标题\n\ttop.title('小游戏')\n\t# 创建标签对象并添加到顶层窗口\n\tlabel = tkinter.Label(top, text='Hello, world!', font='Arial -32', fg='red')\n\tlabel.pack(expand=1)\n\t# 创建一个装按钮的容器\n\tpanel = tkinter.Frame(top)\n\t# 创建按钮对象 指定添加到哪个容器中 通过command参数绑定事件回调函数\n\tbutton1 = tkinter.Button(panel, text='修改', command=change_label_text)\n\tbutton1.pack(side='left')\n\tbutton2 = tkinter.Button(panel, text='退出', command=confirm_to_quit)\n\tbutton2.pack(side='right')\n\tpanel.pack(side='bottom')\n\t# 开启主事件循环\n\ttkinter.mainloop()\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n需要说明的是，GUI应用通常是事件驱动式的，之所以要进入主事件循环就是要监听鼠标、键盘等各种事件的发生并执行对应的代码对事件进行处理，因为事件会持续的发生，所以需要这样的一个循环一直运行着等待下一个事件的发生。另一方面，Tk为控件的摆放提供了三种布局管理器，通过布局管理器可以对控件进行定位，这三种布局管理器分别是：Placer（开发者提供控件的大小和摆放位置）、Packer（自动将控件填充到合适的位置）和Grid（基于网格坐标来摆放控件），此处不进行赘述。\n\n### 使用Pygame进行游戏开发\n\nPygame是一个开源的Python模块，专门用于多媒体应用（如电子游戏）的开发，其中包含对图像、声音、视频、事件、碰撞等的支持。Pygame建立在[SDL](https://zh.wikipedia.org/wiki/SDL)的基础上，SDL是一套跨平台的多媒体开发库，用C语言实现，被广泛的应用于游戏、模拟器、播放器等的开发。而Pygame让游戏开发者不再被底层语言束缚，可以更多的关注游戏的功能和逻辑。\n\n下面我们来完成一个简单的小游戏，游戏的名字叫“大球吃小球”，当然完成这个游戏并不是重点，学会使用Pygame也不是重点，最重要的我们要在这个过程中体会如何使用前面讲解的面向对象程序设计，学会用这种编程思想去解决现实中的问题。\n\n#### 制作游戏窗口\n\n```Python\nimport pygame\n\n\ndef main():\n\t# 初始化导入的pygame中的模块\n    pygame.init()\n    # 初始化用于显示的窗口并设置窗口尺寸\n    screen = pygame.display.set_mode((800, 600))\n    # 设置当前窗口的标题\n    pygame.display.set_caption('大球吃小球')\n    running = True\n    # 开启一个事件循环处理发生的事件\n    while running:\n    \t# 从消息队列中获取事件并对事件进行处理\n        for event in pygame.event.get():\n            if event.type == pygame.QUIT:\n                running = False\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n#### 在窗口中绘图\n\n可以通过pygame中draw模块的函数在窗口上绘图，可以绘制的图形包括：线条、矩形、多边形、圆、椭圆、圆弧等。需要说明的是，屏幕坐标系是将屏幕左上角设置为坐标原点`(0, 0)`，向右是x轴的正向，向下是y轴的正向，在表示位置或者设置尺寸的时候，我们默认的单位都是[像素](https://zh.wikipedia.org/wiki/%E5%83%8F%E7%B4%A0)。所谓像素就是屏幕上的一个点，你可以用浏览图片的软件试着将一张图片放大若干倍，就可以看到这些点。pygame中表示颜色用的是色光[三原色](https://zh.wikipedia.org/wiki/%E5%8E%9F%E8%89%B2)表示法，即通过一个元组或列表来指定颜色的RGB值，每个值都在0~255之间，因为是每种原色都用一个8位（bit）的值来表示，三种颜色相当于一共由24位构成，这也就是常说的“24位颜色表示法”。\n\n```Python\nimport pygame\n\n\ndef main():\n\t# 初始化导入的pygame中的模块\n    pygame.init()\n    # 初始化用于显示的窗口并设置窗口尺寸\n    screen = pygame.display.set_mode((800, 600))\n    # 设置当前窗口的标题\n    pygame.display.set_caption('大球吃小球')\n    # 设置窗口的背景色(颜色是由红绿蓝三原色构成的元组)\n    screen.fill((242, 242, 242))\n    # 绘制一个圆(参数分别是: 屏幕, 颜色, 圆心位置, 半径, 0表示填充圆)\n    pygame.draw.circle(screen, (255, 0, 0,), (100, 100), 30, 0)\n    # 刷新当前窗口(渲染窗口将绘制的图像呈现出来)\n    pygame.display.flip()\n    running = True\n    # 开启一个事件循环处理发生的事件\n    while running:\n    \t# 从消息队列中获取事件并对事件进行处理\n        for event in pygame.event.get():\n            if event.type == pygame.QUIT:\n                running = False\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n####加载图像\n\n如果需要直接加载图像到窗口上，可以使用pygame中image模块的函数来加载图像，再通过之前获得的窗口对象的`blit`方法渲染图像，代码如下所示。\n\n```Python\nimport pygame\n\n\ndef main():\n    # 初始化导入的pygame中的模块\n    pygame.init()\n    # 初始化用于显示的窗口并设置窗口尺寸\n    screen = pygame.display.set_mode((800, 600))\n    # 设置当前窗口的标题\n    pygame.display.set_caption('大球吃小球')\n    # 设置窗口的背景色(颜色是由红绿蓝三原色构成的元组)\n    screen.fill((255, 255, 255))\n    # 通过指定的文件名加载图像\n    ball_image = pygame.image.load('./res/ball.png')\n    # 在窗口上渲染图像\n    screen.blit(ball_image, (50, 50))\n    # 刷新当前窗口(渲染窗口将绘制的图像呈现出来)\n    pygame.display.flip()\n    running = True\n    # 开启一个事件循环处理发生的事件\n    while running:\n        # 从消息队列中获取事件并对事件进行处理\n        for event in pygame.event.get():\n            if event.type == pygame.QUIT:\n                running = False\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n####实现动画效果 \n\n说到[动画](https://zh.wikipedia.org/wiki/%E5%8A%A8%E7%94%BB)这个词大家都不会陌生，事实上要实现动画效果，本身的原理也非常简单，就是将不连续的图片连续的播放，只要每秒钟达到了一定的帧数，那么就可以做出比较流畅的动画效果。如果要让上面代码中的小球动起来，可以将小球的位置用变量来表示，并在循环中修改小球的位置再刷新整个窗口即可。\n\n```Python\nimport pygame\n\n\ndef main():\n    # 初始化导入的pygame中的模块\n    pygame.init()\n    # 初始化用于显示的窗口并设置窗口尺寸\n    screen = pygame.display.set_mode((800, 600))\n    # 设置当前窗口的标题\n    pygame.display.set_caption('大球吃小球')\n    # 定义变量来表示小球在屏幕上的位置\n    x, y = 50, 50\n    running = True\n    # 开启一个事件循环处理发生的事件\n    while running:\n        # 从消息队列中获取事件并对事件进行处理\n        for event in pygame.event.get():\n            if event.type == pygame.QUIT:\n                running = False\n        screen.fill((255, 255, 255))\n        pygame.draw.circle(screen, (255, 0, 0,), (x, y), 30, 0)\n        pygame.display.flip()\n        # 每隔50毫秒就改变小球的位置再刷新窗口\n        pygame.time.delay(50)\n        x, y = x + 5, y + 5\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n#### 碰撞检测\n\n通常一个游戏中会有很多对象出现，而这些对象之间的“碰撞”在所难免，比如炮弹击中了飞机、箱子撞到了地面等。碰撞检测在绝大多数的游戏中都是一个必须得处理的至关重要的问题，pygame的sprite（动画精灵）模块就提供了对碰撞检测的支持，这里我们暂时不介绍sprite模块提供的功能，因为要检测两个小球有没有碰撞其实非常简单，只需要检查球心的距离有没有小于两个球的半径之和。为了制造出更多的小球，我们可以通过对鼠标事件的处理，在点击鼠标的位置创建颜色、大小和移动速度都随机的小球，当然要做到这一点，我们可以把之前学习到的面向对象的知识应用起来。\n\n```Python\nfrom enum import Enum, unique\nfrom math import sqrt\nfrom random import randint\n\nimport pygame\n\n\n@unique\nclass Color(Enum):\n    \"\"\"颜色\"\"\"\n\n    RED = (255, 0, 0)\n    GREEN = (0, 255, 0)\n    BLUE = (0, 0, 255)\n    BLACK = (0, 0, 0)\n    WHITE = (255, 255, 255)\n    GRAY = (242, 242, 242)\n\n    @staticmethod\n    def random_color():\n        \"\"\"获得随机颜色\"\"\"\n        r = randint(0, 255)\n        g = randint(0, 255)\n        b = randint(0, 255)\n        return (r, g, b)\n\n\nclass Ball(object):\n    \"\"\"球\"\"\"\n\n    def __init__(self, x, y, radius, sx, sy, color=Color.RED):\n        \"\"\"初始化方法\"\"\"\n        self.x = x\n        self.y = y\n        self.radius = radius\n        self.sx = sx\n        self.sy = sy\n        self.color = color\n        self.alive = True\n\n    def move(self, screen):\n        \"\"\"移动\"\"\"\n        self.x += self.sx\n        self.y += self.sy\n        if self.x - self.radius <= 0 or \\\n                self.x + self.radius >= screen.get_width():\n            self.sx = -self.sx\n        if self.y - self.radius <= 0 or \\\n                self.y + self.radius >= screen.get_height():\n            self.sy = -self.sy\n\n    def eat(self, other):\n        \"\"\"吃其他球\"\"\"\n        if self.alive and other.alive and self != other:\n            dx, dy = self.x - other.x, self.y - other.y\n            distance = sqrt(dx ** 2 + dy ** 2)\n            if distance < self.radius + other.radius \\\n                    and self.radius > other.radius:\n                other.alive = False\n               a self.radius = self.radius + int(other.radius * 0.146)\n\n    def draw(self, screen):\n        \"\"\"在窗口上绘制球\"\"\"\n        pygame.draw.circle(screen, self.color,\n                           (self.x, self.y), self.radius, 0)\n\n```\n\n#### 事件处理\n\n可以在事件循环中对鼠标事件进行处理，通过事件对象的`type`属性可以判定事件类型，再通过`pos`属性就可以获得鼠标点击的位置。如果要处理键盘事件也是在这个地方，做法与处理鼠标事件类似。\n\n```Python\ndef main():\n    # 定义用来装所有球的容器\n    balls = []\n    # 初始化导入的pygame中的模块\n    pygame.init()\n    # 初始化用于显示的窗口并设置窗口尺寸\n    screen = pygame.display.set_mode((800, 600))\n    # 设置当前窗口的标题\n    pygame.display.set_caption('大球吃小球')\n    running = True\n    # 开启一个事件循环处理发生的事件\n    while running:\n        # 从消息队列中获取事件并对事件进行处理\n        for event in pygame.event.get():\n            if event.type == pygame.QUIT:\n                running = False\n            # 处理鼠标事件的代码\n            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:\n                # 获得点击鼠标的位置\n                x, y = event.pos\n                radius = randint(10, 100)\n                sx, sy = randint(-10, 10), randint(-10, 10)\n                color = Color.random_color()\n                # 在点击鼠标的位置创建一个球(大小、速度和颜色随机)\n                ball = Ball(x, y, radius, sx, sy, color)\n                # 将球添加到列表容器中\n                balls.append(ball)\n        screen.fill((255, 255, 255))\n        # 取出容器中的球 如果没被吃掉就绘制 被吃掉了就移除\n        for ball in balls:\n            if ball.alive:\n                ball.draw(screen)\n            else:\n                balls.remove(ball)\n        pygame.display.flip()\n        # 每隔50毫秒就改变球的位置再刷新窗口\n        pygame.time.delay(50)\n        for ball in balls:\n            ball.move(screen)\n            # 检查球有没有吃到其他的球\n            for other in balls:\n                ball.eat(other)\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n上面的两段代码合在一起，我们就完成了“大球吃小球”的游戏（如下图所示），准确的说它算不上一个游戏，但是做一个小游戏的基本知识我们已经通过这个例子告诉大家了，有了这些知识已经可以开始你的小游戏开发之旅了。其实上面的代码中还有很多值得改进的地方，比如刷新窗口以及让球移动起来的代码并不应该放在事件循环中，等学习了多线程的知识后，用一个后台线程来处理这些事可能是更好的选择。如果希望获得更好的用户体验，我们还可以在游戏中加入背景音乐以及在球与球发生碰撞时播放音效，利用pygame的mixer和music模块，我们可以很容易的做到这一点，大家可以自行了解这方面的知识。事实上，想了解更多的关于pygame的知识，最好的教程是[pygame的官方网站](https://www.pygame.org/news)，如果英语没毛病就可以赶紧去看看啦。 如果想开发[3D游戏](https://zh.wikipedia.org/wiki/3D%E6%B8%B8%E6%88%8F)，pygame就显得力不从心了，对3D游戏开发如果有兴趣的读者不妨看看[Panda3D](https://www.panda3d.org/)。\n\n\n\n"
  },
  {
    "path": "Day01-15/Day11/.py",
    "content": ""
  },
  {
    "path": "Day01-15/Day11/csv1.py",
    "content": "\"\"\"\n\n读取CSV文件\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nimport csv\n\nfilename = 'example.csv'\n\ntry:\n\twith open(filename) as f:\n\t\treader = csv.reader(f)\n\t\tdata = list(reader)\nexcept FileNotFoundError:\n\tprint('无法打开文件:', filename)\nelse:\n\tfor item in data:\n\t\tprint('%-30s%-20s%-10s' % (item[0], item[1], item[2]))\n"
  },
  {
    "path": "Day01-15/Day11/csv2.py",
    "content": "\"\"\"\n\n写入CSV文件\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nimport csv\n\n\nclass Teacher(object):\n\n\tdef __init__(self, name, age, title):\n\t\tself.__name = name\n\t\tself.__age = age\n\t\tself.__title = title\n\t\tself.__index = -1\n\n\t@property\n\tdef name(self):\n\t\treturn self.__name\n\n\t@property\n\tdef age(self):\n\t\treturn self.__age\n\n\t@property\n\tdef title(self):\n\t\treturn self.__title\n\n\nfilename = 'teacher.csv'\nteachers = [Teacher('骆昊', 38, '叫兽'), Teacher('狄仁杰', 25, '砖家')]\n\ntry:\n\twith open(filename, 'w') as f:\n\t\twriter = csv.writer(f)\n\t\tfor teacher in teachers:\n\t\t\twriter.writerow([teacher.name, teacher.age, teacher.title])\nexcept BaseException as e:\n\tprint('无法写入文件:', filename)\nelse:\n\tprint('保存数据完成!')\n"
  },
  {
    "path": "Day01-15/Day11/ex1.py",
    "content": "\"\"\"\n\n异常机制 - 处理程序在运行时可能发生的状态\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\ninput_again = True\nwhile input_again:\n\ttry:\n\t\ta = int(input('a = '))\n\t\tb = int(input('b = '))\n\t\tprint('%d / %d = %f' % (a, b, a / b))\n\t\tinput_again = False\n\texcept ValueError:\n\t\tprint('请输入整数')\n\texcept ZeroDivisionError:\n\t\tprint('除数不能为0')\n# 处理异常让代码不因异常而崩溃是一方面\n# 更重要的是可以通过对异常的处理让代码从异常中恢复过来\n"
  },
  {
    "path": "Day01-15/Day11/ex2.py",
    "content": "\"\"\"\n\n异常机制 - 处理程序在运行时可能发生的状态\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\ninput_again = True\nwhile input_again:\n\ttry:\n\t\ta = int(input('a = '))\n\t\tb = int(input('b = '))\n\t\tprint('%d / %d = %f' % (a, b, a / b))\n\t\tinput_again = False\n\texcept (ValueError, ZeroDivisionError) as msg:\n\t\tprint(msg)\n"
  },
  {
    "path": "Day01-15/Day11/ex3.py",
    "content": "\"\"\"\n\n异常机制 - 处理程序在运行时可能发生的状态\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nimport time\nimport sys\n\nfilename = input('请输入文件名: ')\ntry:\n\twith open(filename) as f:\n\t\tlines = f.readlines()\nexcept FileNotFoundError as msg:\n\tprint('无法打开文件:', filename)\n\tprint(msg)\nexcept UnicodeDecodeError as msg:\n\tprint('非文本文件无法解码')\n\tsys.exit()\nelse:\n\tfor line in lines:\n\t\tprint(line.rstrip())\n\t\ttime.sleep(0.5)\nfinally:\n\t# 此处最适合做善后工作\n\tprint('不管发生什么我都会执行')\n"
  },
  {
    "path": "Day01-15/Day11/ex4.py",
    "content": "\"\"\"\n\n引发异常和异常栈\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\n\ndef f1():\n\traise AssertionError('发生异常')\n\n\ndef f2():\n\tf1()\n\n\ndef f3():\n\tf2()\n\n\nf3()\n"
  },
  {
    "path": "Day01-15/Day11/example.csv",
    "content": "4/5/2014 13:34,Apples,73\n4/5/2014 3:41,Cherries,85\n4/6/2014 12:46,Pears,14\n4/8/2014 8:59,Oranges,52\n4/10/2014 2:07,Apples,152\n4/10/2014 18:10,Bananas,23\n4/10/2014 2:40,Strawberries,98\n"
  },
  {
    "path": "Day01-15/Day11/file1.py",
    "content": "\"\"\"\n\n从文本文件中读取数据\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nimport time\n\n\ndef main():\n\t# 一次性读取整个文件内容\n\twith open('致橡树.txt', 'r', encoding='utf-8') as f:\n\t\tprint(f.read())\n\n\t# 通过for-in循环逐行读取\n\twith open('致橡树.txt', mode='r') as f:\n\t\tfor line in f:\n\t\t\tprint(line, end='')\n\t\t\ttime.sleep(0.5)\n\tprint()\n\n\t# 读取文件按行读取到列表中\n\twith open('致橡树.txt') as f:\n\t\tlines = f.readlines()\n\tprint(lines)\n\t\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day11/file2.py",
    "content": "\"\"\"\n\n读取圆周率文件判断其中是否包含自己的生日\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nbirth = input('请输入你的生日: ')\nwith open('pi_million_digits.txt') as f:\n\tlines = f.readlines()\n\tpi_string = ''\n\tfor line in lines:\n\t\tpi_string += line.strip()\n\tif birth in pi_string:\n\t\tprint('Bingo!!!')\n"
  },
  {
    "path": "Day01-15/Day11/file3.py",
    "content": "\"\"\"\n\n写文本文件\n将100以内的素数写入到文件中\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nfrom math import sqrt\n\n\ndef is_prime(n):\n\tfor factor in range(2, int(sqrt(n)) + 1):\n\t\tif n % factor == 0:\n\t\t\treturn False\n\treturn True\n\n\n# 试一试有什么不一样\n# with open('prime.txt', 'a') as f:\nwith open('prime.txt', 'w') as f:\n\tfor num in range(2, 100):\n\t\tif is_prime(num):\n\t\t\tf.write(str(num) + '\\n')\nprint('写入完成!')\n"
  },
  {
    "path": "Day01-15/Day11/file4.py",
    "content": "\"\"\"\n\n读写二进制文件\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nimport base64\n\nwith open('mm.jpg', 'rb') as f:\n\tdata = f.read()\n\t# print(type(data))\n\t# print(data)\n\tprint('字节数:', len(data))\n\t# 将图片处理成BASE-64编码\n\tprint(base64.b64encode(data))\n\nwith open('girl.jpg', 'wb') as f:\n\tf.write(data)\nprint('写入完成!')\n"
  },
  {
    "path": "Day01-15/Day11/json1.py",
    "content": "\"\"\"\n\n读取JSON数据\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nimport json\nimport csv2\n\njson_str = '{\"name\": \"骆昊\", \"age\": 38, \"title\": \"叫兽\"}'\nresult = json.loads(json_str)\nprint(result)\nprint(type(result))\nprint(result['name'])\nprint(result['age'])\n\n# 把转换得到的字典作为关键字参数传入Teacher的构造器\nteacher = csv2.Teacher(**result)\nprint(teacher)\nprint(teacher.name)\nprint(teacher.age)\nprint(teacher.title)\n\n# 请思考如何将下面JSON格式的天气数据转换成对象并获取我们需要的信息\n# 稍后我们会讲解如何通过网络API获取我们需要的JSON格式的数据\n\"\"\"\n\t{\n\t\t\"wendu\": \"29\",\n\t\t\"ganmao\": \"各项气象条件适宜，发生感冒机率较低。但请避免长期处于空调房间中，以防感冒。\",\n\t\t\"forecast\": [\n\t\t\t{\n\t\t\t\t\"fengxiang\": \"南风\",\n\t\t\t\t\"fengli\": \"3-4级\",\n\t\t\t\t\"high\": \"高温 32℃\",\n\t\t\t\t\"type\": \"多云\",\n\t\t\t\t\"low\": \"低温 17℃\",\n\t\t\t\t\"date\": \"16日星期二\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"fengxiang\": \"南风\",\n\t\t\t\t\"fengli\": \"微风级\",\n\t\t\t\t\"high\": \"高温 34℃\",\n\t\t\t\t\"type\": \"晴\",\n\t\t\t\t\"low\": \"低温 19℃\",\n\t\t\t\t\"date\": \"17日星期三\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"fengxiang\": \"南风\",\n\t\t\t\t\"fengli\": \"微风级\",\n\t\t\t\t\"high\": \"高温 35℃\",\n\t\t\t\t\"type\": \"晴\",\n\t\t\t\t\"low\": \"低温 22℃\",\n\t\t\t\t\"date\": \"18日星期四\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"fengxiang\": \"南风\",\n\t\t\t\t\"fengli\": \"微风级\",\n\t\t\t\t\"high\": \"高温 35℃\",\n\t\t\t\t\"type\": \"多云\",\n\t\t\t\t\"low\": \"低温 22℃\",\n\t\t\t\t\"date\": \"19日星期五\"\n\t\t\t},\n\t\t\t{\n\t\t\t\t\"fengxiang\": \"南风\",\n\t\t\t\t\"fengli\": \"3-4级\",\n\t\t\t\t\"high\": \"高温 34℃\",\n\t\t\t\t\"type\": \"晴\",\n\t\t\t\t\"low\": \"低温 21℃\",\n\t\t\t\t\"date\": \"20日星期六\"\n\t\t\t}\n\t\t],\n\t\t\"yesterday\": {\n\t\t\t\"fl\": \"微风\",\n\t\t\t\"fx\": \"南风\",\n\t\t\t\"high\": \"高温 28℃\",\n\t\t\t\"type\": \"晴\",\n\t\t\t\"low\": \"低温 15℃\",\n\t\t\t\"date\": \"15日星期一\"\n\t\t},\n\t\t\"aqi\": \"72\",\n\t\t\"city\": \"北京\"\n\t}\n\"\"\"\n"
  },
  {
    "path": "Day01-15/Day11/json2.py",
    "content": "\"\"\"\n\n写入JSON文件\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-13\n\n\"\"\"\n\nimport json\n\nteacher_dict = {'name': '白元芳', 'age': 25, 'title': '讲师'}\njson_str = json.dumps(teacher_dict)\nprint(json_str)\nprint(type(json_str))\nfruits_list = ['apple', 'orange', 'strawberry', 'banana', 'pitaya']\njson_str = json.dumps(fruits_list)\nprint(json_str)\nprint(type(json_str))\n"
  },
  {
    "path": "Day01-15/Day11/pi_million_digits.txt",
    "content": "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679\n  8214808651328230664709384460955058223172535940812848111745028410270193852110555964462294895493038196\n  4428810975665933446128475648233786783165271201909145648566923460348610454326648213393607260249141273\n  7245870066063155881748815209209628292540917153643678925903600113305305488204665213841469519415116094\n  3305727036575959195309218611738193261179310511854807446237996274956735188575272489122793818301194912\n  9833673362440656643086021394946395224737190702179860943702770539217176293176752384674818467669405132\n  0005681271452635608277857713427577896091736371787214684409012249534301465495853710507922796892589235\n  4201995611212902196086403441815981362977477130996051870721134999999837297804995105973173281609631859\n  5024459455346908302642522308253344685035261931188171010003137838752886587533208381420617177669147303\n  5982534904287554687311595628638823537875937519577818577805321712268066130019278766111959092164201989\n  3809525720106548586327886593615338182796823030195203530185296899577362259941389124972177528347913151\n  5574857242454150695950829533116861727855889075098381754637464939319255060400927701671139009848824012\n  8583616035637076601047101819429555961989467678374494482553797747268471040475346462080466842590694912\n  9331367702898915210475216205696602405803815019351125338243003558764024749647326391419927260426992279\n  6782354781636009341721641219924586315030286182974555706749838505494588586926995690927210797509302955\n  3211653449872027559602364806654991198818347977535663698074265425278625518184175746728909777727938000\n  8164706001614524919217321721477235014144197356854816136115735255213347574184946843852332390739414333\n  4547762416862518983569485562099219222184272550254256887671790494601653466804988627232791786085784383\n  8279679766814541009538837863609506800642251252051173929848960841284886269456042419652850222106611863\n  0674427862203919494504712371378696095636437191728746776465757396241389086583264599581339047802759009\n  9465764078951269468398352595709825822620522489407726719478268482601476990902640136394437455305068203\n  4962524517493996514314298091906592509372216964615157098583874105978859597729754989301617539284681382\n  6868386894277415599185592524595395943104997252468084598727364469584865383673622262609912460805124388\n  4390451244136549762780797715691435997700129616089441694868555848406353422072225828488648158456028506\n  0168427394522674676788952521385225499546667278239864565961163548862305774564980355936345681743241125\n  1507606947945109659609402522887971089314566913686722874894056010150330861792868092087476091782493858\n  9009714909675985261365549781893129784821682998948722658804857564014270477555132379641451523746234364\n  5428584447952658678210511413547357395231134271661021359695362314429524849371871101457654035902799344\n  0374200731057853906219838744780847848968332144571386875194350643021845319104848100537061468067491927\n  8191197939952061419663428754440643745123718192179998391015919561814675142691239748940907186494231961\n  5679452080951465502252316038819301420937621378559566389377870830390697920773467221825625996615014215\n  0306803844773454920260541466592520149744285073251866600213243408819071048633173464965145390579626856\n  1005508106658796998163574736384052571459102897064140110971206280439039759515677157700420337869936007\n  2305587631763594218731251471205329281918261861258673215791984148488291644706095752706957220917567116\n  7229109816909152801735067127485832228718352093539657251210835791513698820914442100675103346711031412\n  6711136990865851639831501970165151168517143765761835155650884909989859982387345528331635507647918535\n  8932261854896321329330898570642046752590709154814165498594616371802709819943099244889575712828905923\n  2332609729971208443357326548938239119325974636673058360414281388303203824903758985243744170291327656\n  1809377344403070746921120191302033038019762110110044929321516084244485963766983895228684783123552658\n  2131449576857262433441893039686426243410773226978028073189154411010446823252716201052652272111660396\n  6655730925471105578537634668206531098965269186205647693125705863566201855810072936065987648611791045\n  3348850346113657686753249441668039626579787718556084552965412665408530614344431858676975145661406800\n  7002378776591344017127494704205622305389945613140711270004078547332699390814546646458807972708266830\n  6343285878569830523580893306575740679545716377525420211495576158140025012622859413021647155097925923\n  0990796547376125517656751357517829666454779174501129961489030463994713296210734043751895735961458901\n  9389713111790429782856475032031986915140287080859904801094121472213179476477726224142548545403321571\n  8530614228813758504306332175182979866223717215916077166925474873898665494945011465406284336639379003\n  9769265672146385306736096571209180763832716641627488880078692560290228472104031721186082041900042296\n  6171196377921337575114959501566049631862947265473642523081770367515906735023507283540567040386743513\n  6222247715891504953098444893330963408780769325993978054193414473774418426312986080998886874132604721\n  5695162396586457302163159819319516735381297416772947867242292465436680098067692823828068996400482435\n  4037014163149658979409243237896907069779422362508221688957383798623001593776471651228935786015881617\n  5578297352334460428151262720373431465319777741603199066554187639792933441952154134189948544473456738\n  3162499341913181480927777103863877343177207545654532207770921201905166096280490926360197598828161332\n  3166636528619326686336062735676303544776280350450777235547105859548702790814356240145171806246436267\n  9456127531813407833033625423278394497538243720583531147711992606381334677687969597030983391307710987\n  0408591337464144282277263465947047458784778720192771528073176790770715721344473060570073349243693113\n  8350493163128404251219256517980694113528013147013047816437885185290928545201165839341965621349143415\n  9562586586557055269049652098580338507224264829397285847831630577775606888764462482468579260395352773\n  4803048029005876075825104747091643961362676044925627420420832085661190625454337213153595845068772460\n  2901618766795240616342522577195429162991930645537799140373404328752628889639958794757291746426357455\n  2540790914513571113694109119393251910760208252026187985318877058429725916778131496990090192116971737\n  2784768472686084900337702424291651300500516832336435038951702989392233451722013812806965011784408745\n  1960121228599371623130171144484640903890644954440061986907548516026327505298349187407866808818338510\n  2283345085048608250393021332197155184306354550076682829493041377655279397517546139539846833936383047\n  4611996653858153842056853386218672523340283087112328278921250771262946322956398989893582116745627010\n  2183564622013496715188190973038119800497340723961036854066431939509790190699639552453005450580685501\n  9567302292191393391856803449039820595510022635353619204199474553859381023439554495977837790237421617\n  2711172364343543947822181852862408514006660443325888569867054315470696574745855033232334210730154594\n  0516553790686627333799585115625784322988273723198987571415957811196358330059408730681216028764962867\n  4460477464915995054973742562690104903778198683593814657412680492564879855614537234786733039046883834\n  3634655379498641927056387293174872332083760112302991136793862708943879936201629515413371424892830722\n  0126901475466847653576164773794675200490757155527819653621323926406160136358155907422020203187277605\n  2772190055614842555187925303435139844253223415762336106425063904975008656271095359194658975141310348\n  2276930624743536325691607815478181152843667957061108615331504452127473924544945423682886061340841486\n  3776700961207151249140430272538607648236341433462351897576645216413767969031495019108575984423919862\n  9164219399490723623464684411739403265918404437805133389452574239950829659122850855582157250310712570\n  1266830240292952522011872676756220415420516184163484756516999811614101002996078386909291603028840026\n  9104140792886215078424516709087000699282120660418371806535567252532567532861291042487761825829765157\n  9598470356222629348600341587229805349896502262917487882027342092222453398562647669149055628425039127\n  5771028402799806636582548892648802545661017296702664076559042909945681506526530537182941270336931378\n  5178609040708667114965583434347693385781711386455873678123014587687126603489139095620099393610310291\n  6161528813843790990423174733639480457593149314052976347574811935670911013775172100803155902485309066\n  9203767192203322909433467685142214477379393751703443661991040337511173547191855046449026365512816228\n  8244625759163330391072253837421821408835086573917715096828874782656995995744906617583441375223970968\n  3408005355984917541738188399944697486762655165827658483588453142775687900290951702835297163445621296\n  4043523117600665101241200659755851276178583829204197484423608007193045761893234922927965019875187212\n  7267507981255470958904556357921221033346697499235630254947802490114195212382815309114079073860251522\n  7429958180724716259166854513331239480494707911915326734302824418604142636395480004480026704962482017\n  9289647669758318327131425170296923488962766844032326092752496035799646925650493681836090032380929345\n  9588970695365349406034021665443755890045632882250545255640564482465151875471196218443965825337543885\n  6909411303150952617937800297412076651479394259029896959469955657612186561967337862362561252163208628\n  6922210327488921865436480229678070576561514463204692790682120738837781423356282360896320806822246801\n  2248261177185896381409183903673672220888321513755600372798394004152970028783076670944474560134556417\n  2543709069793961225714298946715435784687886144458123145935719849225284716050492212424701412147805734\n  5510500801908699603302763478708108175450119307141223390866393833952942578690507643100638351983438934\n  1596131854347546495569781038293097164651438407007073604112373599843452251610507027056235266012764848\n  3084076118301305279320542746286540360367453286510570658748822569815793678976697422057505968344086973\n  5020141020672358502007245225632651341055924019027421624843914035998953539459094407046912091409387001\n  2645600162374288021092764579310657922955249887275846101264836999892256959688159205600101655256375678\n  5667227966198857827948488558343975187445455129656344348039664205579829368043522027709842942325330225\n  7634180703947699415979159453006975214829336655566156787364005366656416547321704390352132954352916941\n  4599041608753201868379370234888689479151071637852902345292440773659495630510074210871426134974595615\n  1384987137570471017879573104229690666702144986374645952808243694457897723300487647652413390759204340\n  1963403911473202338071509522201068256342747164602433544005152126693249341967397704159568375355516673\n  0273900749729736354964533288869844061196496162773449518273695588220757355176651589855190986665393549\n  4810688732068599075407923424023009259007017319603622547564789406475483466477604114632339056513433068\n  4495397907090302346046147096169688688501408347040546074295869913829668246818571031887906528703665083\n  2431974404771855678934823089431068287027228097362480939962706074726455399253994428081137369433887294\n  0630792615959954626246297070625948455690347119729964090894180595343932512362355081349490043642785271\n  3831591256898929519642728757394691427253436694153236100453730488198551706594121735246258954873016760\n  0298865925786628561249665523533829428785425340483083307016537228563559152534784459818313411290019992\n  0598135220511733658564078264849427644113763938669248031183644536985891754426473998822846218449008777\n  6977631279572267265556259628254276531830013407092233436577916012809317940171859859993384923549564005\n  7099558561134980252499066984233017350358044081168552653117099570899427328709258487894436460050410892\n  2669178352587078595129834417295351953788553457374260859029081765155780390594640873506123226112009373\n  1080485485263572282576820341605048466277504500312620080079980492548534694146977516493270950493463938\n  2432227188515974054702148289711177792376122578873477188196825462981268685817050740272550263329044976\n  2778944236216741191862694396506715157795867564823993917604260176338704549901761436412046921823707648\n  8783419689686118155815873606293860381017121585527266830082383404656475880405138080163363887421637140\n  6435495561868964112282140753302655100424104896783528588290243670904887118190909494533144218287661810\n  3100735477054981596807720094746961343609286148494178501718077930681085469000944589952794243981392135\n  0558642219648349151263901280383200109773868066287792397180146134324457264009737425700735921003154150\n  8936793008169980536520276007277496745840028362405346037263416554259027601834840306811381855105979705\n  6640075094260878857357960373245141467867036880988060971642584975951380693094494015154222219432913021\n  7391253835591503100333032511174915696917450271494331515588540392216409722910112903552181576282328318\n  2342548326111912800928252561902052630163911477247331485739107775874425387611746578671169414776421441\n  1112635835538713610110232679877564102468240322648346417663698066378576813492045302240819727856471983\n  9630878154322116691224641591177673225326433568614618654522268126887268445968442416107854016768142080\n  8850280054143613146230821025941737562389942075713627516745731891894562835257044133543758575342698699\n  4725470316566139919996826282472706413362221789239031760854289437339356188916512504244040089527198378\n  7386480584726895462438823437517885201439560057104811949884239060613695734231559079670346149143447886\n  3604103182350736502778590897578272731305048893989009923913503373250855982655867089242612429473670193\n  9077271307068691709264625484232407485503660801360466895118400936686095463250021458529309500009071510\n  5823626729326453738210493872499669933942468551648326113414611068026744663733437534076429402668297386\n  5220935701626384648528514903629320199199688285171839536691345222444708045923966028171565515656661113\n  5982311225062890585491450971575539002439315351909021071194573002438801766150352708626025378817975194\n  7806101371500448991721002220133501310601639154158957803711779277522597874289191791552241718958536168\n  0594741234193398420218745649256443462392531953135103311476394911995072858430658361935369329699289837\n  9149419394060857248639688369032655643642166442576079147108699843157337496488352927693282207629472823\n  8153740996154559879825989109371712621828302584811238901196822142945766758071865380650648702613389282\n  2994972574530332838963818439447707794022843598834100358385423897354243956475556840952248445541392394\n  1000162076936368467764130178196593799715574685419463348937484391297423914336593604100352343777065888\n  6778113949861647874714079326385873862473288964564359877466763847946650407411182565837887845485814896\n  2961273998413442726086061872455452360643153710112746809778704464094758280348769758948328241239292960\n  5829486191966709189580898332012103184303401284951162035342801441276172858302435598300320420245120728\n  7253558119584014918096925339507577840006746552603144616705082768277222353419110263416315714740612385\n  0425845988419907611287258059113935689601431668283176323567325417073420817332230462987992804908514094\n  7903688786878949305469557030726190095020764334933591060245450864536289354568629585313153371838682656\n  1786227363716975774183023986006591481616404944965011732131389574706208847480236537103115089842799275\n  4426853277974311395143574172219759799359685252285745263796289612691572357986620573408375766873884266\n  4059909935050008133754324546359675048442352848747014435454195762584735642161981340734685411176688311\n  8654489377697956651727966232671481033864391375186594673002443450054499539974237232871249483470604406\n  3471606325830649829795510109541836235030309453097335834462839476304775645015008507578949548931393944\n  8992161255255977014368589435858775263796255970816776438001254365023714127834679261019955852247172201\n  7772370041780841942394872540680155603599839054898572354674564239058585021671903139526294455439131663\n  1345308939062046784387785054239390524731362012947691874975191011472315289326772533918146607300089027\n  7689631148109022097245207591672970078505807171863810549679731001678708506942070922329080703832634534\n  5203802786099055690013413718236837099194951648960075504934126787643674638490206396401976668559233565\n  4639138363185745698147196210841080961884605456039038455343729141446513474940784884423772175154334260\n  3066988317683310011331086904219390310801437843341513709243530136776310849135161564226984750743032971\n  6746964066653152703532546711266752246055119958183196376370761799191920357958200759560530234626775794\n  3936307463056901080114942714100939136913810725813781357894005599500183542511841721360557275221035268\n  0373572652792241737360575112788721819084490061780138897107708229310027976659358387589093956881485602\n  6322439372656247277603789081445883785501970284377936240782505270487581647032458129087839523245323789\n  6029841669225489649715606981192186584926770403956481278102179913217416305810554598801300484562997651\n  1212415363745150056350701278159267142413421033015661653560247338078430286552572227530499988370153487\n  9300806260180962381516136690334111138653851091936739383522934588832255088706450753947395204396807906\n  7086806445096986548801682874343786126453815834280753061845485903798217994599681154419742536344399602\n  9025100158882721647450068207041937615845471231834600726293395505482395571372568402322682130124767945\n  2264482091023564775272308208106351889915269288910845557112660396503439789627825001611015323516051965\n  5904211844949907789992007329476905868577878720982901352956613978884860509786085957017731298155314951\n  6814671769597609942100361835591387778176984587581044662839988060061622984861693533738657877359833616\n  1338413385368421197893890018529569196780455448285848370117096721253533875862158231013310387766827211\n  5726949518179589754693992642197915523385766231676275475703546994148929041301863861194391962838870543\n  6777432242768091323654494853667680000010652624854730558615989991401707698385483188750142938908995068\n  5453076511680333732226517566220752695179144225280816517166776672793035485154204023817460892328391703\n  2754257508676551178593950027933895920576682789677644531840404185540104351348389531201326378369283580\n  8271937831265496174599705674507183320650345566440344904536275600112501843356073612227659492783937064\n  7842645676338818807565612168960504161139039063960162022153684941092605387688714837989559999112099164\n  6464411918568277004574243434021672276445589330127781586869525069499364610175685060167145354315814801\n  0545886056455013320375864548584032402987170934809105562116715468484778039447569798042631809917564228\n  0987399876697323769573701580806822904599212366168902596273043067931653114940176473769387351409336183\n  3216142802149763399189835484875625298752423873077559555955465196394401821840998412489826236737714672\n  2606163364329640633572810707887581640438148501884114318859882769449011932129682715888413386943468285\n  9006664080631407775772570563072940049294030242049841656547973670548558044586572022763784046682337985\n  2827105784319753541795011347273625774080213476826045022851579795797647467022840999561601569108903845\n  8245026792659420555039587922981852648007068376504183656209455543461351341525700659748819163413595567\n  1964965403218727160264859304903978748958906612725079482827693895352175362185079629778514618843271922\n  3223810158744450528665238022532843891375273845892384422535472653098171578447834215822327020690287232\n  3300538621634798850946954720047952311201504329322662827276321779088400878614802214753765781058197022\n  2630971749507212724847947816957296142365859578209083073323356034846531873029302665964501371837542889\n  7557971449924654038681799213893469244741985097334626793321072686870768062639919361965044099542167627\n  8409146698569257150743157407938053239252394775574415918458215625181921552337096074833292349210345146\n  2643744980559610330799414534778457469999212859999939961228161521931488876938802228108300198601654941\n  6542616968586788372609587745676182507275992950893180521872924610867639958916145855058397274209809097\n  8172932393010676638682404011130402470073508578287246271349463685318154696904669686939254725194139929\n  1465242385776255004748529547681479546700705034799958886769501612497228204030399546327883069597624936\n  1510102436555352230690612949388599015734661023712235478911292547696176005047974928060721268039226911\n  0277722610254414922157650450812067717357120271802429681062037765788371669091094180744878140490755178\n  2038565390991047759414132154328440625030180275716965082096427348414695726397884256008453121406593580\n  9041271135920041975985136254796160632288736181367373244506079244117639975974619383584574915988097667\n  4470930065463424234606342374746660804317012600520559284936959414340814685298150539471789004518357551\n  5412522359059068726487863575254191128887737176637486027660634960353679470269232297186832771739323619\n  2007774522126247518698334951510198642698878471719396649769070825217423365662725928440620430214113719\n  9227852699846988477023238238400556555178890876613601304770984386116870523105531491625172837327286760\n  0724817298763756981633541507460883866364069347043720668865127568826614973078865701568501691864748854\n  1679154596507234287730699853713904300266530783987763850323818215535597323530686043010675760838908627\n  0498418885951380910304235957824951439885901131858358406674723702971497850841458530857813391562707603\n  5639076394731145549583226694570249413983163433237897595568085683629725386791327505554252449194358912\n  8405045226953812179131914513500993846311774017971512283785460116035955402864405902496466930707769055\n  4810288502080858008781157738171917417760173307385547580060560143377432990127286772530431825197579167\n  9296996504146070664571258883469797964293162296552016879730003564630457930884032748077181155533090988\n  7025505207680463034608658165394876951960044084820659673794731680864156456505300498816164905788311543\n  4548505266006982309315777650037807046612647060214575057932709620478256152471459189652236083966456241\n  0519551052235723973951288181640597859142791481654263289200428160913693777372229998332708208296995573\n  7727375667615527113922588055201898876201141680054687365580633471603734291703907986396522961312801782\n  6797172898229360702880690877686605932527463784053976918480820410219447197138692560841624511239806201\n  1318454124478205011079876071715568315407886543904121087303240201068534194723047666672174986986854707\n  6781205124736792479193150856444775379853799732234456122785843296846647513336573692387201464723679427\n  8700425032555899268843495928761240075587569464137056251400117971331662071537154360068764773186755871\n  4878398908107429530941060596944315847753970094398839491443235366853920994687964506653398573888786614\n  7629443414010498889931600512076781035886116602029611936396821349607501116498327856353161451684576956\n  8710900299976984126326650234771672865737857908574664607722834154031144152941880478254387617707904300\n  0156698677679576090996693607559496515273634981189641304331166277471233881740603731743970540670310967\n  6765748695358789670031925866259410510533584384656023391796749267844763708474978333655579007384191473\n  1988627135259546251816043422537299628632674968240580602964211463864368642247248872834341704415734824\n  8183330164056695966886676956349141632842641497453334999948000266998758881593507357815195889900539512\n  0853510357261373640343675347141048360175464883004078464167452167371904831096767113443494819262681110\n  7399482506073949507350316901973185211955263563258433909982249862406703107683184466072912487475403161\n  7969941139738776589986855417031884778867592902607004321266617919223520938227878880988633599116081923\n  5355570464634911320859189796132791319756490976000139962344455350143464268604644958624769094347048293\n  2941404111465409239883444351591332010773944111840741076849810663472410482393582740194493566516108846\n  3125678529776973468430306146241803585293315973458303845541033701091676776374276210213701354854450926\n  3071901147318485749233181672072137279355679528443925481560913728128406333039373562420016045664557414\n  5881660521666087387480472433912129558777639069690370788285277538940524607584962315743691711317613478\n  3882719416860662572103685132156647800147675231039357860689611125996028183930954870905907386135191459\n  1819510297327875571049729011487171897180046961697770017913919613791417162707018958469214343696762927\n  4591099400600849835684252019155937037010110497473394938778859894174330317853487076032219829705797511\n  9144051099423588303454635349234982688362404332726741554030161950568065418093940998202060999414021689\n  0900708213307230896621197755306659188141191577836272927461561857103721724710095214236964830864102592\n  8874579993223749551912219519034244523075351338068568073544649951272031744871954039761073080602699062\n  5807602029273145525207807991418429063884437349968145827337207266391767020118300464819000241308350884\n  6584152148991276106513741539435657211390328574918769094413702090517031487773461652879848235338297260\n  1361109845148418238081205409961252745808810994869722161285248974255555160763716750548961730168096138\n  0381191436114399210638005083214098760459930932485102516829446726066613815174571255975495358023998314\n  6982203613380828499356705575524712902745397762140493182014658008021566536067765508783804304134310591\n  8046068008345911366408348874080057412725867047922583191274157390809143831384564241509408491339180968\n  4025116399193685322555733896695374902662092326131885589158083245557194845387562878612885900410600607\n  3746501402627824027346962528217174941582331749239683530136178653673760642166778137739951006589528877\n  4276626368418306801908046098498094697636673356622829151323527888061577682781595886691802389403330764\n  4191240341202231636857786035727694154177882643523813190502808701857504704631293335375728538660588890\n  4583111450773942935201994321971171642235005644042979892081594307167019857469273848653833436145794634\n  1759225738985880016980147574205429958012429581054565108310462972829375841611625325625165724980784920\n  9989799062003593650993472158296517413579849104711166079158743698654122234834188772292944633517865385\n  6731962559852026072947674072616767145573649812105677716893484917660771705277187601199908144113058645\n  5779105256843048114402619384023224709392498029335507318458903553971330884461741079591625117148648744\n  6861124760542867343670904667846867027409188101424971114965781772427934707021668829561087779440504843\n  7528443375108828264771978540006509704033021862556147332117771174413350281608840351781452541964320309\n  5760186946490886815452856213469883554445602495566684366029221951248309106053772019802183101032704178\n  3866544718126039719068846237085751808003532704718565949947612424811099928867915896904956394762460842\n  4065930948621507690314987020673533848349550836366017848771060809804269247132410009464014373603265645\n  1845667924566695510015022983307984960799498824970617236744936122622296179081431141466094123415935930\n  9585407913908720832273354957208075716517187659944985693795623875551617575438091780528029464200447215\n  3962807463602113294255916002570735628126387331060058910652457080244749375431841494014821199962764531\n  0680066311838237616396631809314446712986155275982014514102756006892975024630401735148919457636078935\n  2855505317331416457050499644389093630843874484783961684051845273288403234520247056851646571647713932\n  3775517294795126132398229602394548579754586517458787713318138752959809412174227300352296508089177705\n  0682592488223221549380483714547816472139768209633205083056479204820859204754998573203888763916019952\n  4091893894557676874973085695595801065952650303626615975066222508406742889826590751063756356996821151\n  0949669744580547288693631020367823250182323708459790111548472087618212477813266330412076216587312970\n  8112307581598212486398072124078688781145016558251361789030708608701989758898074566439551574153631931\n  9198107057533663373803827215279884935039748001589051942087971130805123393322190346624991716915094854\n  1401871060354603794643379005890957721180804465743962806186717861017156740967662080295766577051291209\n  9079443046328929473061595104309022214393718495606340561893425130572682914657832933405246350289291754\n  7087256484260034962961165413823007731332729830500160256724014185152041890701154288579920812198449315\n  6999059182011819733500126187728036812481995877070207532406361259313438595542547781961142935163561223\n  4966615226147353996740515849986035529533292457523888101362023476246690558164389678630976273655047243\n  4864307121849437348530060638764456627218666170123812771562137974614986132874411771455244470899714452\n  2885662942440230184791205478498574521634696448973892062401943518310088283480249249085403077863875165\n  9113028739587870981007727182718745290139728366148421428717055317965430765045343246005363614726181809\n  6997693348626407743519992868632383508875668359509726557481543194019557685043724800102041374983187225\n  9677387154958399718444907279141965845930083942637020875635398216962055324803212267498911402678528599\n  6734052420310917978999057188219493913207534317079800237365909853755202389116434671855829068537118979\n  5262623449248339249634244971465684659124891855662958932990903523923333364743520370770101084388003290\n  7598342170185542283861617210417603011645918780539367447472059985023582891833692922337323999480437108\n  4196594731626548257480994825099918330069765693671596893644933488647442135008407006608835972350395323\n  4017958255703601693699098867113210979889707051728075585519126993067309925070407024556850778679069476\n  6126298082251633136399521170984528092630375922426742575599892892783704744452189363203489415521044597\n  2618838003006776179313813991620580627016510244588692476492468919246121253102757313908404700071435613\n  6231699237169484813255420091453041037135453296620639210547982439212517254013231490274058589206321758\n  9494345489068463993137570910346332714153162232805522972979538018801628590735729554162788676498274186\n  1642187898857410716490691918511628152854867941736389066538857642291583425006736124538491606741373401\n  7357277995634104332688356950781493137800736235418007061918026732855119194267609122103598746924117283\n  7493126163395001239599240508454375698507957046222664619000103500490183034153545842833764378111988556\n  3187777925372011667185395418359844383052037628194407615941068207169703022851522505731260930468984234\n  3315273213136121658280807521263154773060442377475350595228717440266638914881717308643611138906942027\n  9088143119448799417154042103412190847094080254023932942945493878640230512927119097513536000921971105\n  4120966831115163287054230284700731206580326264171161659576132723515666625366727189985341998952368848\n  3099930275741991646384142707798870887422927705389122717248632202889842512528721782603050099451082478\n  3572905691988555467886079462805371227042466543192145281760741482403827835829719301017888345674167811\n  3989547504483393146896307633966572267270433932167454218245570625247972199786685427989779923395790575\n  8189062252547358220523642485078340711014498047872669199018643882293230538231855973286978092225352959\n  1017341407334884761005564018242392192695062083183814546983923664613639891012102177095976704908305081\n  8547041946643713122996923588953849301363565761861060622287055994233716310212784574464639897381885667\n  4626087948201864748767272722206267646533809980196688368099415907577685263986514625333631245053640261\n  0569605513183813174261184420189088853196356986962795036738424313011331753305329802016688817481342988\n  6815855778103432317530647849832106297184251843855344276201282345707169885305183261796411785796088881\n  5032960229070561447622091509473903594664691623539680920139457817589108893199211226007392814916948161\n  5273842736264298098234063200244024495894456129167049508235812487391799648641133480324757775219708932\n  7722623494860150466526814398770516153170266969297049283162855042128981467061953319702695072143782304\n  7687528028735412616639170824592517001071418085480063692325946201900227808740985977192180515853214739\n  2653251559035410209284665925299914353791825314545290598415817637058927906909896911164381187809435371\n  5213322614436253144901274547726957393934815469163116249288735747188240715039950094467319543161938554\n  8520766573882513963916357672315100555603726339486720820780865373494244011579966750736071115935133195\n  9197120948964717553024531364770942094635696982226673775209945168450643623824211853534887989395673187\n  8066061078854400055082765703055874485418057788917192078814233511386629296671796434687600770479995378\n  8338787034871802184243734211227394025571769081960309201824018842705704609262256417837526526335832424\n  0661253311529423457965569502506810018310900411245379015332966156970522379210325706937051090830789479\n  9990049993953221536227484766036136776979785673865846709366795885837887956259464648913766521995882869\n  3380183601193236857855855819555604215625088365020332202451376215820461810670519533065306060650105488\n  7167245377942831338871631395596905832083416898476065607118347136218123246227258841990286142087284956\n  8796393254642853430753011052857138296437099903569488852851904029560473461311382638788975517885604249\n  9874831638280404684861893818959054203988987265069762020199554841265000539442820393012748163815853039\n  6439925470201672759328574366661644110962566337305409219519675148328734808957477775278344221091073111\n  3518280460363471981856555729571447476825528578633493428584231187494400032296906977583159038580393535\n  2135886007960034209754739229673331064939560181223781285458431760556173386112673478074585067606304822\n  9409653041118306671081893031108871728167519579675347188537229309616143204006381322465841111157758358\n  5811350185690478153689381377184728147519983505047812977185990847076219746058874232569958288925350419\n  3795826061621184236876851141831606831586799460165205774052942305360178031335726326705479033840125730\n  5912339601880137825421927094767337191987287385248057421248921183470876629667207272325650565129333126\n  0595057777275424712416483128329820723617505746738701282095755443059683955556868611883971355220844528\n  5264008125202766555767749596962661260456524568408613923826576858338469849977872670655519185446869846\n  9478495734622606294219624557085371272776523098955450193037732166649182578154677292005212667143463209\n  6378918523232150189761260343736840671941930377468809992968775824410478781232662531818459604538535438\n  3911449677531286426092521153767325886672260404252349108702695809964759580579466397341906401003636190\n  4042033113579336542426303561457009011244800890020801478056603710154122328891465722393145076071670643\n  5568274377439657890679726874384730763464516775621030986040927170909512808630902973850445271828927496\n  8921210667008164858339553773591913695015316201890888748421079870689911480466927065094076204650277252\n  8650728905328548561433160812693005693785417861096969202538865034577183176686885923681488475276498468\n  8219497397297077371871884004143231276365048145311228509900207424092558592529261030210673681543470152\n  5234878635164397623586041919412969769040526483234700991115424260127343802208933109668636789869497799\n  4001260164227609260823493041180643829138347354679725399262338791582998486459271734059225620749105308\n  5315371829116816372193951887009577881815868504645076993439409874335144316263303172477474868979182092\n  3948083314397084067308407958935810896656477585990556376952523265361442478023082681183103773588708924\n  0613031336477371011628214614661679404090518615260360092521947218890918107335871964142144478654899528\n  5823439470500798303885388608310357193060027711945580219119428999227223534587075662469261776631788551\n  4435021828702668561066500353105021631820601760921798468493686316129372795187307897263735371715025637\n  8733579771808184878458866504335824377004147710414934927438457587107159731559439426412570270965125108\n  1155482479394035976811881172824721582501094960966253933953809221955919181885526780621499231727631632\n  1833989693807561685591175299845013206712939240414459386239880938124045219148483164621014738918251010\n  9096773869066404158973610476436500068077105656718486281496371118832192445663945814491486165500495676\n  9826903089111856879869294705135248160917432430153836847072928989828460222373014526556798986277679680\n  9146979837826876431159883210904371561129976652153963546442086919756737000573876497843768628768179249\n  7469438427465256316323005551304174227341646455127812784577772457520386543754282825671412885834544435\n  1325620544642410110379554641905811686230596447695870540721419852121067343324107567675758184569906930\n  4604752277016700568454396923404171108988899341635058515788735343081552081177207188037910404698306957\n  8685473937656433631979786803671873079693924236321448450354776315670255390065423117920153464977929066\n  2415083288583952905426376876689688050333172278001858850697362324038947004718976193473443084374437599\n  2503417880797223585913424581314404984770173236169471976571535319775499716278566311904691260918259124\n  9890367654176979903623755286526375733763526969344354400473067198868901968147428767790866979688522501\n  6369498567302175231325292653758964151714795595387842784998664563028788319620998304945198743963690706\n  8276265748581043911223261879405994155406327013198989570376110532360629867480377915376751158304320849\n  8720920280929752649812569163425000522908872646925284666104665392171482080130502298052637836426959733\n  7070539227891535105688839381132497570713310295044303467159894487868471164383280506925077662745001220\n  0352620370946602341464899839025258883014867816219677519458316771876275720050543979441245990077115205\n  1546199305098386982542846407255540927403132571632640792934183342147090412542533523248021932277075355\n  5467958716383587501815933871742360615511710131235256334858203651461418700492057043720182617331947157\n  0086757853933607862273955818579758725874410254207710547536129404746010009409544495966288148691590389\n  9071865980563617137692227290764197755177720104276496949611056220592502420217704269622154958726453989\n  2276976603105249808557594716310758701332088614632664125911486338812202844406941694882615295776253250\n  1987035987067438046982194205638125583343642194923227593722128905642094308235254408411086454536940496\n  9271494003319782861318186188811118408257865928757426384450059944229568586460481033015388911499486935\n  4360302218109434667640000223625505736312946262960961987605642599639461386923308371962659547392346241\n  3459779574852464783798079569319865081597767535055391899115133525229873611277918274854200868953965835\n  9421963331502869561192012298889887006079992795411188269023078913107603617634779489432032102773359416\n  9086500719328040171638406449878717537567811853213284082165711075495282949749362146082155832056872321\n  8557406516109627487437509809223021160998263303391546949464449100451528092508974507489676032409076898\n  3652940657920198315265410658136823791984090645712468948470209357761193139980246813405200394781949866\n  2026240089021501661638135383815150377350229660746279529103840686855690701575166241929872444827194293\n  3100485482445458071889763300323252582158128032746796200281476243182862217105435289834820827345168018\n  6131719593324711074662228508710666117703465352839577625997744672185715816126411143271794347885990892\n  8084866949141390977167369002777585026866465405659503948678411107901161040085727445629384254941675946\n  0548711723594642910585090995021495879311219613590831588262068233215615308683373083817327932819698387\n  5087083483880463884784418840031847126974543709373298362402875197920802321878744882872843727378017827\n  0080587824107493575148899789117397461293203510814327032514090304874622629423443275712600866425083331\n  8768865075642927160552528954492153765175149219636718104943531785838345386525565664065725136357506435\n  3236508936790431702597878177190314867963840828810209461490079715137717099061954969640070867667102330\n  0486726314755105372317571143223174114116806228642063889062101923552235467116621374996932693217370431\n  0598722503945657492461697826097025335947502091383667377289443869640002811034402608471289900074680776\n  4844088711341352503367877316797709372778682166117865344231732264637847697875144332095340001650692130\n  5464768909850502030150448808342618452087305309731894929164253229336124315143065782640702838984098416\n  0295030924189712097160164926561341343342229882790992178604267981245728534580133826099587717811310216\n  7340256562744007296834066198480676615805021691833723680399027931606420436812079900316264449146190219\n  4582296909921227885539487835383056468648816555622943156731282743908264506116289428035016613366978240\n  5177015521962652272545585073864058529983037918035043287670380925216790757120406123759632768567484507\n  9151147313440001832570344920909712435809447900462494313455028900680648704293534037436032625820535790\n  1183956490893543451013429696175452495739606214902887289327925206965353863964432253883275224996059869\n  7475988232991626354597332444516375533437749292899058117578635555562693742691094711700216541171821975\n  0519831787137106051063795558588905568852887989084750915764639074693619881507814685262133252473837651\n  1929901561091897779220087057933964638274906806987691681974923656242260871541761004306089043779766785\n  1966189140414492527048088197149880154205778700652159400928977760133075684796699295543365613984773806\n  0394368895887646054983871478968482805384701730871117761159663505039979343869339119789887109156541709\n  1330826076474063057114110988393880954814378284745288383680794188843426662220704387228874139478010177\n  2139228191199236540551639589347426395382482960903690028835932774585506080131798840716244656399794827\n  5783650195514221551339281978226984278638391679715091262410548725700924070045488485692950448110738087\n  9965474815689139353809434745569721289198271770207666136024895814681191336141212587838955773571949863\n  1721084439890142394849665925173138817160266326193106536653504147307080441493916936326237376777709585\n  0313255990095762731957308648042467701212327020533742667053142448208168130306397378736642483672539837\n  4876909806021827857862165127385635132901489035098832706172589325753639939790557291751600976154590447\n  7169226580631511102803843601737474215247608515209901615858231257159073342173657626714239047827958728\n  1505095633092802668458937649649770232973641319060982740633531089792464242134583740901169391964250459\n  1288134034988106354008875968200544083643865166178805576089568967275315380819420773325979172784376256\n  6118431989102500749182908647514979400316070384554946538594602745244746681231468794344161099333890899\n  2638411847425257044572517459325738989565185716575961481266020310797628254165590506042479114016957900\n  3383565748692528007430256234194982864679144763227740055294609039401775363356554719310001754300475047\n  1914489984104001586794617924161001645471655133707407395026044276953855383439755054887109978520540117\n  5169747581344926079433689543783221172450687344231989878844128542064742809735625807066983106979935260\n  6933921356858813912148073547284632277849080870024677763036055512323866562951788537196730346347012229\n  3958160679250915321748903084088651606111901149844341235012464692802880599613428351188471544977127847\n  3361766285062169778717743824362565711779450064477718370221999106695021656757644044997940765037999954\n  8450027106659878136038023141268369057831904607927652972776940436130230517870805465115424693952651271\n  0105292707030667302444712597393995051462840476743136373997825918454117641332790646063658415292701903\n  0276017339474866960348694976541752429306040727005059039503148522921392575594845078867977925253931765\n  1564161971684435243697944473559642606333910551268260615957262170366985064732812667245219890605498802\n  8078288142979633669674412480598219214633956574572210229867759974673812606936706913408155941201611596\n  0190237753525556300606247983261249881288192937343476862689219239777833910733106588256813777172328315\n  3290825250927330478507249771394483338925520811756084529665905539409655685417060011798572938139982583\n  1929367910039184409928657560599359891000296986446097471471847010153128376263114677420914557404181590\n  8800064943237855839308530828305476076799524357391631221886057549673832243195650655460852881201902363\n  6447127037486344217272578795034284863129449163184753475314350413920961087960577309872013524840750576\n  3719925365047090858251393686346386336804289176710760211115982887553994012007601394703366179371539630\n  6139863655492213741597905119083588290097656647300733879314678913181465109316761575821351424860442292\n  4453041131606527009743300884990346754055186406773426035834096086055337473627609356588531097609942383\n  4738222208729246449768456057956251676557408841032173134562773585605235823638953203853402484227337163\n  9123973215995440828421666636023296545694703577184873442034227706653837387506169212768015766181095420\n  0977083636043611105924091178895403380214265239489296864398089261146354145715351943428507213534530183\n  1587562827573389826889852355779929572764522939156747756667605108788764845349363606827805056462281359\n  8885879259940946446041705204470046315137975431737187756039815962647501410906658866162180038266989961\n  9655805872086397211769952194667898570117983324406018115756580742841829106151939176300591943144346051\n  5404771057005433900018245311773371895585760360718286050635647997900413976180895536366960316219311325\n  0223851791672055180659263518036251214575926238369348222665895576994660491938112486609099798128571823\n  4940066155521961122072030922776462009993152442735894887105766238946938894464950939603304543408421024\n  6240104872332875008174917987554387938738143989423801176270083719605309438394006375611645856094312951\n  7597713935396074322792489221267045808183313764165818269562105872892447740035947009268662659651422050\n  6300785920024882918608397437323538490839643261470005324235406470420894992102504047267810590836440074\n  6638002087012666420945718170294675227854007450855237772089058168391844659282941701828823301497155423\n  5235911774818628592967605048203864343108779562892925405638946621948268711042828163893975711757786915\n  4301650586029652174595819888786804081103284327398671986213062055598552660364050462821523061545944744\n  8990883908199973874745296981077620148713400012253552224669540931521311533791579802697955571050850747\n  3874750758068765376445782524432638046143042889235934852961058269382103498000405248407084403561167817\n  1705128133788057056434506161193304244407982603779511985486945591520519600930412710072778493015550388\n  9536033826192934379708187432094991415959339636811062755729527800425486306005452383915106899891357882\n  0019411786535682149118528207852130125518518493711503422159542244511900207393539627400208110465530207\n  9328672547405436527175958935007163360763216147258154076420530200453401835723382926619153083540951202\n  2632916505442612361919705161383935732669376015691442994494374485680977569630312958871916112929468188\n  4936338647392747601226964158848900965717086160598147204467428664208765334799858222090619802173211614\n  2304194777549907387385679411898246609130916917722742072333676350326783405863019301932429963972044451\n  7928812285447821195353089891012534297552472763573022628138209180743974867145359077863353016082155991\n  1314144205091447293535022230817193663509346865858656314855575862447818620108711889760652969899269328\n  1787055764351433820601410773292610634315253371822433852635202177354407152818981376987551575745469397\n  2715048846979361950047772097056179391382898984532742622728864710888327017372325881824465843624958059\n  2560338105215606206155713299156084892064340303395262263451454283678698288074251422567451806184149564\n  6861116354049718976821542277224794740335715274368194098920501136534001238467142965518673441537416150\n  4256325671343024765512521921803578016924032669954174608759240920700466934039651017813485783569444076\n  0470232540755557764728450751826890418293966113310160131119077398632462778219023650660374041606724962\n  4901374332172464540974129955705291424382080760983648234659738866913499197840131080155813439791948528\n  3043673901248208244481412809544377389832005986490915950532285791457688496257866588599917986752055455\n  8099004556461178755249370124553217170194282884617402736649978475508294228020232901221630102309772151\n  5694464279098021908266898688342630716092079140851976952355534886577434252775311972474308730436195113\n  9611908003025587838764420608504473063129927788894272918972716989057592524467966018970748296094919064\n  8764693702750773866432391919042254290235318923377293166736086996228032557185308919284403805071030064\n  7768478632431910002239297852553723755662136447400967605394398382357646069924652600890906241059042154\n  5392790441152958034533450025624410100635953003959886446616959562635187806068851372346270799732723313\n  4693971456285542615467650632465676620279245208581347717608521691340946520307673391841147504140168924\n  1213198268815686645614853802875393311602322925556189410429953356400957864953409351152664540244187759\n  4931693056044868642086275720117231952640502309977456764783848897346431721598062678767183800524769688\n  4084989185086149003432403476742686245952395890358582135006450998178244636087317754378859677672919526\n  1112138591947254514003011805034378752776644027626189410175768726804281766238606804778852428874302591\n  4524707395054652513533945959878961977891104189029294381856720507096460626354173294464957661265195349\n  5701860015412623962286413897796733329070567376962156498184506842263690367849555970026079867996261019\n  0393312637685569687670292953711625280055431007864087289392257145124811357786276649024251619902774710\n  9033593330930494838059785662884478744146984149906712376478958226329490467981208998485716357108783119\n  1848630254501620929805829208334813638405421720056121989353669371336733392464416125223196943471206417\n  3754912163570085736943973059797097197266666422674311177621764030686813103518991122713397240368870009\n  9686292254646500638528862039380050477827691283560337254825579391298525150682996910775425764748832534\n  1412132800626717094009098223529657957997803018282428490221470748111124018607613415150387569830918652\n  7806588966823625239378452726345304204188025084423631903833183845505223679923577529291069250432614469\n  5010986108889991465855188187358252816430252093928525807796973762084563748211443398816271003170315133\n  4402309526351929588680690821355853680161000213740851154484912685841268695899174149133820578492800698\n  2551957402018181056412972508360703568510553317878408290000415525118657794539633175385320921497205266\n  0783126028196116485809868458752512999740409279768317663991465538610893758795221497173172813151793290\n  4431121815871023518740757222100123768721944747209349312324107065080618562372526732540733324875754482\n  9675734500193219021991199607979893733836732425761039389853492787774739805080800155447640610535222023\n  2540944356771879456543040673589649101761077594836454082348613025471847648518957583667439979150851285\n  8020607820554462991723202028222914886959399729974297471155371858924238493855858595407438104882624648\n  7880533042714630119415898963287926783273224561038521970111304665871005000832851773117764897352309266\n  6123458887310288351562644602367199664455472760831011878838915114934093934475007302585581475619088139\n  8752357812331342279866503522725367171230756861045004548970360079569827626392344107146584895780241408\n  1584052295369374997106655948944592462866199635563506526234053394391421112718106910522900246574236041\n  3009369188925586578466846121567955425660541600507127664176605687427420032957716064344860620123982169\n  8271723197826816628249938714995449137302051843669076723577400053932662622760323659751718925901801104\n  2903842741855078948874388327030632832799630072006980122443651163940869222207453202446241211558043545\n  4206421512158505689615735641431306888344318528085397592773443365538418834030351782294625370201578215\n  7373265523185763554098954033236382319219892171177449469403678296185920803403867575834111518824177439\n  1450773663840718804893582568685420116450313576333555094403192367203486510105610498727264721319865434\n  3545040913185951314518127643731043897250700498198705217627249406521461995923214231443977654670835171\n  4749367986186552791715824080651063799500184295938799158350171580759883784962257398512129810326379376\n  2183224565942366853767991131401080431397323354490908249104991433258432988210339846981417157560108297\n  0658306521134707680368069532297199059990445120908727577622535104090239288877942463048328031913271049\n  5478599180196967835321464441189260631526618167443193550817081875477050802654025294109218264858213857\n  5266881555841131985600221351588872103656960875150631875330029421186822218937755460272272912905042922\n  5978771066787384000061677215463844129237119352182849982435092089180168557279815642185819119749098573\n  0570332667646460728757430565372602768982373259745084479649545648030771598153955827779139373601717422\n  9960273531027687194494449179397851446315973144353518504914139415573293820485421235081739125497498193\n  0871439661513294204591938010623142177419918406018034794988769105155790555480695387854006645337598186\n  2846419905220452803306263695626490910827627115903856995051246529996062855443838330327638599800792922\n  8466595035512112452840875162290602620118577753137479493620554964010730013488531507354873539056029089\n  3352640071327473262196031177343394367338575912450814933573691166454128178817145402305475066713651825\n  8284898099512139193995633241336556777098003081910272040997148687418134667006094051021462690280449159\n  6465453301077546954130887141653125448130611924078211886900560277818242350226961893443525476335735364\n  8561936325441775661398170393063287216690572225974520919291726219984440964615826945638023950283712168\n  6446561785235565164127712826918688615572716201474934052276946595712198314943381622114006936307430444\n  1732847861017777438379770372317952554341072234455125555899986461838767649039724611679590181000350989\n  2864120419516355110876320426761297982652942588295114127584126273279079880755975185157684126474220947\n  9721843309352972665210015662514552994745127631550917636730259462132930190402837954246323258550301096\n  7069227202270748634190054383026506812141421350571541750575086399076739463351462090828889349383764393\n  9925690060406731142209331219593620298297235116325938677224147791162957278075239505625158160313335938\n  2311500518626890530658368129988108663263271980611271548858798093487912913707498230575929091862939195\n  0147211975860672700925477180257503377307993971345395326461952699965963856549175904583335857991020127\n  1320458390320085387888163363768518208372788513117522776960978796214237216254521459128183179821604411\n  1311671406914827170981015457781939202311563871950805024679725792497605772625913328559726371211201905\n  7207714091486450740949267180358151575715140503976109638467555692989703835473141002238025834687673501\n  2977541327953206097115450648421218593649099791776687477448188287063231551586503289816422828823274686\n  6106592732197907162384642153489852476216789050260998045266483929542357287343977680495774091449538391\n  5755654854590589764951985138010079580107837599457752991967005476022525520344539887125387801719607181\n  6407812484784725791240782454436168234523957068951427226975043187363326301110305342333582160933319121\n  8806608268341428910415173247216053355849993224548730778822905252324234861531520976938461042582849714\n  9634753418375620030149157032796853018686315724884015266398356895636346574353217834931998255421173084\n  6774529708583950761645822963032442432823773745051702856069806788952176819815671078163340526675953942\n  4926280756968326107495323390536223090807081455919837355377748742029039018142937311529334644468151212\n  9450975965343062842153194457271186149000176505581770953024688752632501197052094761594167687277844720\n  0019278913725184162285778379228443908430118112149636642465903363419454065718354477191244662125939265\n  6620306888520055599121235363718226922531781458792593750441448933981608657900876165024635197045828895\n  4817937566810464746141051424988702521399368705093723054477341126413548928068410591077166778212383328\n  1026218558775131272117934444820144042574508306394473836379390628300897330624138061458941422769474793\n  1665717623182472168350678076487573420491557628217583972975134478990696589532548940335615613167403276\n  4724692125057591162515296545685446334981143176702572956618447754874693784642337372389819206620485118\n  9437886822480727935202250179654534375727416391079197295295081294292220534771730418447791567399173841\n  8311710362524395716152714669005814700002633010452643547865903290733205468338872078735444762647925297\n  6901709120078741837367350877133769776834963442524199499513883150748775374338494582597655609965559543\n  1804092017849718468549737069621208852437701385375768141663272241263442398215294164537800049250726276\n  5150789085071265997036708726692764308377229685985169122305037462744310852934305273078865283977335246\n  0174635277032059381791253969156210636376258829375713738407544064689647831007045806134467312715911946\n  0843593582598778283526653115106504162329532904777217408355934972375855213804830509000964667608830154\n  0612824308740645594431853413755220166305812111033453120745086824339432159043594430312431227471385842\n  0303901060709403152355561727679941600203939750998976293353258555756248089966918298642226775023601932\n  5797472674257821111973470940235745722227121252685238429587427350156366009318804549333898974157149054\n  4182559738080871565281430102670460284316819230392535297795765862414392701549740879273131051636119137\n  5770089295648233236482982630246079758757677453771601024908046243018565241617566556001608591215345562\n  6760219268998285537787258314514408265458348440947846317877737479465358016996077940556870119232860804\n  1130904629350871827125934668712766694873899824598527786499569165464029458935064964335809824765965165\n  1420909867552038083092032304873427034682887516040715466538346196112230137594515792526967436425319273\n  9003603860823645076269882749761872357547676288995075211480485252795084503395857083813047693788132112\n  3674281319487950228066320170022460331989671970649163741175854851878484012054844672588851401562725019\n  8217190669608126277854859648183696214107217142149863619187747545096503089570994709343378569816744658\n  2826791194061195603784539785583924076127634410576675102430755981455278616781594965706255975507430652\n  1085301597908073343736079432866757890533483669555486803913433720156498834220893399971641479746938696\n  9054800891930671380571715058573071488156499207140867582596028760564597824237702424698053280566327870\n  4192676846711626687946348695046450742021937394525926266861355294062478136120620263649819999949840514\n  3868285258956342264328707663299304891723400725471764188685351372332667877921738347541480022803392997\n  3579361524127558295692768372312347989894462743304545667900620324205163962825884430854383072014956721\n  0646053323853720314324211260742448584509458049408182092763914000854042202355626021856434899414543995\n  0410980591817948882628052066441086319001688568155169229486203010738897181007709290590480749092427141\n  0189335428184299959881696609938369616443815288772140852680887574882932587358099056707558170179491619\n  0611400190855374488272620093668560447559655747648567400817738170330738030547697360978654385938218722\n  0583902344443508867499866506040645874346005331827436296177862518081893144363251205107094690813586440\n  5192295129324500788333987884293393424351263433652043858129128343452973086529097833006712617981303167\n  9438553572629699874035957045845223085639009891317947594875212639707837594486113945196028675121056163\n  8976008880092746115860800207803341591451797073036835196977766076373785333012024120112046988609209339\n  0853657732223924124490515327809509558664594776344822699860748132973026309750288121035177231244650953\n  4965369309001863776409409434983731325132186208021480992268550294845466181471555744470966953017769043\n  4272031892770604717784527939160472281534379803539679861424370956683221491465438014593829277393396032\n  7540480095522318166673803571839327570771420467238386246178039762923771312095807893638414479298025880\n  6552212926209362393063731349664018661951081158347117331202580586672763999276357907806381881306915636\n  6274125431259589936119647626101405563503399523140323113819656236327198961837254845333702062563464223\n  9527669435683767613687119629218187545760816170530315907288287007123136663087227549186613957737305460\n  6599743781098764980241401124214277366808275139095931340415582626678951084677611866595766016599817808\n  9414985754976284387856100263796543178313634025135814161151902096499133548733131115022700681930135929\n  5959716401971960536250335584799809634887180391116128135959685654788683258564378961731597620024196215\n  5289629790481982219946226948713746244472909345647002853769495885959160678928249105441251599630078136\n  8367490209374915732896270028656829344431342347351239298259166739503425995868970697267332582735903121\n  2887466604514614878503461428277659916080903986525757172630818334944418201935333850712923457743755793\n  4406217871133006310600332405399169368260374617663856575887758020122936635327026710068126182517291460\n  8202541892885935244491070138206211553827793565296914576502048643282865557934707209634807372692141186\n  8954673227677513356901901537236690368653891612916888878764075254934942497334271811788927599315967193\n  5475898809792452526236365903632007085444078454479734829180208204492667063442043755532505052752283377\n  8887040804033531923407685630109347772125639088640413101073817853338316038135280828119040832564401842\n  0537467929926220376987180180611226244909092426419858208617511771137890516091403815750033664241560952\n  1632819712233502316742260056794128140621721964184270578432895980288233505982820819666624903585778994\n  0333152274817776952843681630088531769694783690580671064828083598046698841098135158654906933319522394\n  3632879239905348109878302745001720654336990661177845543646877236318444647680691428280045510746866453\n  9280539940910875493916609573161971503316696830992946634914279878084225722069714887558063748030886299\n  5118473187124777291910070227588893486939456289515802965372150409603107761289831263589964893410247036\n  0366450586872875890514068412381242473863854279082827338279733268855049358743031602747490631295723497\n  4261122151741715313361862241091386950068883589896234927631731647834007746088665559873338211382992877\n  6911495492184192087771606068472874673681886167507221017261103830671787856694812948785048943063086169\n  9487987031605158841082823512741535385133658953329486294944950618685147791058046960390693726626703865\n  1290520113781085861618888694795760741358553458515176805197333443349523012039577073962377131603024288\n  7200537320998253008977618973129817881944671731160647231476248457551928732782825127182446807824215216\n  4695678192940982389262849437602488522790036202193866964822156280936053731780408637272684266964219299\n  4681921490870170753336109479138180406328738759384826953558307739576144799727000347288018278528138950\n  3217986345216111066608839314053226944905455527867894417579202440021450780192099804461382547805858048\n  4424164047750315360549065914300781583724301231375115622840158386442708907182848167575271238467824595\n  3433444962201009607105137060846180118754312072549133499424761711563332140893460915656155060031738421\n  8701570226103101916603887064661438897736318780940711527528174689576401581047016965247557740891644568\n  6777171585005832699434016772021567677240681283665652641229824394651331973591997094032759385026695574\n  7023181320324371642058614103360652453693916005064495306016126782264894243739716671766123104897503188\n  5732165554988342121802846912529086101485527815277625623750456375769497734336846015607727035509629049\n  3924870884062810679436224187047470083688426710225583024035998416459511224852726336326451140173952480\n  8619463584078375355688562231711552094722306543709260679735100056554938122457548372854571179739361575\n  6167641692895805257297522338558611388322171107362265816218842443178857488798109026653793426664216990\n  9140565364322493013348679881548866286650523469972355747384248305904236771432787923164224038777643301\n  9260019228477831383763253612102533693581262408686669973827597736568222790721583247888864236934639616\n  4363308730139814211430306008730666164803678984091335926293402304324974926887831643602681011309570716\n  1419128306865773235326396536773903176613613159655535849993986005651559219367599777179330197446881483\n  7110320650369319289452140265091546518430993655349333718342529843367991593941746622390038952767381333\n  0617747629574943868716978453767219493506590875711917720875477107189937960894774512654757501871194870\n  7387367858902006173733210756933022163206284320656711920969505857611739616323262177089454262146098584\n  1023781321581772760222273813349541048100307327510779994899197796388353073444345753297591426376840544\n  2264784216063122769646967156473999043715903323906560726644116438605404838847161912109008701019130726\n  0710441141432419767968285478855247794764818029597360494397004795960402927462992035720997619501403483\n  1538094771460105633344699882082212058728151072918297121191787642488035467231691654185225672923442918\n  7128163232596965413548589577133208339911288775917226115273379010341362085614577992398778325083550730\n  1998184590259583559892605532996737704917224549353296833000022301815172265757875240588322490858212800\n  8974790932610076257877042865600699617621217684547899644070506624171021332748679623743022915535820078\n  0141165348065647488230615003392068983794766255036549822805329662862117930628430170492402301985719978\n  9488368971830438051821744191476604297524372516834354112170386313794114220952958857980601529387527537\n  9903093887168357209576071522190027937929278630363726876582268124199338480816602160372215471014300737\n  7537792699069587121289288019052031601285861825494413353820784883465311632650407642428390870121015194\n  2319616522684220037112304643006734420647477180213530701240988603533991526679238711017062218658835737\n  8121093517977560442563469499978725112544085452227481091487430725986960204027594117894258128188215995\n  2359658979181144077653354321757595255536158128001163846720319346507296807990793963714961774312119402\n  0212975731251652537680173591015573381537720019524445436200718484756634154074423286210609976132434875\n  4884743453966598133871746609302053507027195298394327142537115576660002578442303107342955153394506048\n  6222764966687624079324353192992639253731076892135352572321080889819339168668278948281170472624501948\n  4097009757609209837240900747179733407881418251958425980962417476101382526439551352593118850456362641\n  8830033853965243599741693132289471987830842760040136807470390409723847394583489618653979059411859931\n  0356168436869219485382055780395773881360679549900085123259442529724486666766834641402189915944565309\n  4234406506678519484177667794704720419588220432953803263105374948831221803912796784461001397267538921\n  9511911783658766252808369005324900459741094706877291232821430463533728351995364827432583311914445901\n  7809607782883583730111857543659958982724531925310588115026307542571493943024453931870179923608166611\n  3054262539958338979429716020703387678150330102801200959972522222808014235710947603519255444349299867\n  6781789104555906301595380976187592035893734197896235893112598390259831026719330418921510968915622506\n  9659119828323455503059081730735195503721665870288053992138576037035377105178021280129566841984140362\n  8727256232144287543022109094727210734741349755141907370433182766261772759968888260272252471336833534\n  5281669277959132886138176634985772893690096574956228710302436259077241221909430087175569262575806570\n  9912016659622436080242870024547362036394841255954881727272473653467783647201918303998717627037515724\n  6499222894679323226936191776416146187956139566995677830682903165896994307673335082349907906241002025\n  0613405734430069574547468217569044165154063658468046369262127421107539904218871612761778701425886482\n  5775223889184599523376292377915585744549477361295525952226578636462118377598473700347971408206994145\n  5807190802135907322692331008317595106590191212947954086036407573587502058902087045796700070552625058\n  1142066390745921527330940682364944159089100922029668052332526619891131184201629163107689408472356436\n  6808182168657219688268358402785500782804043453710183651096951782335743030504852653738073531074185917\n  7056103973950626403554422751561011072617793706347238049906669221619711942591204450846417463835899382\n  3994651739550900085947999013602667426149429006646711506717542217703877450767356374215478290591101261\n  9157555870238957001405117822646989944917908301795475876760168094100135837613578591356924455647764464\n  1786671153919513576961048649224900834467154863830544779143300976804868783481846727337584368927243104\n  4740680768527862558516509208826381323362314873333671476452045087662761495038994950480956046098960432\n  9123358348859990294526400284994280878624039811814884767301216754161106629995553668193123287425702063\n  7383520200868636913117334697317412191536332467453256308713473027921749562270146873258678917345583799\n  6435135880095935087755635624881049385299900767513551352779241242927748856588856651324730251471021057\n  5352516511814850902750476845518252096331899068527614435138213662152368890578786699432288816028377482\n  0355060160298940091197138501798716836337441392759736440170070147637066557035043381211135764150184518\n  2141361982349515960106475271257593518530433287553778305750956742544268471221961870917856078393614451\n  1383335649103256405733898667178123972237519316430617013859539474367843392670986712452211189690840236\n  3274114966012434830989299417380305884171666130730400675883804321115553794406054977217059428215148861\n  6567277124090338772774562909711013488518437411869565544974573684521806698291104505800429988795389902\n  7804383596282409421860556287788428802127553884803728640019441614257499904272009595204654170598104989\n  9675045119364711727722204361026140797508096869751766002371877483480161203102346805671126447661237476\n  2785219024120256994353471622666089367521983311181351114650385489502512065577263614547360442685949807\n  4396932331297127377157347099713952291182653485155587137336629120242714302503763269501350911612952993\n  7858646813072264860082708813335381937036825988678933212383270532976258573827900978264605455985551318\n  3668884462826513379849166783940976135376625179825824966345877195012438404035914084920973375464247448\n  8176184070023569580177410177696925077814893386672557898564589851056891960924398841569280696983352240\n  2256345704973122452693541938370048431833571965166267215755241934019330990183193091965829209696562476\n  6768365964701959575473934551433741370876151732367720422738567427917069820454995309591887243493952409\n  4441678998846319845504852393662972079777452814399418256789457795712552426826089940863317371538896262\n  8896294021121088844273765686245276121303710173007851357154045330415079594477761435974378037424366469\n  7324713841049212431413890357909241603640631403814983148190525172093710396402680899483257229795456404\n  2701757722904173234796073618787889913318305843069394825961318713816423467218730845133877219086975104\n  9428437693250249816566738162606159417682525099937416728839517440669325496534031014522253161890092353\n  7648637848288134420987004809622717122640748957193900291857330746010436072919094576799461492929042798\n  1687729426487729952858434647775386906950148984133924540394144680263625402118614317031251117577642829\n  9146445334089209769616990983726523617687456058947049681701369749095230720826828878907301900182534258\n  0534342170592871393173799314241085264739094828459641809361413847583113613057610846236683723769591349\n  2615824516221552134879244145041756848064120636520170386330129532777699023118648020067556905682295016\n  3549319923059142463962170253297475731140942201801993680350264956369558664259067626856873721103391567\n  9383989576556519317788300024161353956243777784080174881937309502069990089089932808839743036773659552\n  4891300156633294077907139615464534088791510300651321934486673248275907946807879819425019582622320395\n  1312520141099605312606965554042486705499867869230217469890095478507256729787947698888310934874644264\n  0071818316033165551153427615562240547447337804924621495213325852769884733626918264917433898782478927\n  8468918828054669982303689939783413747587025805716349413568433929396068192061773331791738208562436433\n  6353598634944968907810640196740744365836670715869245211829978938040771375012908586465789057714268335\n  8276897855471768718442772612050926648610205153564284063236848180728794071712796682006072755955590404\n  0233178749447346454760628189541512139162918444297651066947969354016866010055196077687335396511614930\n  9375709685545593815137895690392510149532656281470119983269922000663928753747131352364215892651262040\n  7288771657835840521964605410543544364216656224456504299901025658692727914275293117208279393775132610\n  6052881235373451068372939893580871243869385934389175713376300720319760816604464683937725806909237297\n  5234867029169104263692620901996052041210240776481903160140858635584276095370865581642739953493465463\n  1450404019952853725200495780525465625115410925243799132626271360909940290226206283675213230506518393\n  4057450112099341464918433323646569371725914489324159006242020612885732926133596808726500045628284557\n  5745965921205303413101118275013069615098355156320043107846019065654938065425252291619918199596027523\n  2770224985573882489988270746593635576858256051806896428537685077201222034792099393617926820659014216\n  5615925306737944568949070853263568196831861772268249911472615732035807646298116244013316737892788689\n  2290325933498617970219949819257396176730758344170985592221701718257127775344915082052784309046194608\n  3521740200583867284970941102326695392144546106621500641067474020700918991195137646690448126725369153\n  7162290791385403937560077835153374167747942100384002308951850994548779039346122220865060160500351776\n  2648316111533255877050735412792499098593734737870811942530551214369797499149518605359204038302357163\n  5272763087469321962219006426088618367610334600225547747781364101269190656968649501268837629690723396\n  1276287223041141813610060264044030035996988919945827397624114613744804059697062576764723766065541618\n  5746905272292382282751867991569833907476711461030227766060200612468764777288190967916133540198814027\n  5799217416767879923160396356949285151363364721954061117176738737255572852294005436178517650230754469\n  3869307873499110352182532929726044553210797887711449898870911511237250604238753734841257086064069052\n  0584521227545338480082053024504565176695185769132000428167580549248117805198326460324457928297301291\n  0531838563682120621553128866856495651261389226136706409395333457052698695969235035309422454386527867\n  7673027540402702246384483553239914751363441044050092330361271496081355490531539021002299595756583705\n  3812619656831442860579566966221547216956208700137277685369608407048333251327931122325071486302069512\n  4539500373572334680709465648308920980153487870563349109236605755405086411152144148143463043727327104\n  5027768661953107858323334857840297160925215326092558932655600672124359464255065996771770388445396181\n  6328796144608177892721718369088801267782074301064225246348074543004764928855534090621851536543554741\n  2547615276977266776977277705831580141218568801170502836527554321480348800444297999806215790456416195\n  7212784508928489806426497427090579129069217807298769477975112447305991406050629946894280931034216416\n  6299356148281309988707452927160484336308184041264696379258430941854422163590845761460785585624738149\n  3142707826621518554160387020687698046174740080832434366538235455510944949843109349475994467267366535\n  2517662706772194183191977196378015702169933675083760057163454643671776723387588643405644871566964321\n  0412825956453498413884128904206820470076155969168430389993483667935425492103281133631847225923055543\n  8305820694167562999201337317548912203723034907268106853445403599356182357631283776764063101312533521\n  2141994611869350833176587852047112364331226765129964171325217513553261867681942338790365468908001827\n  1352835848884441117612341011799187092365071848578562210211040097769944531217950224795780695065329659\n  4038398736990724079767904082679400761872954783596349279390457697366164340535979221928587057495748169\n  6694062334272619733518136626063735982575552496509807260123668283605928341855848026958413772558970883\n  7899429105498003311138846034019391661221866960584915714857335682861495000190975911252188003964197621\n  6355937574371801148055944229873041819680808564726571354761283162920044988031540210553059707666636274\n  9328308916880932359290081787411985738317192616728834918402429721290434965526942726402559641463525914\n  3484006758676903503823205729341329815935330444464968294413673234421583807616948312193331198190610961\n  4295220153617029857510559432646146850545268497576480780800922133581137819774927176854507553832876887\n  4474591593731162470601091244609829424841287520224462594477638749491997840446829257360968534549843266\n  5368628444893657041118177938064416165312236002149187687694673984075171763075168498563592014868929431\n  0594020245796962292456664488196757629434953532638217161339575779076637076456957025973880043841580589\n  4336137106551859987600754924187211714889295221737721146081154344982665479872580056674724051122007383\n  4592715757277152185899469481179406444663994323700442911407472181802248258377360173466853007449855647\n  1542003612359339731291445859152288740871950870863221883728826282288463184371726190330577714765156414\n  3822306791847386039147683108141358275755853643597721650028277803713422869688787349795096031108899196\n  1433866640684506974207877002805093672033872326296378560386532164323488155575570184690890746478791224\n  3637555666867806761054495501726079114293083128576125448194444947324481909379536900820638463167822506\n  4809531810406570254327604385703505922818919878065865412184299217273720955103242251079718077833042609\n  0867942734289557355592527238055114404380012390416877164451802264916816419274011064516224311017000566\n  9112173318942340054795968466980429801736257040673328212996215368488140410219446342464622074557564396\n  0452985313071409084608499653767803793201899140865814662175319337665970114330608625009829566917638846\n  0567629729314649114937046244693519840395344491351411936679333019366176636525551491749823079870722808\n  6085962611266050428929696653565251668888557211227680277274370891738963977225756489053340103885593112\n  5679991516589025016486961427207005916056166159702451989051832969278935550303934681219761582183980483\n  9605625230914626384473862960398489243861872985077759287927220685548072104978176532862101874767668972\n  4884113956034948037672703631692100735083407386526168450748249644859742813493648037242611670426687083\n  1925040997615319076855770327421785010006441984124207396400139603601583810565928413684574119102736420\n  2741637234882145241013477165296031284086584197879511165115298278146203791398550063999603265912485253\n  0849369031313010079997719136223086601109992914287124938854161203802041134018888721969347790449752745\n  4288072803509305828754420755134816660927879353566521255620139988249628478726214432362853676502591450\n  4683776352825876521391564809721419296755493843755826002531685363567313792624758780494459441834291727\n  5698837622626184636545274349766241113845130548144983631178978448973207671950878415861887969295581973\n  3250699951402601511675529750575437810242238957925786562128432731202200716730574069286869363930186765\n  9582513264991459502609170693475194089753574640168308117988464524736189560564794263580705625632811892\n  6966302647953595109712765913623318086692153578860781275991053717140220450618607537486630635059148391\n  6467656723205714516886170790984695932236724946737583099607042589220481550799132752088583781117685214\n  2693347869218952406226579210436203488529262679840139532164587911515790504605797108389833718640380244\n  1751134722647254701079479399695355466961972676325522991465493349966323418595145036098034409221220671\n  2567698723427940708857070474293173329188523896721971353924492426178641188637790962814486917869468177\n  5917171506691114800207594320120619696377951032270890295660855622254526026104607361313688690092817210\n  6819861855378098201847115416363032626569928342415502360097804641710852553761272890533504550613568414\n  3775854429677977014660294387687225115363801191758154028120818255606485410787933598921064427244898618\n  9616294134180012951306836386092941000831366733721530083526962357371753307386533382048421903081864491\n  8409372394403340524490955455801640646076158101030176748847501766190869294609876920169120218168829104\n  0870709560951470416921147027413390052253340834812870353031023919699978597413908593605433599697075604\n  4601342424536824960987725813110247327985620721265724990034682938868723048955622532044636026398542252\n  5841646432427161141981780248259556354490721922658386366266375083594431487763515614571074552801615967\n  7048442714194435183275698407552677926411261765250615965235457187956673170913319358761628255920783080\n  1852068901515047133403861003100559148178521103847545429333891884441205179439699701941126951195265649\n  1959418997541839323464742429070271887522353439367363366320030723274703740712398256202466265197409019\n  9762452056198557625760008708173083288344381831070054514493545885422678578551915372292379555494333410\n  1744201696000906964156127322977702212179518683763590822551288164700219923488640439591530184640047143\n  2118636062252701154112228380277853891109849020134274101412155976996543887719748537643115822983853312\n  3071751132961904559007938064276695819014842627991221792947987348901868471676503827328552059082984529\n  8062592503521284519259279865935061329619467962523739725655841578537445675589980324054921869628884903\n  3256085145534439166022625777551291620077279685262938793753045418108072928589198971538179734349618723\n  2927614747850192611450413274873242970583408471112333746274617274626582415324271059322506255302314738\n  7592517247873228814914559156050363345754242337791603749525024930223514819613811625639114156103268449\n  5807250827343176594405409826976526934457986347970974312449827193311386387315963636121862349726140955\n  6079920628316999420072054811525353393946076850019909886553861433495781650089961649079678142901148387\n  6456821749140756237676184537751440314754112067601607264605568592577993220703373333989163695043466906\n  9482843662998003741452762771654762382554617088318981086880684785370553648046935095881802536052974079\n  3538676511195079373282083146268960071075175520614433784114549950136432446328193346389050936545714506\n  9008644834401804283633905135781572739733345372842633721740657757710798305175557210367959769018899584\n  9413019599957301790124019390868135658553966194137179448763207986880037160730322054742357226689680188\n  2123424391885984168972277652194032493227314793669234004848976059037958094696041754279613782553781223\n  9476461478329269765451622902817011004378460387565441517394339600489153188175766505009516974024156447\n  7129365661425394936888423051740012992055685428985389794266995677702708914651373689220610441548166215\n  6804219838476730871787590279209175900695273456682026513373111518000181434120962601658629821076663523\n  3617740078377834237091526440630540718078433580610729611055500204151316963730468492133568372654003075\n  0982908936461204789111475303704989395283345782408281738644132271000296831194020332345642082647327623\n  3830294639378998375836554559919340866235090967961134004867027123176526663710778725111860354037554487\n  4186935197336566217723592293967764632515620234875701137957120962377234313702120310049651521119760131\n  7641940820343734851285260291333491512508311980285017785571072537314913921570910513096505988599993156\n  0863655477403551898166733535880048214665099741433761182777723351910741217572841592580872591315074606\n  0256349037772633739144613770380213183474473011130326702969173350477016321066162278300272692833655840\n  1179141944780874825336071440329625228577500980859960904093631263562132816207145340610422411208301000\n  8587264252112262480142647519426184325853386753874054743491072710049754281159466017136122590440158991\n  6002298278017960351940800465135347526987776095278399843680869089891978396935321799801391354425527179\n  1022539701081063214304851137829149851138196914304349750018998068164441212327332830719282436240673319\n  6554692677851193152775113446468905504248113361434984604849051258345683266441528489713972376040328212\n  6602535166939140820499473204860216277597917712347510975024030789357599377150950217516935558270725339\n  1189233407022383207758580213717477837877839101523413209848942345961369234049799827930414446316270721\n  4796117456975719681239291913740982925805561955207434243295982898980529233366415419256367380689494201\n  4712413405250722040617943552525552250087487900865683145428351677505422948032747830440564385815919526\n  6675828292970522612762871104013480178722480178968405240792436058274246744307672164527031345135416764\n  9668901274786801010295133862698649748212118629040337691568576240699296372493097201628707200189835423\n  6903641492702369619385473724803298550451120891928798298744678641291594175316756025334353106267452545\n  0711418148323988060729714023472552071349079839898235526872395090936566787899238371257897624875599044\n  3228895388377317348941122757071410959790047919301046740750411435381782464630795989555638991884773781\n  3413470702467473621120489862269918885174562517325193413520381158633501239130544419100736284475675141\n  6105041097350585276204448919097890198431548528053398577784431393388399431044446566924455088594631408\n  1751220331390681596592510546858013133838152176418210433429788826119630443111388796258746090226130900\n  8499754303957712432306169062629194039214397402708947776637024881554993224588259790206312574369109463\n  9325280624164247686849545532493801763937161563684785982371590238542126584061536722860713170267474013\n  1145261063765383390315921943469817605358380310612887852051546933639241088467632009567089718367490578\n  1630851581381619668822220475704375906143380407258538620835651769984267745231958241826836982701602374\n  1493836349662935157685406139734274647089968561817016055110488097155485911861718966802597354170542398\n  5135560018720335079060946421271143993196046527424050882225359773481519135438571253258540493946010865\n  7937980586201433660788252197178090258173708709164604527279771535099103407364250203863867182205228796\n  9445838765294795104866071739022932745542678566977686593992341683412227466301506215532050265534146099\n  5249356050854921756549134830958906536175693817637473644183378974229700703545206663170929607591989627\n  7324230902523974438610142630986877339138825186843165010279649114977375828889134503411488659486702154\n  9210108432808078342808941729800898329753694064496990312539986391958160146899522088066228540841486427\n  4786281975546629278814621607171381880180840572084715868906836919393381864278454537956719272397972364\n  6516675920110579956639625985355127635587681402134098290162968734298507924718460568748283313812591619\n  6247615690287590107273310329914062386460833337863825792630239159000355760903247728133888733917809696\n  6601469615031754226751125993315529674213336300222964906480934582008181061802100227664580400278213336\n  7585730190113717546727630590443531313190360924890972464279284555499134900051802957070829190525567818\n  8991389962513866231938005361134622429461024895407240485712325662888893172211643294781619055486805494\n  3441034090680716088028227959686950133643814268252170472870863010137301155236861416908375675747637239\n  7631857570381094433905645644685241830281481079983769185121272019350440418046047216269394457883770901\n  0597469321972055811407877598977207200968938224930323683051586265728111463799698313751793762321511125\n  2349734305240622105244234353732905655163406669506165892878218707756794176080712973781335187117931650\n  0331555238224877306534441794534153952024244497034101208740721881093882681675120422994049481794494727\n  3289477011157413944122845552182842492224065875268917227278060711675404697300803703961878779669488255\n  5614674384392570115829546661358678671897661297311267200072971553613027503556167817765442287442114729\n  8816148027052438068176535732755786025058470840132088379328160087690813004924914736825170353822196190\n  3901499952349538710599735114347829233949918793660869230137559636853237380670359114424326856151210940\n  4259582639301678017128669239283231057658851714020211196957064799814031505633045141564414623163763809\n  9044028162569175764891425697141635984393174332702378123369380430128926263753826677950341693343236075\n  0024817574180875038847509493945489620974048544263563716499594992098088429479036366629752600324385635\n  2945844728944547166209297495496616877414120882130477022816116456044007236351581149729739218966737382\n  6472047226422212420165601502849713063327958143025160136948255670147809357908896571349261581613469018\n  0696508955631012121849180584792272069187169631633004485802010286065785859126997463766174146393415956\n  9539554203314628026518951167938074573315759846086173702687867602943677780500244673391332431669880354\n  0732323882818475010516413311895370364884226902704780527424906034920829547550540034571601840725745369\n  3814553117535421072655783561549987444748042732345788006187314934156604635297977945507535930479568720\n  9316724536547208381685855606043801977030764246083489876101345709394877002946175792061952549255757109\n  0385251714885252656710453498134198033906415298763436954202560802776144219143189213939088345431317696\n  8510184010384447234894886952098194353190650655535461733581404554483788475252625394966586999205841765\n  2780125341033896469818642430034146791380619028059607854888010789705516946215228773090104467462497979\n  9926271209516847795684825833414022664772108433624375937416105367340419547389641978954253350363018614\n  0095153476696147625565187382329246854735693580289601153679178730355315937836308224861517777054157757\n  6561759358512016692943111138863582159667618830326104164651714846979385422621687161400122378213779774\n  1312689772667129920259220174087700769562834739322010881593562862819285635718933849588506038531581797\n  6067947984087836097596014973342057270460352179060564760328556927627349518220323614411258418242624771\n  2012035776388895974318232827871314608053533574494297621796789034568169889553518504478325616380709476\n  9516990862471000197488092050095219436323787197648703392238115403634754886268459561597551937654101150\n  1406700122692747439388858994385973024541480106123590803627458528849356325158538438324249325266608758\n  8908318700709100237377106576985056433928854337658342596750653715005333514489908293887737352051459333\n  0496265314151413861244379358850709446880454869753581702129084907873478068143663233228194158273456713\n  5644317153796781805819585246484008403290998194378171817730231700398973305049538735611626102399943325\n  9780126893432605584710278764901070923443884634011735556865903585244919370181041626208504299258697435\n  8170981338940459344719374938776242324098528327622666049423851297094532455862521036008292866497241749\n  1914198896612955807677097959479530601311915901177394310420904907942444886851308684449370590902600612\n  0649425744710353547657859242708130410618546219881830090634588187038755856274911587375421064667951346\n  4875867715438380185213482819158124625993351601989355951679689328522058247994210345127158771633452229\n  9541883968044883552975336128683722593539007920166694133909116875880398882886921600237325736158820716\n  3516271332810518187602104852180675526648673908900907195138058626735124312215691637902277328705410842\n  0378415256832887180469879525130732663402785190594173389203585403956770356113293544825856282876106106\n  9822972142096199350933131217118789107876687204454887608941017479864713788246215395593333327556200943\n  9580434537919782280590395959927436913793778664940964048777841748336432684026282932406260081908081804\n  3909145563519368560630450891422896452199877988493474777291327972660276584016678901364905087411421268\n  6196986204412696528298108704547986155954533802120115564697997678573892018624359932677768945406050821\n  8838227909833627167124490026761178498264377033002081844590009717235204331994708242098771514449751017\n  0556430295428218196700092025156158441742059336581481349026931115170938722600264586305613256057925609\n  2733226557934628080568344392137368840565043430739657406101777937014142461549307074136080544210029560\n  0095663588977899267630517718781943706761498217564186590116160865408635391513039201316805769034172596\n  4536923508064174465623515239290504094799531840748621512105618338545661766526063937136588025216662235\n  7613220194170137266496607325201077194793126528276330241380516490717456596485374835466919452358031530\n  1969160480994606814904037819829732360930087135760798621425422096419004367905479049930078372421581954\n  5354183711293686584305538427176280352791288211293083515756565999447417884383815651484342298587042455\n  9243469329523282180350833372628379183021659183618155421715744846577842013432998259456688455826617197\n  9012180849480332448787258183774805522268151011371745368417870280274452442905474518234674919564188551\n  2444213377835214238659799259882032870851093383868299065719946149062902574276860388505110326385445404\n  1918495886653854504057132362968106914681484786965916686184275679846004186876229805556296304595322792\n  3051616721591968675849523635298935788507746081537321454642984792310511676357749494622952569497660359\n  4739624309953433104049942096778838270027144784940690370732491064441516960532565605867787574174721108\n  2743577431519406075798356362914332639781221894628744779811980722564671466405485013100965678631488009\n  0303749338875364183165134982546694673316118123364854397649325026179549357204305402182974871251107404\n  0116114058999110930624923128131163405492625713567218186289327861388337180285350565035919527414008695\n  1092616754147679266803210923746708721360627833292238641361959412133927803611827632410600474097111104\n  8140003623342714514483334641675466354699731494756643423659493496845884551524150756376605086632827424\n  7941360628760412906449138285194564026431532258586240431418386695906332450630003922131926476259626915\n  1090445769530144405461803785750303668621246227863975274666787012100339298487337501447560032210062235\n  8029343774955032037012738468163061026570300872275462966796880890587127676361066225722352229739206443\n  0935243272281008599730951325286306011054979156447918450046180467624089289256809129305929606423570210\n  6152464620502324896659398732493396737695202399176089847457184353193664652912584806448019652016283879\n  5189499336759241485626136995945307287254532463291529110128763770605570609531377527751867923292134955\n  2451330898679691651290738413021675732386375758200803635757280027544903279530799007994425411087256931\n  8801466793559583467643286887696661009739574996783659339784634695994895061049038364740950469522606385\n  8046758073069912290474089879166872117147527644711604401952718169508289733537148530928937046384420893\n  2997711258568408466083399340456890267875160087754612679880154658565220612109534907967073655397025761\n  9943137663996060606110640695933082817187642604357342536175694378484849525010826648839515970049059838\n  0812105221111091943323951136051446459834210799058082093716464523127704023160072138543723461267260997\n  8703856570919985075956346132484601884098501942876879022687345565005191215465440638292538512763176639\n  2205093834520430077301702994036261543400132276391091298832786392041230044555168405488980908077917463\n  6092439334912641164240093880746356607262336695842764583698268734815881961058571835767462009650526065\n  9292635482914990457683072108932458570737016607173981944850288426039636607460311847862258310565808708\n  7030556759586134170074540296568763477417643105175103673286924555858208237203860178173940517513043799\n  4868822320044378043103170921034261674998000073016094814586374488778522273076330495383944345382770608\n  7607635420984450083062476302535727810327834617669705442871553153400164970766571959850417481990872014\n  9087568603778359199471934335277294728553792578768483230110185936580071729118696761765505377503029303\n  3830706448912811412025506150896411007623824574488655182581058140345320124754723269087547507078577659\n  7325428444593530449920700145387489482265564422236963655441942254413382122254774975354946248276805333\n  3698328415613869236344335855386847111143049824839899180316545863828935379913053522283343013795337295\n  4016257623228081138499491876144141322933767106563492528814528239506209022357876684650116660097382753\n  6604054469416534222390521083145858470355293522199282727605748212660652913855303455497445514703449394\n  8686342945965843102419078592368022456076393678416627051855517870290407355730462063969245330779578224\n  5949710420188043000183881429008173039450507342787013124466860092778581811040911511729374873627887874\n  9074652855654347488868310641100510230208751077689187815256227352515503795324448577872776170019648537\n  0355516765520911933934376286628461984402629525218367852236747510880978150709897841308624588152266096\n  3551401874495836926917799047120726494905737264286005211403581231076006699518536124862746756375896225\n  2991164960668765082617341784847893372950567390078786179253514406210453662506404637288156982323175005\n  9626108092195521115085930295565496753886261297233991462835847604862762702730973920200143224870758233\n  7354915246085608210328882974183906478869923273691360048837436615223517058437705545210815513361262142\n  9118156153017588825735948925071088792621286413924433093837973338678061317952373152667738208580247014\n  3352700924380326695174211950767088432634644274912755890774686358216216604274131517021245858605623363\n  1493164646913946562497471741958354218607748711057338458433689939645913740603382159352243594751626239\n  1886853078228217639832373061802042465604775279431047961897242995330297924974816840528937910449470045\n  9086499187272734541350810198388186467360939257193051196864560185578245021823106588943798652243205067\n  7379966196955472440585922417953006820451795370043472451762893566770508490213107736625751697335527462\n  3029430312035962609534235743972496592110106578178261087453188748031874308235736991951563409571627009\n  9244492974910548985151965866474014822510633536794973714251022934188258511737199449911509758374613010\n  5505064197721531929354875371191630262030328588658528480193509225875775597425276584011721342323648084\n  0271433563675420463751825525249443296570438613878659019657388028684018940876728167141370336617326501\n  2057865391578070308871426151907500149257611292767519309672845397116021360630309054224396632067432358\n  2797889332324405779199278484633339777737655901870574806828678347965624146102899508487399692970750432\n  7530299728722973279344429886464127253481606037797072982991730292963086958019963124133049393504933254\n  1235507105446118259114111645453471032988104784406778013807713146540009938630648126661433085820681139\n  5838319169545558259426895769841428893743467084107946318932539106963955780706021245974898293564613560\n  7889834724199794785643620420946134123876131988653523583129968622689486084084566556068769545012744866\n  3140505473535174687300980632278046891224682146080672762770840240226615548502400895289165711761743902\n  0337584877842911289623247059191874691042005848326140677333751027195653994697162517248312230633919328\n  7079838007484857265161234349332733566644733585564302352808839243482787608861649432893991663992104883\n  0784777704804572849145630335326507002958890626591549850940797276756712979501009822947622896189159144\n  1520032283878773485130979081019129267227103778898053964156362364169154985768408398468861684375407065\n  1210390625061281076637990479088796747780697384731704752534421563903872012388063236880370179493089549\n  0077633152306354837425681665336160664198003018828712376748189833024683637148830925928337590227894258\n  8060087286038859168849730693948020511221766359138251524278670094406942355120201568377778851824670025\n  6517085092496237477268136942843500629388144299879053010562173754591826799732177350293689280652100253\n  9626880749809264345801165571588670044350397650532347828732736884086354000274067678382196352222653929\n  0939807367391364082898722017776747168118195856133721583119054682936083236976113450281757830202934845\n  9829250008956826302712632958662921476531422333517930933879513570953463771836840924444220963193312956\n  2030557551734006797374061416210792363342380564685009203716715264255637185388957141641977238742261059\n  6667396997173168169415435095283193556417705668622215217991151355639707143312893657553844648326201206\n  4243380169558626985610224606460693307938478588143674070005997697036490192733288261353293631124036506\n  9865216063898725026723808740339674439783025829689425689674186433613497947524552629142652284241924308\n  3388103580053787023999542172113686550275341362211693140694669513186928102574795985605145005021715913\n  3177516099578655519818861932112821107094422872404424811534060558959583558152320121846058205635926993\n  0347885113206862662758877144603599665610843072569650056306448918759946659677284717153957361210818084\n  1547273142661748933134174632662354222072600146012701206934639520564445543291662986660783089068118790\n  0908152950636267820756143888157813511346953663038784120923469428687308393204323338727754968052103028\n  2154432472338884521534372725012858974769146080831440412586818154004918777228786980185345453700652665\n  5649170915429522756709222217474112062720656622989806032891672068743654948246108697367225547404812889\n  2424718543236057534116728507575520571311566979545848873987422281358879858407831350605482905514827852\n  9489112190538319562422871948475940785939804790109419407067176443903273071213588738504999363883820550\n  1683402777496070276844880281912220636888636811043569529300652195528261526991271637277388418993287130\n  5634646882273982887631986457098363089177864870866761854856800476725526754147428510281458074031529921\n  9781455775684368111018531749816701642664788409026268282444825802753209454991510451851771654631180490\n  4567985713257528117913656278158111288816562285876030875974963849435275676612168959261485030785362045\n  2745077529506310124803418045840594329260798544356200937080918215239203717906781219922804960697382387\n  4331262673030679594396095495718957721791559730058869364684557667609245090608820221223571925453671519\n  1834872587423919410890444115959932760044506556206461164655665487594247369252336955993030355095817626\n  1762318495619064948396730020377638743693439998294302091470736189479326927624451865602395590537051289\n  7816345542332011497599489627842432748378803270141867695262118097500640514975588965029300486760520801\n  0491537885413909424531691719987628941277221129464568294860281493181560249677887949813777216229359437\n  8110044480607976724292762495107841534464291508427645200020427694706980417758322090970202916573472515\n  8290463091035903784297757265172087724474095226716630600546971638794317119687348468873818665675127929\n  8575016363411314627530499019135646823804329970695770150789337728658035712790913767420805655493624646\n  4126002437968454377733902647251281941632007684873625176406596754069362175887930785591647877727473927\n  2002910342949562447661308200729250734529170764226621047673037863169954237455117456522022783324096803\n  5246676631908610112067458562873174135111622920788651329412448154716281820798771683463413223622341177\n  8823102765982510935889235916205510876329808799316517252893800123781743489683215159056249334737020683\n  2232100118637395770567473867102173212375224325241626358034376253606808669163571594551527817803921774\n  3228234366337728111863905118930759016666507429527583840085446354193171905313636597249051584091065822\n  0181473479902235906713814690511605192230126948231611341743994471483304086248426913950233671341242512\n  3864026657258130943967621939655407386524229897879782198637918299709557924747320303239116410445906907\n  9778623155183495930353059237898175158914576504080251094791234217584828418819501385461656803017550355\n  8005494489488487135160537559340234574897951660244233832140603009593710558845705251570426628460035440\n  2823678768550982678161765520375795655481677896038927498355608791541177749423573400764161093294003899\n  9821992672570869573260687749742248020233075251876502559684207606932299885875798988964607443817881700\n  8154889522651672283404527721910699141576463948523112679473086580319507645519767562895742888179681209\n  0026387145257858315277615109088631740243695680567873015235427804793414266495223833707117511265375503\n  9423720987846680491394734465307140796225972871305030772587148755705025825734668666138023514260561161\n  9740554343654869800544487929597028759035225840978268359866644658604569424139072909526624993290297344\n  0568160683805726626057277088407073471496060064561454070734432782514087474275506722304845357006092214\n  3900029929816082117170479176145051910081326703752149307405678533111060583529127810073917499491978451\n  1291591368110739405517520801963053935074024850955377250036705466516233043042508744232426240463211507\n  8997336929985407041656261041976700202415094892411856092409637604429612002364590706449770627207919019\n  2359648070489236369798601982830872842285647523531628827913242955248144475055219096720460806895451817\n  1220493032185374062724742151974030576904360268636078079200477623242955182947352202724437633902772139\n  2087767065716241639751785859254426923428535274328856336850789651962072519416556061870370550218462845\n  4342578503830000953745182929584404649188386857934839611512971605816657450967036774958366666931218817\n  6367964494361713041603724305065848513174926405585519401800518090847521186822461697614924323831948643\n  4415908558011073070311201502243416073157929528752936835820397003389112114170685219366589789459503154\n  3895890153038271430019295890741499435928940830970770783628759144840370450386189669758112018523192318\n  6865996803858381237032915620757883594878094168820553160512819015264759280757495815456422134145937816\n  7056992868299895611982353837157880480478704584175394665497690173220310890070303362911767308448450372\n  1456696444014695451738574341578101586187838392785526093991305702555755590609470514980934877733200727\n  9757303824598946680968082222134848587382299928179409082566520958165547247524456674369759447468637633\n  2428904269776106791933910983300422310293728298798903209391092682836306173610173878123679898645149311\n  7024371282858826304862988844922074156406071470591374055246657569718702173552872454394277148091793644\n  3765063786186132434863579741125852086345992780368879249835436329845768765016506511534500869572123950\n  7544785683173631557153527046524235259737513408825461609661440746675514226836031959801072152463551069\n  1718713357316854856312808578344356236709596509499469688206611851180860342028213318012494109915026014\n  3545001743273079362511307029825049941799428445114647932915459955590958780762163666859179106543596606\n  5253525320273650725989121255686842802077246487722010996631829559552903393312284364864475973560859840\n  7609472983895424339326231532399189818522641808312963335463568748288634656185048106322888055967378445\n  6200094146560349928087940511531005758712955257196411150685034077371060438037125957559698594936205847\n  7512026354947347534748189262254190352671614429284899857536740692165271630086060654373736823556588626\n  4863436891532180955722044567771373683104580755845296128328326063196297285279666743629748008213186279\n  2186904428434263073576070399966943078950814726973025381737569492275179535432615691204059483286094999\n  2366412287881226419148504856328072066418557059520375030322916894489427578306090910852410601400683274\n  2055839697738231507349961087587637042555649640868550719422563449667324306562592504745817627332818160\n  1701969816654242637876360145303594653845032547667499973734083566513818602515652028363738917101654541\n  4882674448009105704186162626837971120886141357279611099088292970229692128180978798951391504270936786\n  4449831964201345668339087759430064424856230121246145116979219396344095080832292812942704365991464827\n  4998437594211302041829730841717881309037955854560324717081919530277146579455547554475428443440813938\n  8908609776017857389307518661906505018077165001840744325854024184360501118242990702323417243674525365\n  3495947990633345407543718126993998337192184854187359798453489345922685150681826624900780293350126588\n  2497422624188535252663670282766249934982948874833106176420842901692305289960897860413006510902817980\n  5040587107671179041130217482796682353001960220253185576789843317586806378359968791601538922220236575\n  7655815866114091993948615992091599175533417830333476431316350127053906970793265678124159064342847213\n  6023521823674121473312449994433415591527431593168747788253315509277033620290122259779480985539220006\n  4527162280855398278906584233447552821276517650572663267691141075034845871896996434875775138479148183\n  6351006214668185850963488870814569767220201679911994624177766889079171368659459607264685388107787830\n  0216136827669702622345941873747673353799888440342704680304255169412715873932039844437460454781611305\n  6625176412759821181939661101850562880555942566060032312116180994622129301002470913347150682268430458\n  6803009042428616820255621409460879000651910994955708158165058289833407394660844575657806366902728434\n  6201858732825292479650528668140850353851983752363745192562279549029055790703028395010485483592983454\n  2814487304358047053315081510503001521428117175393649133166172621235405527863308002083177055630294963\n  5942016543330940941771963262341193871051615701017980535516793708602913667569860971241203685838129576\n  9530779814136570017476135696698614606849143969957383763169582460251334210807262171360194301808720988\n  8551415024163818325975259593165531865833117126857941527206612218422661411825154657484878312610347834\n  5467492583087299854474212064450952332450508774314961665552517971680209917200264093749219075699368963\n  3028139164720896358177173555584859270652450486251641954055080134351032338981337830249770182275490638\n  1499964723334079613041469739476372650869273347108415685608430921316240434629863920841660055904598506\n  4912435052647660676003444416181864036700837741141010943205889555986586700778636718969440896223213740\n  3411359719913313594655368544669236765258901210841377743248219181274784789228726489297003237187345615\n  7981599834839100412601050746964599430331978810634913923812490503061433407918328004063907098672596197\n  0983112659601474737253305268537177421465540058739246237276173649051987133680677239525707813606866832\n  6139501432950947485159472466752720168431658660880751276858475554118438116901162200555211348448896066\n  8259227431319007963011587084670117654935393046563356225311244727796669005831190616101972663073970542\n  5314398184573794494867801346182178759390769996020290839656772878469057364015640150476964489939475414\n  7460833991869688927115694234549265124664550779255402810503762203596753055860185649205606287909076945\n  3339208808849477828894851122154743230191383245562993881020614490266876010207753210915684977830740859\n  6498579671526170100394754945399176987913235465501064073558169994097562481499674432784292027626441897\n  9391815839456270817330158216022551965989876937616401986120746675504886111085572676450705262244613022\n  2335852072273620485057289238815884938754535229186399714380884061757286220950122506515863104258884134\n  3554319737298562177530720226294755524830444453404348888785811703413453425223543194078779728467601815\n  8322709774518092934219318981581248283265895004070485520609989378390034191416304463916388054965878650\n  1375046341695655156618298878630705842306967660254053024811471007899784211830489010464056896539702885\n  5955309255586360521589573751140895649058441567749371058596480143158746144912505492531911646538215851\n  9737009328019453032057262845265804604633781663142993307664664653076059054896288872418971606022588261\n  7577539922055131509377200624863085562820493575752724995567089221634233983602565328731029194007041176\n  9192208500151167356701019589710017970195781208929109694177543699043682025630240548226254019056965077\n  1058157424072149633956036527028333440730575007367456226058464988611510168961218111905847171446106871\n  9761017456587373796740697137423238753839030317200200207205928488785123911746471673743737923283881966\n  2016876221913462338937625995270256721386221124589802121305014072889043003225355040958668187241393699\n  3819306914874471718664618311194260316166407037731648700186479960024304400324224180940227853330901150\n  9880870678268835317200767522553138008818780431690190072804831799287414125476123089606833095828377667\n  6882875786886830929760010119745338983319525886196301329170943858166153741717944963191771543125069598\n  5348128568461937766989427745917091880252001274990555940728969659479333167224362156789677696670803522\n  9039018485730806275670867658627104769409203565593025352743418965927002227049233186829991560936413757\n  0049885373045963961527346293969749517480626964517930187199867885375814159757993148066085572325683743\n  0528276417567005028804048942989958094810353483393414492788592526219241554723199714338508663732092663\n  2728243514933640704589683852345624744361175256766987767597223439206357507471552918102762614012992480\n  4228839902978799254185174991296302839907296355885798905933177959087690739056460256235335672215522594\n  6883829845288292296627513716242217295467867071584092418408414755758253938524096330205134970474069539\n  9567897981727860920462286839735779815111868152659884606949758965481314651150392626377749513761557248\n  1951161198772503445647107385134359273555387124623755981938132142384415819290700463897716838872079163\n  6174143249707910965816274642971707287172514274589835689709553462682016908535610894489840710058192030\n  2176945120771774588795519510473384184739980796306767885845167575729904306971542642383498009870869933\n  6709121083944535062459224323123482785496603746571880148929379451478705406079245759006012196221239287\n  2001721558866634573497140953372115165598575794172441988902616701610161155783431502546032878119842402\n  7484608510722406676778760855247617773833089502610064388350550205456324346167859451941795669874968515\n  2448838475136181806671083161655642093692705206118985172926171417144346555087063060635510129494003097\n  5916779915842604919712095432270267843265429657240327208871432199964531320258710967716512854966996255\n  2698607311763718207498827399770601991362093083230736838206455732563765982912578131492224220427971241\n  4416299512659456397927593803838047826231604243253991328511230322470375619423217330478540785762440132\n  9171799297924078339071575798142681686465538294684739920588863165593491986789696284044734496802407709\n  2831376408103352255242717404107673565424441004483347440101726441052954787296345898640501203608024451\n  1903509949744939736171815752770937802092366681358416362683192634067141827974213425462207054156000509\n  5967404561684045177174795279035325493258912048338574659009678173041600052108893461076875400424197780\n  3082885181200173369559127137714195011361304409753279190504891583246399143483531648681548579178632935\n  1239255525102111827885736960602769313014696614334496423021143824837056335327938588952676720766889712\n  7443581563208810665014956814355879657690985776590276870745365927636497555344961730807816098710324801\n  3795136170367763457594975686208013996374551762425147780628722265971455482906769295713643572152674468\n  9878894188207512922257565091435528288746141950978624275278815715664007637210378031940430958442725492\n  6998716923433189002214150311399876526068876156674021019720171960239086108297492763956954115303227546\n  0173870795625993579785302443476716399591462317931239989986928437975702492369551587297683854005227651\n  4956144471059719628898881571094151717015181147435136438540051162462021311748007919837497001004713634\n  3252328157891135545045337190527506822915618500332846956792622620819044247334036250389279207158596003\n  9363153368842724375366799698647934741133198328619441460653922784099903143840354565047056789552024827\n  1760118743356436902435030856313095590552503904927316133117349225846446090245350791901844112993216997\n  7045183285358648042855682220873721361649058630325636891308410376021567992702000532235543980465311933\n  9775459044045078568021398465009693429547310269249947586466058091669984160684646087293943808274308285\n  8174796941728729903110131926755738979840913642534796949434803777033646349584768629825901034707278612\n  1862300198660798778268424593383563891957020685352160321163523006498874460020017041305698536515466875\n  2023859375183280372851143274811699683692849220447380570633496618711240947835915869626858643589141359\n  8542535776887749327436345147544886408688180303696524317556883002058607732569597160864854158344684324\n  8996307701137134467515693024488548207712413355773230694945806726784523594363150787272815790157307003\n  3178796854436279525719023623274614262868732738009497741122856237663214904653294072026197539071740422\n  2595392428881645597965700309571413891069368450362682310539867437532400527015347458933256795149418545\n  3780882706345729596216908538353537038141811557381637820903256151986974535764641212549807600515614170\n  7298046994813593483150568116642793219335279822714715767340186088721518799669350252700757556099719882\n  8630642854481282751392806947027501481632897273143473485285295046048832716739789815636788047804436021\n  0900732072736974934463049973144257156043313369038761810094887312071348271081588985748326585420751007\n  7953118326861708037070935927614936782530858340482351003632166378957426202550350116861543407379504516\n  4828967556983589355220201736795480757819095026979812711487034311903631122461282953038205128704309294\n  7197459469082102563478899543177152437969621128122450342606639926885213307919637027778044885792057304\n  6990800923440186638113252097123096476059989947925759851008173039606822219975327301606582628527582576\n  6950785472603493829813358252817867060851265600226887178112535978293373477914127362841886561759208328\n  7944741096970387985473698402545806329483502235939354358748022398976091629625011047393116944910066690\n  7230634693130169711820632535269244043840093724284428209709364856909468920087371753252557030543539828\n  7278123011398080938670154748858034456318713196026785487938933162050076752641120443902375833427242986\n  9965478636853410284885737025472550236566341868091903838867078790720840361940216467012153483797815183\n  2826472578628815207101081499558980338118961569441756761340717046538512170902123777884333649651872119\n  9054075818773943975283641439530442459139031788130041887918871145531482674699870555879310402403888840\n  8385068734162507165727418513495208496367095554245043948394804597915622828248378793415272036226336956\n  1805556371076814888893619275742659935823559431530887933052767558747512365065843969475604297192002319\n  8680243517199378681003611023125683642560795974105741536282971800464977485737183786390370390153973749\n  1165468549971645394161121641761071714540176519056505252066227788312904571969320599024137539598386198\n  2603205495839501675552509644137118222561496014003023035407899209698677507867200038074267970530307167\n  9322960156486228085184033523501706085895129122232461178302531636289439460736527713365116316464461990\n  9902122492241231516899276785586373631552600250348848781323300191018939961670273141699962651194574263\n  6761965002434737172729028462209798394871065982270009954918877696188505432653211802219444282228425152\n  5561411874340180419461413945147128725275923912559644373568339728963312676782349103563329612947191015\n  1571431157954909339032614119186547523762472153110207936911584874220582274734320173558507712243796985\n  7965491580627950274097716886114807616315161855306856692457171769220443668433127398933794111629722451\n  6999854685622157024175947117699529165502116855001089857619346394559088262707753114657752238846343519\n  3765397349848024549760760244030808448901068387869726123709783578245166801171485983679405529046198262\n  1656691720274262854823933960018254599409254308169691032978411234022885600190549342750223185294712829\n  6096939768137341977042781213001473286776057194059699792755124617184349569856417128724811834654206423\n  1871455182415286763056751311626771773506175112454633879942652912701057899567180572143655791835069177\n  7930704075732904397494995822410623810514917650238504182730096620171750940590805408957283755406355152\n  2199658207573513157075923615398639459211155864000988097552610538382568992721584785041746065161511337\n  8833609760121148487005560165812492470682568442720454728963094203066504452986462235942260085549915891\n  4995360649842803457949275700949795945060237877501947062463239495495782308228306684081880252107663907\n  4230973720916285337176806216446935432317917855305833171420847988630340846572642693955700268576057539\n  3478885870946005827232305191081175142349126873365859607998917329289158960018150918163374008060354752\n  0005151175102901229924870961545928026206076169827218102916731554892942374085196743307916607849905578\n  2101935713662435990883613859808516156417476946054785540081953530670803089697630452946868233210532878\n  2374389441156851762717116363094014799096494563545929501307390036268210073263700823561506912696431833\n  5171625439030469898931426154426359511363466057378654951244574752621678954703628904830484996804037722\n  5134319373734412366185869445880640185840731476337929403863404359194198723552630156546080518686760680\n  4316084512845916042441326987912538560299159967278766195195053176488313469325736689464438255813910848\n  6209663742674579831301222343872583124422033094571457541470479293875858238997738515213523723895596643\n  1223564326262860114748908681715928106687270840082033771869215352352692634722680908259898898400262081\n  5217828261122931311820866007099686036540981832680755824776706950410997586143624355216194535302920025\n  4667367996485043373133495208210751199258926638995647569858707901856123791578864374469037871509500112\n  5502100388453119236529655994619004748466206423479423296700605290037091755781887081935221468714272352\n  7763255989808694872111384598001412384216382782441273654244674883338167971620112886191415401936712909\n  4789902646664431560983729615019686242282506723061667209435465714251493086424887785986827595887490650\n  7726025095182953676518118236861694472436078376429476246922631949892196464406831692876616150605081384\n  6319415116202577907863071801231159458603896562526554223346234454507394788690268159497513116885143694\n  5210216883190446168629763325229863851818850049286935727647668238555646365544964006317648285575785866\n  6102285515648599088209586894443625469867952382268611596991005636608292679153375381606611224786953132\n  6158531871763885989377929188902998793879810003697307848959270625410484859315854323395683104239029907\n  0263443797875691855434089764407601308444819786265079476440830134942435834281885915259293471436317533\n  7495897010728735012707889804816350456766676932075530518404324461007403216764718360837084750651269307\n  0766084982529900031785030585368213951273503863824605642510337775580986464339801718620814266307417259\n  2226000511091342681074670129014301654101064933212283790827515001003530015654597508323772965439697382\n  0477416265710657408216499606262274961879533479070659889748717795643340648417456457479069251701494998\n  1009535341354890875483632757952240720698629102467170357925144176670388660990698572626058124082533622\n  5218992000418975745765315123000064445715931701771688635483333051921582055946117357716321132233931965\n  3203861990051161781713340010705766526899197081692022194647043237953564118660639205586090344570641517\n  9778214505472227885298721019785884607004742002846887379584422894997433365627187799172113791616449254\n  1329715652879529532639759538535920950138633380507561369530899547584883024261962758985941513780515805\n  0257675404017857958524488311721050892770892272734319738238846873071682302487886885855101080735227814\n  0537140652075810727084816726397709873145516264691142328610303693298433030032367616271426406758780673\n  1883971515002798163374779078775038307986759404591073921034587404219617034925808189907205961291586420\n  2028857340091149552388651079113714953346397639881839488045300750747403722809368205354304949519483328\n  3347007516197900868728543996298157560589163762472306916287111113767608648032375245966493041175394613\n  6464337804671165055504670671836221285795048067165630427626711429999113487698447050370637900181096888\n  6297217579517324338027806174704963020424929166191718862433555992820932439194457118863215563201616542\n  4705537593869662465633412154101403228699093015913288580883124124288287637387274283803859071029274863\n  3351503090445328052597795658920554562434297982794134891756382400771612173324736428540160610044337641\n  4572207859217155914010378320201321338330963807789040957238105588293927963743816606868351950592770195\n  1536160172215890428785678482068291944169871819286273082704441630396254713053284388337913374768735826\n  1221162583602728961624559041896770247453827583966522993712351630489833012421417455788591594256059792\n  4277218199085562798486056174536844789237969079755945551546468531630244623256740348958454622567448582\n  0204245739199425309426422450420268903815015268360241255980759752364816280930489127461511962315461140\n  0822056396780658535407668688227542650381225999162076017089556747446524234452017661650325945665912966\n  7863246213799192229614586714224824928806476803210864779941004100600339067927523736254602774296007347\n  8803835668752200348245769490845686269605771570191917489226063520812973879744383548328613693956245039\n  2976805783223402171676555917766840375723484409461762931288492689936871389838822271060279037990019045\n  5833600797392774109266557392331470259092338906543884223513241153880185592349561399302239196450504503\n  6935292701156630515335191864186482344249991927202729534595990630487236080415957600296681211168317236\n  6038110542803591445720248256456105714055462420821343520948108417158289572445072063546816002305120140\n  8480543587425261710176818538835575587174154247754497722214192613155252691091755633319323222432185254\n  2218272914915981058368970250352281300214119248601424806807975369964777193949068046835528083473276103\n  0604940973309169031678309793463661183278453186871646268073883365670456601042376850580139507443647963\n  9222841126979451347730049249878649656367949099291327125289776519181754279628060849323755208153611132\n  4033971316550439188796019838213858500077324246177884918758145964264233788979333081948816004011312652\n  5635693244659398400636890315254722923991414474377069633893576192603918924793631780083102611419548543\n  6051577871600495578865657970665885510428824663630572077789022667770425126815719795332251076389036819\n  7628440286102588053923393294746720240885412764923864476021611626208242129916603622991849237822363009\n  8347811952291382184732634228575912097980547828525059183798336801787411242644746002256241498069140074\n  0979721023278539575615128345806165411117926710427990579394497134946328950456512868847841871758020504\n  5832838748531373691135102550620102775345809439105001021833973245650472889476879298925945019875076712\n  2363791875864720121496606115128048709648863056228440839369443872169212084920085155838125107074195518\n  7208093746942459731172811721051928903896370394235776862127668210931827636649840421249381440979598631\n  1422543648396549998347908430702176438555435125743682822815303222238083476795111355701480631820045322\n  0723794891863572149106242526993994671015366846234105153338142684770627585203524099207972086991453730\n  1095516415033176282001969164115460268207236692552751418429969920539853433073068057372380504167197221\n  1273740507892726634063885068673445856077326664838457802771891147580132310551987841336521851907146068\n  1389868867103147598264611293795439526672867275994833590259744587868768496462683484434414135917714587\n  7660880778453571839329371937393236408356337576688468211117993505541020855618849010201600505639541687\n  4510822060355541081766646052412496622442280454524321603203601946413560979200195902404979292367329892\n  4553990101980112140290868699920575891777188074146122205024728585715367530747814389730571787268366360\n  1576136100772286319638852646235125538077319459563567965382362499926551804330796359621106745528521429\n  0262949826567553352731004687886573104724664933265679273313451229550591862329373933260860774513507753\n  0901574443829487339779605322849358301361837958626480321297368474817516476913662110360369509106666505\n  1717115082782009327883587225983940463068376318118089044236262199881236826807857952621972166872017455\n  1747262781803268305854880397097704793483103543985590784355277667603313988460527150313885633246768892\n  7104595851932895139167823857735772658100479825639355193520055204080028705967824973937478860528356493\n  5914978380377964960005212445834779001756042465866651998077028839438516380955043049219603244360903400\n  8517466042962743097683871519459826447359402342482110447572911177795877313415536095275957089861258677\n  1456252399450075938020609355024892008476733229308574222255020645569023912654366357852427242905605320\n  5754030821014512382090217466975797653475172501465837478848080537735150422224042957603613754324861996\n  5589193922050469998210629316096756517907513229607778575533102658584257608668676453552092774827556754\n  5177169950878941180593630524994496701237598006553499873966639539441701705969810151271933311840767923\n  2718539539809764048527846743872316432910029065495308612833302664007580129618499207022002555972156957\n  5883761687843643467927558635739722535648841330601192895746428093578580811323314331152874821797660397\n  1257952890036407198923328131611640416937736628013259738222237426818917648959642270338039059295964969\n  6482133114473166765041976781108490966469425717069457007871264014486522428469488976172567465352205061\n  6210730010192624831468212035516995015220073163840041320303332423121670826854689317584366304307843507\n  8592810447849266395265239871864417338008568169232134742975458326940216125333283790096064862778549412\n  6679513674045877416945596140762656625029900692267267876036587137932796041848839393393469263543415480\n  9518362332331752293703521029146413312752037117166754872063473892329378510729029514462927415467619479\n  4274716691603049782928896147458702649979707920638724082502300642554499590401197410853516784440901880\n  6462937483544396144003535233103040411784572289029581805810321237438258987027473704010683777715925126\n  4535706508300921479258349892475127453622006105854575997369313529707814374284134055195444672148941505\n  7452839171603715453082525558343202512542416624457524562964457910769717152147095185055003550543906316\n  8825810578507463565620479146676805569843845520277099697198898072337148695635670317768776378974327349\n  2829343905145567060744607970476931646278121417138182743785614621970880870210642110573778514713588373\n  7738824076528045191427137488110559744718310093937519765980210024101251123081368260338474491087716132\n  2857660263938849284959898236565727204263572026374825649494912629141917130646280595669825493603261320\n  1925280434617043902892602799314043613702658201213128514881585731117821041310335728887181729526271120\n  0081475064026830464189887697478791731737038139991888242416994212152776045185956711909418073734793310\n  9970928315546816563952710104611376254066449586183854638982208996778329550111431499593680398222303713\n  6329574232173574464734210974149174364199473195884005263872695923183642325491845595504534377846709470\n  4509594201202114220864191279049359945213739248711074323149511380429379365543637217263481907571135312\n  7093079527295221124795314989699080894665747695565124360561142008663990560990003803025061242360775032\n  9341347289050131677280971316268349596340929224303119508487886710353352002371273020291659297525265703\n  9210421496349523857085605723434621576956985134068304548331545907536471146996824209102321431171769227\n  7385347704177940764410013010485960927072113205231853822274448702433271039878114791275460808361156877\n  9215131131045008366363100751751102590028086427715020962713662397401075288445468331618211502789264307\n  2976355761055112462033248005310599511150543148482955343295983057427245173788652719300073232173623758\n  7327314890910945537402704811855571990516839387453520679708592118964078548950410940569965988715988633\n  6207795504521932156336124685303174705443940294182926355240155452316098682553138970188015397045962501\n  6917966481250155593231148267300563383579726032860177847414960045697257834956205873287301245145557634\n  5230298648149544100907883529801207012654109525184606662017674204525736799469077190845378748206080290\n  4825167017661982073061833123921935356900407052154989390344659388090475077241695436518580750664904594\n  4318886297872357160302248135220460109063521450828063974927551284769435499620339916448879197437902095\n  7188863200247502079102379073072963746326336674594275563784535691367345524014897125909480368566282321\n  0050039400731066320752572831471151926332892852069672393471750982952602125494764330195357438350925828\n  3111339115390633766173730772363027988986998579945016592376906754883798892940060516282614004815046948\n  2814033083916434248650939635458909132805951116334550365634824519150583179498083182728134795050772717\n  3359496633718821491928378711646390356692577994245739435547304493555939684803279020861419681508260648\n  1092468854338332986639074547805263629161562798803187828270745163032786390756653362197506322424864576\n  9459753596673200603898262930000761251494798008956712452569559827585485769012463686594942242277271771\n  5184964175107159841635720724122437196806720392706478942789421712842641334271183184794413346064724314\n  1150155098551171241466824331235206284065722692606904747919644729752832274956981963277872816259540120\n  2053807329582500497445930809782409529912965423318498798800771681631986086512088315867256506594414061\n  8446837496318929137459934216034848228831582897309421614736892558516992715531155888876007217034102445\n  8744020844342827300467309795555666811501300338889583802314643138290026007632285034758307808788951803\n  1398102076278898517435347822512084675949743002443789584289568075266320362769629946018083494199491270\n  6559130840005862656399639110406851041282007153246256426371456355757694528492711263557719632506589654\n  5536482125459263355257292595281499341587877651569223119151023373440716991656476398200089698462984399\n  7759385398112133218103281989699457926176493582974837338775235285946403513823823062694536345810031936\n  7250206982807384333411752831573143426398964163471270530347756991558003118159180911378802688385475769\n  7292339888286032302997704306662886955301210272705763395989768941024996847949816842011992561348075644\n  0406559462383708723688812548949148794873480861416810552114001845517008444484294847550732736642827222\n  0633658240174549880829130188391401568090500008495465737300032747797209917507461785951579953202237285\n  2359204007425152256386166756203188398117618611960221628474319079702503674592828046781785366473935600\n  3540382782818457669478233745711382212193261672950104270694095202650280522898590935002394490874562620\n  5345221731194095778301953605185038549614062182530618203651827337062111989390244889753863581809944918\n  1578487833652886543654224830202789241704968965110417275947501781226785814391748649424357300909171264\n  8771605959209744581146295542231002200851205225897647781148270394267766642782746259395117438071986187\n  2226558650403002846914692786468003183603463817264057027074226203429718755580993868712404656223338914\n  6465830554301315509528510972630050805188265272685335372937338569182693717167730316118647494810424215\n  1279159101460656979533313377409593674932644146370242752453933503013099283364854070698403439912124524\n  9275580299798824092066446404258596620088874191649877302754037292042158109378147131362262886666945474\n  2124495528490914921933719362340294337125575569988652966236450353519202677763794248208286056893623152\n  1523178850145213132149146986854835944706865850109813142058926764161151621094053567807368100897342458\n  7293270521085357267638056422884092966588447779527954671073519329547471301507922084032823220442894467\n  8218396547110902117340725139724757357008555312743219996751259582568063235880883884366203262266191414\n  9347404364980002473983320924118386674296092694607014183881781107142824396577963884398647823137154249\n  8947258304114514952687242361899676305881682084632743744121039055276521871073556452571336011455804558\n  5684558650432859917676519619327114349866540777451450047307271171479571222757201812886446440777517460\n  3282423173385337652989810442322404677246320479517980971576025800885768975134059480548268772884776293\n  8464549604027037050853941909276993706680455171941604037635118018551365754510952470346022600207417428\n  2384948178225490636599208474903758320574467795910675566064077500934712981700581876940802799269046059\n  4987211763415191488225186704395573100179371000466572921803728487979715692278888397041982545657064289\n  0898582795862565990137596875007856985342094439959715236676735599115570900614130188539560069330508261\n  1578831597901882912877765396964067539208084858229047556190518637549059417647208090848523929966365377\n  7468709856801423613707637046742361802921867959247697776529262929041798392750534329433844765333985012\n  2828362798515026374542796671771484197573390657287154305432157523544932053465375423820484485088463459\n  0853386677292538520444984413136863751894117684862613603681937363513393254080685226921474307329134467\n  6252932264084533084493864715156181394136343503648177947550976339255988278690369632386330342579445292\n  2923775203287448902004053266813935475285501746453171721459950814556136469252665022711533738181759785\n  5795041988075485811336289154900903908060775415757361373755988018757307536248737001291223826113438103\n  9234372313536898891533749493786324984941764281417045284082969399172432328677256415048376577311449335\n  2155385230017811082761636303709020525950377909253411047057004656525197792567933141088663264059262317\n  8893126031528575871642421190333798725775874290129037593626972723431489357257241883794186276864566775\n  8686920276014398050163871435204776738809005789283633817797388457344100149966433235822257925351711059\n  4856078918240152199828522694650958763149247127952016446764740270468954543510306982617999140223407285\n  4891546806842095743207506621154487626644675798636443880232586360886918759442271521429650664161384963\n  8150279721730712659205782660027847181400342092656930703090445702459646757649018527813931481315092036\n  4104984596906022531447482294570702527043630406111445514222766936650125425237207439401827752508941432\n  9152151705997454593125946821214351062276330331850433948895127672063729151249368193570319104693572905\n  2762887687825004850548005973230753265227792552419913159617911522069419685479187341566997810967025629\n  9399320816450717417349056433986521998663905570935211985243906798615021448623928438739820187602285471\n  2303949459661572587509650320071247665759381372124801134153550616754720369579105597461067112541711745\n  3695430147191419937319722797169021161357262524311647228936664414262124385498136236949635712821160368\n  5441607108231775107801298304253814190892249208595364610821395648113205316073707772076055993498150342\n  4064077512331512158999246297497845474385785595227089267102479199199645043040166005621762962340149282\n  1816115205046438140512010176327979026932712227012592708163045794086959388503088585777767698805771202\n  7746185837281858599701772111603710982739324147197937663864843160008415792725306116408501515001652030\n  0200142743376390418788622635274702258984849469077694747613276391052599405660382382371636943555470658\n  1748273071824741827263627240462399440284444736424586444751046902997652674973443569857085390578191599\n  5859960967506128309101947488656507512613971363292764158349130420830095085110041407455744378492789857\n  6072610576974181963369679075518838322017344376439805368296268732851893953081597213840998753657746635\n  4932531139362559789543000911914267407538592549690157973419183710401699917900945678359628573224471479\n  0732045696471978631549086284123332517481278482880984876102210097427834751646279055393851966889569651\n  0876062872957459088920170238672074010602453894151954739328142466223126892362650272056402643021776903\n  1895555206112711463146717038915773390065452869232720808111578757374991035324446693616535175221246886\n  6080593973805468948675560258870687103081189892202421749529345821953530099156135536073159095673469906\n  9924874268001953821752462105349862701061321590757260240804300827868356293198384271052198354727511764\n  2330279958926872730531183558056875276124091974244476335680956874844410454670283523651415276562700804\n  3630974774537678098208734980384982599248810670297754949535228299516546559850687428317628520857196139\n  3797828505779014996232139220462341524168238038894466242673730018965433764765036341251828509512088864\n  8562947143987795665592807491648962562185926715414692176768396054500821642162605610642314443579823069\n  1965780470574714846007296818237228797756049608915817868672936323790241579204728364697021031397518009\n  7841598550007055364938753212574961674875872583259925957615074339186228437988301346044540880817809685\n  4911945411934702689650599198604109976532111965810629665500511618365170620292880877609149846167316442\n  6864197089230648463056754573887202476016525776085293772109335844538710740272925919152462676235381797\n  8693064215340131633701135735635111098141821129662210736726269615672674830775248874448416766573702400\n  4850839370255838591012266948358068391545479166016456914863052393597793244672558867174160485503871149\n  0317607553732194472830582219155807880752453696932744601747360524205864696869757706121867761972058749\n  1045165142715495423853920232526975123495465463090613294600566507283098728033873735155375223563183570\n  2537006494092638080317374634854036114660004846876242310894723791650074517970524862846727663375517303\n  6873683856440370498066179092008317107882104981833155261485053735407503510822393924744563010969204227\n  8844737169688950911185736926890336659718522537770329622016708106551812675800940852515068477579219138\n  9321380928696119531220905038018107658748836831788278142527862618796676068219770390932600672961512755\n  7125278643706989835444409613917379035454851804039733313748052358791095558304048153480453918785403824\n  3236907304310274062641777762657301034703384021129669084818046162496487394734584412155302581522214994\n  5822249941941954725641031750211442280865230280221342409319393272767819599060811259862396733945898961\n  9071679777780259511631477576264028588262514815821643994413506196081175890461951158539082613354960388\n  0323713522245169681180597512189590028591797390866524495280407827130270045377437267855532504850397463\n  7573946460984085658930184822341614986583150346608218622360580194811455490351547426626606129502687840\n  9754779814072682395693147248760982803450811893834040961534314863011248676465315478758454946522227531\n  8773560890835043837081120882441759938586466309397048117253004020305813409044745051156377054103501416\n  6861912485252694933482978510181114723298740453961275402222190958440508723066232688884970422345670001\n  1949751859796494099148971385362279458874076099043285422812773058183040249451087063369869468674008948\n  1097539710090849476830410711529550638887652490545659994260773886347394552511448972036104793757254472\n  3966023547748127494160698351013147640236419491461059805563757044651556671236525682827015744528476022\n  0781753972337164096986264920557668761564457744644664925477346729725557053882859078923175970676863982\n  4966294555601938731527103627201242931201764252246448031819544683337639946131383614457041608883422253\n  7155878358070161156027177541424723331527813566940098980044458238998420064074895892389238927522891473\n  2945531240424775520838052379510123938435858775454999001272068286659998579098429303846007329623842629\n  0797218233372747669464015269204881430422739438838386988072365034008809524512726001361525704157749789\n  5464274592866962164154275190720789657656762047087629102592988877128340580613171820688795096273552308\n  0228036658853093027046194006144644918627856642449420816210203832761116962244213863973115713011899185\n  3169915158165025834281284874149275360507355014927516496556894986881445782807241540090116176936589862\n  8113745927903225784890933976881608670857002995345721579420980997220532145751427154112209398869874562\n  8011653320792545519698519103842815726835120109236799524290686799545683083885930136672185211353641724\n  4228370492060364815444971779988618739061970126506684370640425124459951909006226082179845415139874086\n  1561892465930844027470147101672547160166860173976919976620111199893015535406281778132823867987398831\n  8548093651417526904050273992326953229393103604569842520594710877602232101677467927935625307683377220\n  6929809952133275493410764068293696256538097982992215020076190656713323330719175311095376967431445827\n  0474521918565656173056185321660425946455385616883759934532767382788781222315372811134173554517073553\n  2082760440774525442307854537481125966546355745960432703685421573869622444796092593675008309891400068\n  5383635881778748642710688257878740799283418251977140842230489497915517987678274684754084928993864763\n  4983917539244593293129138080738765005052200666662727343844540498968011834325534999762501192176787558\n  0980672332416782617825708911630179808819558379107540118050962160109308042257018054929764678411538769\n  1430708824753121723137940372365928771043455446962665999926233933298641137100126804081160276969402287\n  1365072981064452520165517338604686504062129245789271472274267638614268236764085164119476626514371013\n  9385568064270077829659680486077517949221215629173867163546498898538357515324974315835413991322136505\n  1551384109030902755433236441202253007704282111471419181475709618331378229434207254341031555828186693\n  2838668366072691638369677932010214202904681337049153438059246547114970835401227241006503949742164188\n  6692274473689950625289450277718989469132963467585879264235211633546474686426054856131577840361143149\n  0269544275056480384788879432956556048443391840602027045146827824231514065070221048519592072312004933\n  7176738352370930885652643448419467734538241329688543063024778255435028195957175433268735831728279337\n  7410102634717252580005510899808792042744778385364274972065430922479605721400330661597939815697061366\n  0983964055202876699917225472402063960609642994542705915460007353673154988077390830015813351603573011\n  1114109280154122806666705878555092703338500983115676285161649242550929283039087709889349460723490286\n  5856020542206703715680463500382605276371082398659793184830936764165636079070660523343411137793121612\n  0205880951461437739476835388395047212945283498654808648378850194676769456232670199871331845545348373\n  6084512767180056787542358871951058956527978045378344846504681469516775381369518451030832390374965716\n  2143307963860154481614495523935111212189443023826954057860116467373664795652065872508159275305713134\n  3835699200489996180432549502052195550206179277993056424583665872167535192817503344992391833256236162\n  6502081490355786124405183440403815991358271738433734045297449996405991865666415356124243080016261793\n  3750921429658088283221957057843171697946284551330968382460003698996180592987950660376071243272559753\n  6508820386360958809040038001760475078669744332587723215438325998399864395011449541507700972822653695\n  8394380850912841104162909663701274249881761634410166742340050683616764823271038894223948202530869672\n  2292524340750602651298857635878137500851005688687432827471873232428984773354258150416258955023854489\n  0684967676489282970728115843511676077617260489135585109814789508429849836055936593710532020599790443\n  6973534016628764532063718869382189780157321907629981036125683876483872698536012944816073176186580668\n  0596837338941198265008732624266960024090883207622611783999157440210584278984506303601419933928362455\n  4027683509989720421859620902016210156519223584211948820209123783927557185605541656205455347196978661\n  2350583489628212860820840349731199881077259045458633766108505095823850307512842596428597494715967542\n  5924034955860979643401966466721757237237070785184646638370671702995416983298869124728187680273812549\n  6293898760722340846570950989432016548760479339467946851343732630392230933179068730316994180074048000\n  6872513659785795859947801994965234272868898871781351617155057783915871386404057895659182321370814005\n  8713808836523047167127182200601860881125726033986240354206752127690892108155226032930044410189063723\n  6591957119530302882485868478256488300525181260810354213518122471584004627510592444870583709540835318\n  9752152361034204084507641376742347300588220343231604746330435062814232108294872409025947644118910322\n  3374049794740857827762204826182195142821798112437267662584689519510699867374022732300260261505970642\n  1527460232699949700615823592828222978328684019972903653781681600288411730673324496628384032435365041\n  3975362055091052197490957998605957269413840242675559674863774293085831406648031844531532908153215494\n  3458288044293735568005276670180009478873358860913649494583852689279136559434288174186455594102961792\n  9958126080970645474650902342618403450108124033539000610734694120978386716277216137083614515110500772\n  0117042140575102955114913702554533502068141165244769178458694354034118791350719472868333896624761011\n  8301700497261895611839898160539092008911727724528273299586808380107378131400187606725012692645464509\n  7673374700236767820135235673242624788804823436290099963301097657305710745086213218779682807434398964\n  8355242714487573058303218024945210923199120417862983211064561898234504950543971618030395685126538014\n  9225169487847955472418638278627582327821299397820742867554710924982182446861479580814083550046687559\n  6261579061717590219271869723784547241129855757317937479535182955842991336928140588480421571538074685\n  3113023354946272141844005632397445875377275180714660165706503537500007800054761003678636991113239858\n  6213221822462464343501036322398596701728992842523411315434326293039073595342914413933874282187214841\n  8613127907162685826684720595466403565113327927292836704215333378156489787872434723165771081189058811\n  5922053413447767521297746355065511098018114547089217012441063492394924242267383494394078654658363868\n  5970026019915416838558615578967012722002322003168619541970289247574216667668015248082402211115619098\n  2909528829342278406490395339672008649956965447075211846134340977857777364263165869169876274954188683\n  1332475145315900233544095171491408135927319114619200677579215856331076125470709339611644150880072729\n  3945636849253271858915516881472096011415405664003892102811864854595041190055800792839471619967600301\n  8770007299166134878103899189799277933082603333383340579193386012599266354350647100912606346252385743\n  4635268474929790657800172876659682562194685410779874218445504710482511389936542799445932024438989851\n  3442567266932786132950485170204267041681042398878776628283501931254549510108703766963812060312761799\n  6218893187778305204501948120474270520457321254873390393028668085392898551453951830701677372533915679\n  2769039073362485903433514761178705177976647101075024507681616557253954820094809110586317329891753118\n  4160364021950346357321959475586008320829267512378849551667250649220720609741203129313574353745218554\n  5498302580415651798622780164689374817239713381123695363735811057393910536917973929343197751880325243\n  5258608082755374099972101540080046979927943422345447689707580313149065499764572719969962803326920908\n  9155838176032139892644880237691008274209066808004373992504541223684971940977467046731673788785204941\n  6564473707132543728313954096231813376473848894121827756876058275472115348406411192866091980614228229\n  5524907588525871140721341401635238119989127477891313975746828093424728231102189843007024439996429064\n  4450844788027668653946357835978633014357430738552248011805785516300305948035170230529176193766804489\n  7455190062298141740225468793859809142285837449414294668405678447862996873037366863397510139100798455\n  8831971893984042058517831262556099075164256666091448576606836793744806529724037099333962928343483326\n  6104136871344725962944171536616832569298746075193490043675487124501251738822895942643220617183770595\n  1665664903889623415903428365924676238921543162109473965009869257089507504114157819718945799485168292\n  3997676852605909408476925555603209473017988926182294738346886884787742147478211246290050487616242097\n  5722951786073395988696418605399569127426110537996486482728821472986544793727051143103641539950430249\n  2489038987190473804812173705725663713465147154131222056319569952971074484542325785409319607037480624\n  3288730574037414313238215835562671427568755755136182019176330108628379725855115674172305047190608736\n  1627708326296442958048279756363082376436161545554061698004581964467066781024334784598806924847727489\n  5298262045169437003711201912953531129197138017595577974532179706899810786979967116140647258355731385\n  2803781447946186458216347452039855897512317136407974683851455920414500521772122914466992786476520100\n  3653978899709419567795422900041438454871434885285565176308029925167644424768218649062151219172342568\n  6851600605859780896623668832012839653122703074654818211999482253881430040168114450362116720244462048\n  2829677761601656378975763497955487255108091057813394203472774484748769898419218280856304164926029917\n  6230362632250441829629652154385628760703742186814004738630945015910913254210303256135110757558287347\n  8656260809325645074346337233422408558581633853715306945878269202052395067272475369001398011496431659\n  4582971648686322048417952196424498327948806313464620108913932870531345561503788769211459272685051467\n  7135599589063223865076477828269016803601306170856982886336353398216641166133554804037038210034458380\n  8150558303401797120822493909503856609585571395374634762832404217519342656686392559177433783255482070\n  3861056330126237628769817347282242509461531890702150820504218103977489407657214990832478528545951002\n  4679597393084110627252254156964938923682735814346077275980334626431259827888944181849173802687044960\n  3886707186477083156478758911780354308201318656582034354073422928347455769651498683915039761412613360\n  7894809975591648249062551685536794824740509846496085681889172036998737579643980011652952702772372260\n  1935755572023263101476869284762636285189304849269092640985472493648181412831689383283125795662135988\n  3554452066740895840923148625755911051962200050308020425737002899660124136355648802803399956946560958\n  8576321992603000468539755980287655583171070639975066604761486777635632261161271522426710967361840252\n  9108255244615388577666027796080898302837068778139849238125451717898757790676916513246031087551814796\n  0012167620168554361388753511114464644596594898628685003842938167759796191272999045913439604283622782\n  1457438491080662673720398159683311458313277557371939647621394703694871344837965336720886507609494431\n  0674893862810166860809354876204062953142683679016223243442162500961919886528250184780750093092989616\n  8789351440485278448521019497293149122933664283836109583591179266973210503286586371961913064985733208\n  6615243198917751756133072533690606289440140362467357916861241907679730721538960992609147780039218290\n  9660567805157424539481270515827865608617662808876754852826435345792975109103743243148049050997201340\n  0938712099679922667327456972199757397498352955663444532434557032626027829313689388962967691490051117\n  9164157396415162234596241438799849972397210625910452426655628296014596790128617641535247864330478558\n  1496257111395603251503631837450619425879073297479906540337812932343549647709599415970216918103681473\n  3833330641513877132215173398409381746568333237521245212042635149480179573706485748255881296241114146\n  4692661774781738601561556967768080635428081339262222680573586043957391627387714350848477018662653169\n  7488864738682430941960189287589120213872770961538488095065653207344205898497856821448109934432714379\n  4129234072975479326476182962040361443641127465240436917542835856614059594332610091323144864164204976\n  4947955201717108651706981224160848217072171016494824798077491801666631807604571639525183860958271832\n  7208657052982558926649231274050673123487720349779982956094106360305165816819038480111470304239018204\n  5758372731652085922539947510938900121122194266654459086779269137115495078966657667654609628827777519\n  9570554507297923666208523507816894340032047543740400762179909188135109499396694313427985992158062927\n  0421382675621435340592467202350206425854109685955128295988801679474853488276232260898821426027966949\n  4883399735380911531026157275260615166467574723112673113045630210164427562827821914879246698975320978\n  3265292168258433047908547833654269758433077955719520001012078724019881349498443843676382704117421003\n  6951169011180168326999466120100860532094157901928897613978403516511159934642044414827682054550634184\n  8306161979946027048964895243897025843417177319031533093214798054202089619512507592936490162781474077\n  3224772573220191350456805599978569277543054657879842859468408586784134114538241240720656755982648262\n  5761903033834174251848538540384703710069087650808535086402176210101567282914356736771103511643978363\n  4404283023478073545669143817704745089458721178783915416653092472697951952686392823300371685067876207\n  8775481783910819732182904787993291396078874176833081865318199940659792678221322713459632471409529463\n  0761973967499846349363609758067253661551807859814534953582160148026023317625201506366399391351428775\n  1153532124112251505706572311520853765028432210158406189825700470439171864907241208917145612024917300\n  4379934999420658663798578734606048061922811946433156292568671087969712349623640619373881121802073791\n  5981801097590801132722578430025011137880349579204391899288300516242921760033764107933719681331920675\n  8299182607848524757117752420168349348194140053916463935218273710489150036580479259761583436513553494\n  3843191509214629308199501835916709425302654032980324967615843963471143532471437039221486178438282611\n  3866885521598461344505803302636914394174355991753787166688140045296893435198765272300845846550156565\n  9895211301104852881693941568670635178319221855955305000298648325444774777199550165082658896713964088\n  9880567958066916065806094048513928010222769761561382608319076033245484652866146494294839667733008070\n  7320067510426251414296244714536875097068785066005939402651877861032765470280632572990619689759188738\n  6672305110123794932925976495748262551959273944717640092556185211857724430888945893130457097527258670\n  7145565142360341819890315195457218862114917103453059657845082618680743649773583175770086475879964322\n  7445489500780966711961621513676950853089233612386662834811029398046074355342727244281049032807567670\n  0337727112094912843448745081356882215603305043883517541081483037534434208412208168360581326234576775\n  4279316198604543050444851055580041167943376713205581470587272088253604731064967931847963735278844788\n  5205873182866006563349325602359088898353777250797020050541440210559461072076492440913633722789739946\n  6397512341178836631250900614162322765702854104850679744981271814676430841410300237525653730495276727\n  5484545999787163325331050619024021518146810014651262851039759839412882369862113183152477649679577744\n  1913323947985528716530231998698023983984731981788171333103443398908379580000513196534523383390109097\n  0444714347942650262857403151815203546507282311838519865802936213522437975431938019834329143125027577\n  6675431686988860286567701350037258969644586868341764738783906654442181923585773107870023191744542871\n  4160030268283724049464360347876903573326188114310108132188552798589730345053440330372276915140453182\n  3618783217199889890550829089662419765855980578341428737306480985290782145941126494992196511361256777\n  3076994605802064072391808669002017569564175955272113593375897911604759823155872535644568257143746585\n  6688982037370549704529071584697376355587060928012017697805329357967838079502279220010520167689887325\n  4108389319250907174288810810708623207551018480041769696826290392399839381162366384787130819320185559\n  2678658980709850229537394942175424696253547043954732413392476485210376117773112313850016187130471064\n  7783932487585006361991196778775326807139246898440388265936051085465236922261927240349912103831622629\n  7241144083556868049980746048371359252075390170144693739164092864863919053757393294556536775435632948\n  9530854791973561811689434694434436430308714442549106098294828815811595635629933779473922097851104067\n  2166448032053106709130375948843457873439847370765374740479308090343824433970583053269585629984793830\n  4808177975089019323978819644747281348548648563997367907690393025212859195095945330313797518529818662\n  6201176126095321392633918271825632758305911893721069157764383887227842285290091226125140805231508120\n  2726247737066716153729796236517171183091817152280526537593373755812823486429693226678471338695988769\n  1580950811504993633735690590084289200705482525461768954164710778011758607143286624044830552364259377\n  5798552448696080726730590765024885140814761891799989629290795406069165098627507033091008866119931836\n  5347811068950055323212323104099431566975712843211058927290756266529830683461268817435027634457348731\n  3081278785396682594804502445089945385062622281565720665625908071060090719474158064342896173131515706\n  0558113998960765684277239548120624654927922466441086739301705267840652247504105360432350868815254382\n  1884057815229519878956064995606982745328922732703853758452092709242946673468959337778965806769512859\n  0449057399130794876253979899894685344867084276328476440980465348855120943606428893738371053515595879\n  5075103681999586009247940522051548807777499830613137902641282737157571061281736249783647450207227756\n  1952126743273581685496119698882583112616695052224021881146693062574953847086995865745998878927868473\n  8719864383790480463746222816126871276345113094783166175997075950853325746028493740010436450345565804\n  4944295034531833812907850888333858378697710849820665102062795707669833445177934527180376911410207557\n  4774315429329032629532114978826203515987412546422884395277795499289564754347105898585159005508490056\n  9690369399463805412744078272079588120610950182666750528291004286440115969091560260245872117456045510\n  9407684697973682748145979040455219048418011545663478335343808815341403723981788190775763064723383684\n  8076617187887525444073186583050118647563203017139833900789875424411026277749259455787263151608748702\n  5048062038162606284156754299711008457236079436838831775697116071774760197736299860847092256124190334\n  4303868060751607783650278916662836093176759695530149368127979354666523938986549220821261327763789820\n  2946799581624398705936239170511750705049392442937122875207210047900369520353054174702688100313142753\n  1174456246407354520013033515441611612845306363822062031827141203471057333057060956104199977441294378\n  9723336195293680711629464974174674606161944284195771506421244911540670731221384206414126967154566438\n  9159471777969493519583468433678322141303743107342917437343763544159073773807768335545452204160755832\n  4500141271289974101494705488647243415899129609228298624074551605891496310210005958713471920979723983\n  6831280110175264318686111835170173586754064926579151374058216297242018837510297720276922807801732353\n  6585248661037355246360519741758718234908738197745199604135160468808608272559061048282225757674635819\n  1662903439070547597034809044004304333317413461423454127456779872589232409091510873059202427900149673\n  7015134772151425714802387818972789099319232118851804003049762893873119886876339770569031907414517629\n  7505582950790551571289772603435467222518751947227775034780629888158027640883058588732114089935625654\n  4526325626293042854399332825503295028936990777054902947079622008390293221444112657382089568543447852\n  2535584373126933754793765994306991005699082156031450819886494389488679597736520237763805269495558714\n  5427065851747444596468235269410568519337370049144862376065979574374294931376284954237476962984236204\n  0406990322328625482822335420165228291288443421575127060202153831784521856484115066939436436446339032\n  9462869215001200331737223159459937024404665464401070954637786273667690456425997758603414233762759258\n  5363126437089730757955269968503132069091830679132654203064003148245598623926575975731775912862530894\n  6541251662284071633701497902673843253016190101372978864695403425694557263052203876294232648064996238\n  1630855003126516805447885568199731089679575544268392204851309190268824033771201778639860463980025603\n  7206069295346015367351300935166490475996904153484422840649464357839627395979697011999599689705500713\n  9802671431539123914611613581834068087605346672553050422397928096566221091111847789650335190031281930\n  8140470647874036715555211403407030398907223233915942351265297171121449159128746969645445570922804347\n  3384101385887428050725149320183676549865442619068767503039795693902421343747525920284449370703219824\n  0950852874392941278159586475430366953365464650438122955385696018708146303600068102231935356775884221\n  7066271778752289539374973944984606881958992605790426632428181883297682570878308901643540546417536779\n  7521401491698161349930449104204274172990731837969851312455958606399199659668996108005049400729639709\n  8959517574634950113152395405436384247715767305796899780935112310127000606831560134705616884208186210\n  5906584385468535226530994080955068645181964310455005698528640369722726449640722091072805065651759005\n  3633194257188261901685209110944462304938727622601300966509801815021611618931499175544866484510193964\n  0892424535185862966853588072370252086290396375135442408416767961062540774535439718720220389829258815\n  0488174626321440193245912638467764538782149003218736052884016158146769340972434249669596797455129521\n  5247541300383824175967755422515486890349846758461066315941988121179713345250927530701408561426350301\n  5271473708797902296635683001787990288084193893922491884489117670080380387588878016977011134533491153\n  4802106585087570025517363256882009759552748712253571825516978753150955690868985464837948430351870614\n  9231357340296313652791276152623061043140923956535229749326101802357414494002010757529248895892932458\n  0351889348336232266211070472227951789643113533222151331112813026996570565423666607124273606758337678\n  3519101251099443703046290763466149644955996730321258522840068128863206013843915352393209115790604734\n  1393629732349275918089423365652609394831336481029064358631183082596587859784715023449078747678799566\n  7424852051040103999757103940220630691734742020896991756005288898736759396629367401720982195418337128\n  2339328624773171964386256653145512699222367766777081986434967998415260451946404590163957896049279139\n  2910434902756838172684047052298140890671314915262504417545271011235786801298936828493391396383366078\n  1422917945543449168097066491318845378120257962155232128839888294830960254154515830155645623132845031\n  7418576979979910789556567996082529165537586122338380700692195796394198374261176767691005073575014710\n  4127391778359634794411592416074096491892386416231443150984337999995741238608455687906501796604659040\n  1190093106491459764550874416917093615978054671746589930170413753904682544419849306977396303361433004\n  0322637044138842456485319600091024035914860434195671889198585615655465775089014431777128616456862190\n  0128459460742160742957104583140046201246390110210193236887462318746390639051846090824746612222586831\n  7169890636064025404893508750600193538323584777977777184156692711224004455167705419310730388369438797\n  8890462421759004666609104016362270064506716725632981356191695775856133339039827759965225099040387093\n  2789862215954943799706306480709649417708005812270559330916211844004635893785632435864191061540068204\n  7879016214044578771739810295260717300099121797113754243334882266618671805934535003597940626101694558\n  9487985287382394619259273830058657862369012719296382659263937819596877763449192781383915273468510317\n  1283501167754128969634017633688033476132425006547944835516002423125664608010786702586037609939080045\n  1756260090655554130984042735743005006687743313528206170729903389370532225467004205889640465239361428\n  3079185404169666783240709559587709423200941561095553433443491385438840861082486242898596197412565717\n  0424006787671236859353722710915670406062194347260204099413954720131755244915834594427491919291350235\n  5834404187206974345886053833701858976572062254668638991474061713844091114054244489241812528058737844\n  4375990337027144323207852046419314755947583142919416971906297697904498821308019258759048587570102804\n  9890092764667431817419312738798791908667056460174141045183654736392112018312726421352990750753167418\n  6041139085079174044172658009288966400350856182993724721368434131495692957040198130016060875412795746\n  6419031797332593924021074167670242353517422118285715161832976814222607309029636948713308807785556663\n  2397283342252706565073072518903090395022975145545081413444428165414364410492175062270643628610175717\n  1120483665814970582463578007550456264537446280525932841567885798506901058045279756262857220830478354\n  3668131330317233238135264707525779523301528916639528654318999573174578016782672814602226403818995669\n  3799484242109824897420088233111400134104409516093083130905465503159555154739774802214624067611052716\n  1375799862835439696657835524567007936049751876795850043478594444834874734552599963239258820104452878\n  9576723339110852081379948423471531895261281875108905121354654969246066557673451857177405113980900507\n  4932280070940569206554428799289768091385328823923127426496379071979978524909030460958502032813011881\n  9189798753861277050983112679686721178100609428860334160740802044853244141445794547210546989291664998\n  1941599750811708399758552531253479307072377194823738336760655418502113337357535711604984088630696264\n  9890151155629827792230433349844936783915198562685043252008447985546296912629978831302936306463370450\n  3315526375204047392241570728577799880296353289006984007678189697563540217661942944247537256498457226\n  5506787359093405723897937819146080319827113924804979411004922981431759499199310328089795747253376814\n  6061745433132644892480370134626426692631734244357427051774756506755634133360059178313763737592038902\n  0426517169186542244841360946598636267754333221729097280677212181229450177664232716733109192752337724\n  2450590808589275655643441154844388895321327028560540600643524034011774394263831492694203667677312492\n  3344604615279222871174737320682073795040775380702487513973697487220807941836272457926715860587568437\n  3825696601528845015936360579976487955466689796317276414458267140983930260584443731183219527357824299\n  2380530460979253217595294376466967178599565547975260104811160900192559877031603692890535464219693617\n  9009854720785512572597532576878034184282394193011676471278020013244905417068719406087486425099249004\n  1243777990256723623875213448754686801805700267716590457174167509358537466327846614717022291277538164\n  8935814037542041316317966204626016830058358402780842508470610285632146763492164415596565399512441115\n  2722520988557631807880862837444395373363866289139439904591869356297993169132074310849123878269670817\n  3798380276007328352371305703835388120192178074557053921312504821976693406394280234533509698054521919\n  6416496966420519223222933252249809906809438298608239338686773954452673632194440159865904066528670206\n  5100494097867130245089605063631147497897543186327376379320227953001087717684402618218003859090607702\n  9345978640932969511233853261494565585967711754424619462086741789881434778027023789183865475073672507\n  0123164595421042303682530154992729230497065006887445529088936646551481938480563745544703197171864227\n  2096587063004983436657183030945852528562989254613260790172374623360138208947640472176710210783635306\n  3283918528942630970835241842688066639724543519498745949527236882351106475938370531361494523326299006\n  0613544202079008007844359185142381095406246359288007491747232601428291506647356469491490753130404119\n  4874612758425172542299337656191322834413615968845123050979229080934778061000120243079336754606956718\n  8678475890291671628151047910984819968795053757476103438392892981834755913533728342888492285393965950\n  1645942296849021635769846036566677068849790614937895866238978513950301955252071159479162430380571339\n  1044123512797717425894997181320899397240945763050438176542023774937292923666640858263563047018894284\n  7136621796280779475814106472039686900573358837832383938515643676929109532126309530237234188776377595\n  1325585719886841563511434654449213461836258200177391119635659736209174802895107119119312161615049356\n  6140019891540677191474060450200848900785210448984071558724913181424123745314739095859285491926195512\n  7528154045555489486053043951830551638652963511435855426789578843322470303223984629694037003638667059\n  7551896228216684947215516799401023726052761920617504560496637170762638459530053344438789944328543663\n  0146414207515026765299871484148385924204684351505285892648354129599964190638362225500616202985179080\n  7999551716142892743322162806963512162902965050345455980024292038066113122499875748777814543334957813\n  6558008300458790545565523759643089947282941565846898062943112725975546930218879127310353002168642276\n  3366103189051108633596398607097473741955293417850780136533786877679115147383325251300237191023587588\n  6798039385529704998321830389985333735331510345804434025730422758682609723983422315017640803327317622\n  6319675659897729718394229716522776196734085734441374759147793179333989243599405813960322813465924785\n  5875655057515942861161317673955283481508085185207154795143926672875105744138676971890208777611959245\n  9359290863839696200576865099629303818145491280734180972040320363366766499443919936264145227145073503\n  7059076093857524400009474822971362377215926308360221391588559094614074069763012970865696906676244218\n  6183635520472790353317530936077977879847080239021859587448789607452374905628374741893102680628048174\n  3381300198221277706092184700815252327145986723437854310497839043649305860764535756025983828162540984\n  9639983181129718814386395426544082800861930572917995688879881825724409230860777086263513136094630976\n  7740997028472766829666854290845405202291900303432247189820499382480607516387279456689408497366651622\n  8133694882858339531350502170536111817502101016960937372882174683892618068718872117122032067336498312\n  8125457269276310564825879010685752080806339287513648175837581096955969933848419910626922411365611711\n  2954796777812386239349341400854705378458378285151232798730884093735721100458603654544945301868107329\n  3761108679782828034366133339780538614863594371635008771193119559848021828992677797694091393084926892\n  3971610875162598136464279519116303391796129190017609532216557349110374712094579004186028992215511759\n  1568303624947160865051863227974295613651983035189714287602237507160599904685227028482420257009629938\n  2791478180154066416917925969650230616749677247841947414200924297729713888325116655222730338964447305\n  2704902414772756471540923768066416528226112216605519035104953216953829995701741146510299848982516439\n  0569909394598682049855258312876445683898434210936589431051140755583849278936997409501389198821247991\n  6209888392435587365554523753623890641072663136573386887150143766765743928298320734613140394952617095\n  3084489658005655846309523296318712451836616630427749852736202349067859155769362205347242611125326389\n  1430252893766737392628606460991664258399987464743414163952677732246933313408989228213523671609562825\n  1349234859268040735518153607196567395027069135357634343767443117249084553776703266698841449114808884\n  8013249302584381770118785666357293539878114064658836941728387365708433757510447991235973659724344557\n  4271838473362051640986039310219592121122572034365100139638906494529671420560890861769828831638828382\n  5229707658189611895457298258107339454017277497834540687764110778004407429296639807958026689312946890\n  8915006186184189218530416433221694927821339211827719021675202080596726274946300280538877794596218568\n  3074384298925646302408906336676064738970496873626773471431934643782695278376028614658389278933623236\n  1603686965888599440717090143857650085623703570747288123004277647474703779463200055437274736584724026\n  1839025081850203994131095039708124812210776128324595639956407303784228294941790417991353653370609295\n  3580412844901956771743632655873343028440148149907546510328181387821090721433983745415095721808723321\n  6393141184885404882476133156499354030311313197143885666833802176668360829503236040595136775927155165\n  6796802958597338036134406930781375730116130026579702426559178634319436264662301868725879630575563660\n  7828996953634981452238866007301477187919864160661439080577725519244870708291097673554991120061231753\n  6184781317654395572950385452923653669413348562178789261547404561504523088531184389783350748069944802\n  0815830478029291395027421867886919801765554681814454430741911022927219318644407497903172599397713621\n  8099711176146890001377240700923484996330832030429732196758278940008466523507115511183481032014483529\n  4744885188632413303960676395857662392727435386476553325926113916010589720694912160419438436276922502\n  0408360183481182715855343925553745823628255237262533143596996463666782559338210091759874444027185225\n  1290642515745359479613052718959948884782435317225627541310959985044277475352638887118926497707170550\n  2201056823253071154389564758303122551162876396883514326272862981524075588799596209804394659688932951\n  9044901057419141998149858790000533489612069163111754682534858290076839537662641452052739360786513805\n  7224150689718558277653895215135856589764073014881111337386924588890982276022973395124413507510038725\n  8948206647854453929055116049254655683017922363526377554626840904947800372684716102649508826206935748\n  4631643968978962700833763037430175619457389078848104243092855236310298355174517454466065297670819947\n  4320599516529159600871565211546129673541395732775167844348486459833913758485625055460175079220988358\n  7719338601394896751483376380213903415290428362645376374580878281537904708544575967614210377236123296\n  1964022920228951469688114470582893098035700150410369484170547286922751970446946972920349519697662176\n  6414362032109874971729908144000371573928189152840831974229437336774778258709218717225298406930555693\n  5225836786253877699037108329877979505169169629957607026624877256111532102452287179703093738005633540\n  5929310890187400495751330564575546864588192534437227170484110760458345052572429176844235610013945668\n  2456604288000474072926191657544095336500054458333133334866581972749276001242323822517184689306940857\n  2324615542392813887422027661693797935663441045037115598236757714312491279623141150164528880440942390\n  0517346456378036293953277878016360441042759186420251677118235910812494784489548807258551257454960799\n  5691801297131720540384249096087363621351310975286209862242624187424357837677291264179188013767520032\n  0563326189241018616513034810244006856808606110481129427409009375274857858586840922973157793668860861\n  9964429073615749053303451074679213921393573414693782678405331319923544330346071951552057006610011693\n  0106114645564891680500914500556137849404543693134859106184193301895454863852198600808200402863322268\n  5779286594749900693607510578023474201503531773730083649498916728935090935421209752074727250436661880\n  0613349590930611407110464599244759717542401996540730654084169735239250415635500390264400292275155191\n  0862941367236000269412071278113087636531615224433516226691901231017136295013316980770097670312259233\n  4099542352764898442089109243902756481617004072173927256602429583715571067168541418713003571310230544\n  7259377064542064373028381478419102186882184665671383261282637806975309886082906633039669846839624674\n  7688511450649131518615524629479248111598731109079771152980588092092858162277065275677719539311203573\n  1943345934347337295189941572147227619036780043087959047999266424281962016300988837148845043980122446\n  2455602660408616133199723284978761593171268140040450561896686909847082394137085518132619963768897021\n  2415231378187331300156011219956570354141065353563845243965564267272174345053170897086203476547586741\n  2814640719792280574469540684927959945904582090187317658661625178733129693572624876301827480530656002\n  9462418101514313186902408749384112421582150837307412833731003222668395769073506988176827548481773049\n  9539131031846532783838656267174760018062788758049254008878403927985646496451552789273450200154100313\n  1905096271080962889523768982872651391408194511671959166631818853373127982279478096384186330812324934\n  3682732708847168484082306510680498401989966141848682192923712432262932844248302361017983910042699040\n  7744799190837610211112396067250719299793136517706731645047986232255197970299256653151015966045966901\n  5088706888298252728640598951425047655646438613971390930202571945855825271392719811327758886955446292\n  0605202687675221367966827468775874528760778634491382699563480082544144131825347204948014212654329829\n  6784668605437790613389102060765389746783799090419822642829171356980043472466696993015751149537152043\n  7403191810795486894324062290945862326245220966757449528566016465787368842465402656045769732900129583\n  7874201711510057426597492533286825866257024583781152182201277576078722787536254417678516818491979949\n  4976491000369349095508194502055638112249647967662496507858023271236894462286697963197153902499010991\n  1767205329659201024327415836646285103519400541457190714863882469446903822456883885007824410392501635\n  9715374849056945245605312540379176033101653477500199864958058355366142071699741173310552540420552110\n  7731858104589461046273558070947146683528783522244243951951095964801933997282254412372911975335233397\n  8820050032094830778066283364606324667100180087066628897715761318039445308517785997967916175623642457\n  9913187479952951873675602067243360786278316446550471333425577456220329705837065208461481461803279556\n  5723112891379150610787823672417063157427908602758268048328204825305959448653553053355736089436683787\n  7887790883577331658156656404633363117896557755386745135965474379288244327761776652997753788443212262\n  6758789612663833068438490058005776137309460432457331415978761655537226301616423353451002374635368298\n  9424782425580648076643361805237741563140378933712699900811546084081424058692844640874238912457751936\n  6466994637359158441193177950085848065280520451386178972329910964611770976297169880547414864040358883\n  9279500405680966882682526783325875358351600505794585314848377702967618326360649136605647118508049163\n  5911181680573568625676757483627962595423144408426869444178084654590010983008324701273276732518629652\n  8101198756674251237185471917419644610996381436922527648768652429643328488026710488044888015591064476\n  9829183364432563837983478922499242473473474925585572931518611034534137335672274625782767187551285229\n  6157193501863251721759999422779441251276949166596411764533113076783943587557015112683397880778230893\n  2767292196739065650167909884959899971836201837724669791646815888400401508326413390170244028639070088\n  3106649068349767628800880971315772643341647052515364717730661392722405632571001397299899095593747730\n  5596363485600615984961253518310745042828059910113561527646137187323074054864438709510376239129317441\n  3926799644747323618213633118585804069936583777606558414953328326602877854696894300229268531019343019\n  8737058717358218098006693891250766257084746595062899184683469499119620505628810062352434005024075121\n  2565976218356834552257668404916525157075841461441328952097009306872902271637056385906105921696945735\n  1312296992925835675318834452109537570173563261816644245918307191732592805373518481830987229456262172\n  5404441898640397503845136061110062107180886892905388556538032123197766450079788089229139071971832155\n  3376607146881588861466593708021811848640949124415780158696473723909595858031173549396393423239812188\n  3858322269062273043691547964773290362031023158462282118660828589608169094090006189644213461734468252\n  1433863060864107649130309630386061561226947756727056616419832266128295594054185267009938944181452669\n  9815121965396719051384313536550321313806824245173488947592503124192484175255740381823511390261635537\n  0936864688471015259866820062966604332671588470284672528273675136369158934985721514957696957393793129\n  3333878685870155864384721219088131194713370873382327500056239923744771721034792168999587001504698058\n  9562365188542682939856667127230583317473946798938791798447572639669972565150933504944962393298941183\n  8095115220273859361991620893155937352131938012702984818829682456924664015891024522408334073529472376\n  7660187190835662573439468354704836224454619937129219945521607705226537983475106667694632555115664949\n  1168070523052817308690882682380129412541814673058459343581273433407463471098101697337845113700036146\n  6614777973756676762211878253942360370654923722566475192700250824888860406223409811545113334223901773\n  6841135991533723731846766340507156896681938103585480799073996134538888268575672435045918997400691044\n  7041116287865267920106161324719998448237152334997836375230143135132826955395290108649420581860439615\n  9053058259754001573475299749827230953870577210005396418869704874528973591568792707994416581049442687\n  9390222782002617388424638959221139263874954114195943300270846714237068128137782298487438922580196067\n  3229557664622256072650083204373463689206974257310148877783281459700550621125297094395513482069706780\n  9204578900900556359931930300746710425701791847467995201645098538151015396961735455277804306267757948\n  7710979913625936622349370648370598168419144090086928384175813696077026265263739842179275186558553400\n  1802494738842479507635936962516581598005490110797072695324488613743499388440836614685920902013874629\n  2972909384539568930915524703254564948483425584353927500268398089195124385714727889228818004727979105\n  9416493716641756765094433746540972890144063281301891438633928063344349424002602288104716999725533939\n  5707641070678950590524163290221291761570720281337963064985988232242671029826426454822793271548045876\n  4992124132126818276723090347559579303115848248948301417317193431046635619982934226608452419772743000\n  8947575190644364250704011573813177948095995339269155798840054782895365239563674165729648804634630573\n  6737117215809990209894453733255406649244555657047977207914581230450618880669347731611549213528598081\n  1109640356420103206503138783298144430856387206579389407056232795868744608528406980628390128319940403\n  1753698172910119302742164874460186196321594468453807557098722129647584261058043710144144891074881337\n  6672138354541424787136666538718207128484761707002802307713986200152328528467498051716009417700848306\n  0781630740674129158570458579809143541609290613494597096889257105679100556752900747504379946338211192\n  1199900912215396556317263329873593583866650018970210376810565539125811274256503658921429101919356774\n  0079666127138230714081882841864932545670050478902357998346296652053903452672297367971122296475763842\n  7953370703079415632893117466348996286910518604722726888778758797953654811330971852577488362549950780\n  8962383116823946505116854708626136402178204452762262185094687714584666765889994793710284570278582886\n  4945578192102470884098054884049428920275863251351203276836916550933375756877423110361610668383215808\n  0256433346454271722024956218060593586057783683982546182236449833541991908181754923962168710528049514\n  2246375891201136159799843803455389874368637941643003051303788958312792484549868399065860064078993352\n  8127851940984016719729727069932213390718420955178247520680268463616539771651234574340304432466147817\n  7119961085537282430917112635195011915381033226170096078197922946035526018787669236212486362488512903\n  5442839737923251389555064014239130766546753811452440247068376528064142487208913451379638599944935160\n  8677107460143274772385102847494666363346194172301607736297628897725128300258084687726530151682029250\n  8730013462199231565387199041060550741930363390184442397874423384998260696760570205353684564642727270\n  3489439236648459002459794947394860416671133571702812092268052781568833531326433175902994653857485218\n  4710972047718248056721561923131996627637828206706279778643822558087274035538875576372258299905067359\n  1541471494743726498397870576633115053342116121745340896541521554977462478886291183035260403687328220\n  2507089353084352345808150719569588924126052875718396496305507662860091116726175300728173888458812373\n  5985372692992626426660021729769040932291664578008028615731050138340599605215180202337467493294109576\n  9139999676638521753746488507214642276836486091831973323639215924903900069678881210112974635837340525\n  8687854457022214620873685872796641453017626335415588794059073212225394670737826546756081074649604180\n  4339579538721133064646799286122948571393385632976161785089115582766119790233799986635770474963796822\n  3993509579545082055051118930347793570244303528304428347024105904612246808113753997074287434351207241\n  7982710008293319137141928877140989863705462711361421706031603887715873410756266034626034693205757463\n  6326530612059614741096786436632812848924621727699060440035648313727017184326110762869070629628767824\n  8337252181678495208701873888835266818806885615538210291793846881259759223871757568737766365217279182\n  9359888912481290484999654764459655545951531923019867342143962690524533746344986037179272054279681688\n  9295558794575534131465881283310245574792805020086669571693957780153414390677074688444371997229473142\n  0962430984645053185396521906026711006056621714505652396167629158214100393073338929186256703337144724\n  1709240794482208195793496981155249255732540880883164819519948492518859797181791650718864975353694319\n  5763660262426172292425480056059572174815355934092538283243334477794234508946594682954801561640088402\n  3550373234965498786621710766801062510274472340547773872282337063244223465713099833535636179045129664\n  5359207727938793927009546601461050918027326975551357136549094051709869143338343735386223956625316705\n  0813221234673687814427618547883058500581078515556788076939732421220873066182620090830504150607987867\n  2078008638748314710467962218043947575563099086244244382809070751636039213609739671934940819820051893\n  0846341841851377586942138597002519235721035235978147565628370064989358061942774783767367165686044012\n  4253539425460837473462224960829827247240218753734151044388427140893032903966317059852727435757224919\n  8043964068936908330704606903363403761135669272008017206016525870166209246565318321783590348318466849\n  6336231773544630393379348923795838233801483524662070768884177564682572717136191483552894403611579624\n  6825347099957785414816484667357356113380319206582213549678296294583794899259090657150858589924036877\n  7247095602252060304105945472235734307619920200387034244022234909496718095119479811812317662161328126\n  5741888792671780402385780055985292325615688246765163590483405880044838458230241998417624203975028214\n  4203323781364695612918160908807052269274478502357943715614285496103309997013947721460617450078824754\n  1700679178188133730735538786796010124219243417398732897632280986762293745343728998117259300822232462\n  4375985400183726608738326471207255449130643364499510019478254452554256119854446896338619233410886119\n  0236636252006167177340726844487670870786339928851878574886890695595205756080655359723625548665768065\n  9973002696144997913863949137643343951178186561697245750119555271398766633102419936496159367342333676\n  5935189951082105085455865902404524395014958657097516880177298008199222597252891615283264328713301912\n  0720262250559930210552005936427206720674365808195919838946862415075380275165662282604255844872369634\n  2315273704964736012472937470582351894637772876085862713952359990692232587035991070927536077178731275\n  4815094035127013817079487040027946364336884277169240128264044475383002168060555973991115327567430425\n  0791689664936534610664903033926454798262450752752970355117029389549392605026116732805080636191135041\n  5038722553548052495030725922083212991676993938578960521919040226593296893201528053855848832676736575\n  6858379942868554314884845987804319937107848408933741977908003386369665963270004800753410733130286958\n  2860135928766135088569413072689527062211944465709013500028507817008173296936069944780801165089977469\n  8383275335446223117890041424456125659236190671377822188309901262050387138637461107547138243333426066\n  1119112499604311974873003557846753855809319405365641438724087159307028002233620240342092669248410365\n  4139246032528151391060258069008679246947846415137742530490811333748592565903252108437870583690180305\n  9338532970010969600087425044814184589259856965345569808272371276255400483792707641017020870006758524\n  4432577526457903618268036052623878996687562686845758711349482617027872642077405327791783966059302468\n  0537612528783622421631814764204764333456586924291561946174147929303267274533198796275905105825564390\n  6412796059960516294105583577003536563242856713972433093599861784854409718181725544777914093209591840\n  5016499843861280737887188167547887565056631963197673047058648946240459492697664532851091987443373512\n  1566448881451325097829979985682830183029271812658757997491525942142606638449347618236694361301000778\n  3474504544383940594638253164174696216796375403949152116008355340458730070341674476885386353724175911\n  9191257302962875769986698306028450551254255778130491965735370810975388980514498281958517209632887924\n  9759668785855762687283638577142823352346656795892694854891954487424195222854027581013272572588484604\n  6549518516222527214858969727263289515266100741919597178328836594559768570577262847855954488372407579\n  1628836314849064779145534872657558501119422648699624391090095948421950501182854570218987410345718389\n  8179048636464908296777315083677699733551507417008122025805388524519536398345318761778123182923384516\n  1492018946787202174802452815919012422558651698747259021550762497491226737659456330761660211943484032\n  3979914407024881734343302927257109286573898942406495618109097976549851184247711339007288092990163018\n  6941142126117034372249667476682598881833777489153001358002314602426047205527579931989940964316114429\n  8528316114869897317486423082626493416316845278016222869452176524878906995560991510960158794169103884\n  5956359668529361259912457292837693574949960006374540510293312523537194211565013315475373628090714281\n  5773185118592763310014484781157730515727741163632176299555971064374278716404082983071046305419155993\n  7148153916125547811264374389039745212073575767777507421150508298100857375238351838357539933202975989\n  1578248805041207059046440732276884830874353451226454706269409754445136975725708915057302324257356727\n  2108516847067390111372101828058046032247916600738326914541593198292432543374648604963396534224817293\n  8325475111403759384377805581002679023593384798958654860787419414168840730434173496904240691742895829\n  1133881573943227710156196247763551902402171274686278247219799676266290091917695564381053856926401859\n  1476166954319407769348965559060313034157909445519756029662487545487909111753269937093712638067225675\n  1463060740233445983148205780778552538169343648053568079452045386888722145805202281371652698201162506\n  1657297379748075002972339219097501220494749417006593929672960287387671952225506308643850360228641843\n  7662400917471903283390839953674746861310109327545085370103248816456357548955860367991893611297876190\n  8356737312274823781827018531064263096134724871436054931890377026133291202074118570203965492336859086\n  3272900347872223765989418631895233975752644826232284678147416783941758787792841341122301988055483719\n  1966208599311296978303388651675854462279134053844760839423555344903316330001247579965276168526319453\n  2930959627313146726192661819832194566480048912724042165730413638330422266489785155626456553219711447\n  2973260582132148615280100972768015104029896520206386068600459816142852374999120852093472923079773503\n  0153390597764783428907474877815173481573626882872884730960864188664530329476007533093585380277049260\n  0732884329411952086482971131759375253443889588142555483851732952836011377915329011335759811747590808\n  2955904750657658456860498951986993050662506017097078329876063046816009521097297787513601863205458955\n  7818005958757171911723235091578713751539912551505260695947605933157635090917977332083361368071945515\n  6407495330357188422563693171183439732516057365037747321453500563595638262474936382247058368475214260\n  7279199552510745513042443383364054939700333371348800299785946575449427651830341211197021029987336199\n  1177647930047649326491521909917772362558052712725779928418622127220259472957836424156951838904261862\n  9319498502398088279018227708670870719353980183576382804721762702614902491846340252361295645126001797\n  5449613122087284837388331938574020189082817678502985052621563352750833939410145554721256376368546407\n  9094647653816550805001796737374314099089474841691430065081182103990094191714290554428743486917780828\n  4127163283349333738760189805192382363730219765007029919984095395364081929393544844337867252570777295\n  9596138710071579214721837075804150054413498600492907499698937903488102082792506930057423601746771263\n  9825044479879477551383688753888207757212063531958650030083910654471490754927971155721846090155394573\n  3251863898128582468776959800827417655549925565263787184749887063291494390803074172603675896802548718\n  3739999619682932661224121706771339713788092520170262301471782080063916213598205297385505558209594033\n  3264708915619555223566380626412574791346382537492599128801431261443620117181006104722585841850028634\n  1562115688441856620282727660065536243416531861727054704601829523329536489605733307453064730077394581\n  7405562218010296586954554296232136268085193584500258735730586665195617446371811134477563610293164229\n  2999771284847399247914997524697574616765240133398871189935029199507259403541776788784275863173386202\n  1231433122324549995210226464191705902063721563648704410426983363333138216958848319812093693683591904\n  1149316234787276366275921545684107024174052979256942981914981740639527144786905118423433719559261231\n  9193757906211785809093205884794836305795612156010565182075216489529364750499783642596878804760925999\n  7018653611113136048448104343137267327149325176406779591282704180928409930214809574578663493779227121\n  3755371254949836461321910547901195080548163778231755318805404834474568234829552821306383035954647975\n  5313386037131657640783340885935945737671967408625251809781817880369860116613883471299915377112383415\n  4528740489956469028260300688542763451896235735546181582222140719678668431026826557381151949371316182\n  3492530436547791887277303957729166760359890682984979275326445793020562500419821581783367975832458201\n  6703344016375194361307936066877060596155074581873007405885541857077712937653954611123552017737452675\n  3650277123601026263711408502493754519972388118497200485295407605375755048633498517603934340365895296\n  0860734480553122955335688214567118057604758841942058349633845421653770202262887320328142627192419113\n  4698071535062364060488010610176139643065506664667145977479275127501313346596764639606994405703118605\n  6087812280632896781657653727506296728357626397482838464729501891798560482491985007991609232399766719\n  6476783301263846508088042831110985025546612968618556503500123610685297435664465619849209211012663758\n  3119546240112661948930083828438659999992833337948765982135588393330975965394351687477025420380520337\n  3382317893878282543047736859273772357478886566858736092568691056377446851131559478673651648492178603\n  8920469205739213739659762934266179938759886105571384739015869538001440033773942596352486926368960908\n  7053952625109612729088737679822241074767848829902625921417206513544327199164599833303338205097023670\n  3791891297771139000217964645568170138089418258462959876893635924393798037012604370001954537532094758\n  5656686261869137769323655538553373664018114260401171263453205372512446880839250455380642547662809345\n  0603910861511948831424647739359453611346263253979030531061551540475704318358069888911685088278357540\n  6260470081334894277564198811046150339108196697436038560732670871560877665885891060896072087471582697\n  0169056266871992681584833517410241095060497613332210304683200931629481966641786641089259633540386292\n  4130152476404151953276182470723527897727695774543149145720405417995318578837498108505057157671110581\n  5852167055220110024031214717157984645854332489073410987610992956496761565447188062442849337194222747\n  4044983798596475584133489410742608333615212077501929801512946567208421155076388164598896617646436976\n  0328924324510530298250512242680703731212808393512202255408415132029479998057513768649336556761678499\n  4713349269562577390784837182482831556792981972877868629036310560685800990722240215387661471364480196\n  5614811245388627165423342887561979792048557301929997500417588186220355084352693742241834775423575605\n  3467255495615418988381785602926769085061313659528803917355560245687971772310603217457604975950232256\n  2941963790630937955810449095876213591677865829539303065765309230704398675706257606714270638526055475\n  9595253213047800632610710768083216210014579464097769268006913907193727253192285262742895738950413768\n  5477459296033592272625266668352170703189496282724565284582414254606303728040777479798854129463539799\n  9246474691335524337231830453538489080808931525181357684852728589173285917464503656120068829470503204\n  7169041537686780019293050636695778550885505423698901222980877912670610523562973580602220182943158073\n  5552190937586577473626473699288881279782933393499869773523241375993155463631192982070653727478607258\n  9973120693062721040157239438426087560393263870639290221903085890987772201985593853726881479322882922\n  3698259046430933978816522998597111438879191681125563749831316110931906115632552892612058651598514939\n  7612705562408767671406059062759367897286320465589407531927159129511701844375575853523697820603460308\n  1114085616222042904289052870934871938753668199421196787160344751165632170440416053513413901731366894\n  6388738555313863682433699759859706164570626704130459126437284989148356890455609093481011580923180730\n  1845998408799090461574931098614313315919784060635683188419505707596210326850840753951104607136774315\n  0631865568117504568429109859360948634686959367227758077306072883798814246810034268587441953320342225\n  9222591131568718551298843839977181848177575276528687274786799756095598144332697980232246925174800848\n  0437354026738684446482509456837198696619833088985878352579323281004784980000165924072903146602815056\n  4724110345203157652765771714505108046030512975963903369048782270839013310400538514937353749729516134\n  8972263979021198896344486620188190295769295043464723057845265200580679906453900495542748739603331115\n  1334342323939281539285755241892542753368993670767360327076953407153977831769329985800290247380912222\n  7024700301497321483099349332418808211182569586232946518575636897541635746895986602665172871063731782\n  1154407328308409582293717686280368564515915257032902756903685712988312781187473459607417310097884731\n  5628386494861931043501661812266303769593726764588538380943049453023030268014210975502503890721484246\n  0093398754399153838421377545972464098687379266027941662047086632843876627366087827215003598927765170\n  7445477065383961960283431028523840913387237856397953682578837058304894726634813482131719088833963367\n  2412315363972952037995614054202652355733182260536030151610767270161366775347202108995240601901907310\n  7167115721315313139910873460499485588793055573290748667569249917791477776275257215331530591915437576\n  4020855624311494453725459568097025647576424442309047407014493872009314855661267386418994254949313631\n  0475961893303490949930728432409009866042964776416063621289476951726567416922104126791976202629175585\n  3059616058835981509438139888155464739539002210859787185924059647802767889239242804773232416801150880\n  9942907513006728614972737850416001553809727869101165381637602995600199875677105287434179648634948759\n  0228434508102484523242850619456464928288338024674531436007665393932531690693471534111025909155950980\n  9996077710819240434008174019090499522416945936708415512633504468374235408291264653803549416953846871\n  9159478644821690719718827904537417589786565396354364174964211383323912726608538295677462642204374861\n  3750869656038144115446781746318241578012548976258024056722181651902552564665510417840313993155273497\n  0128274640783796773431039575001167643501232392187217369395615725612096294658612581792259971229360156\n  0483252932466059000746753828911358876966050230432754644157727204135535343106923020990409588280284249\n  2545660922550473678663353597767011475477937895122163950391748837006069208321431310565114032165914971\n  6054503315260875624430397512016270444756654974450829108449142753286512578843201433719161950742434585\n  4267127681102600799697732731091087404071388839859302056854770568128370032410609948808912037233751569\n  1677129447677010573628517526922673867332490411057618836343343739931740573619353690777058069918700110\n  3875506825865123396341929847330966787573203290483700569033536216837286915868224849316458641309955612\n  8076135431583947979650364579844225293998032521346097286226953626724707628997177963276334614112070415\n  4148305304401967545816235986063466572733057403342467568253998855700384203956509771995410026837628297\n  5119707156928778058823190261710147580089737378346499210043057076158595322507336108729570271507431229\n  7920313721103151205786945818242017418320565151175338128457998173296130009722859113082820909053314760\n  1196781850383675303470470005787483609975909091296303441827655051198429426117421250174531088376152772\n  1032091623308833571020857721625950992529864364182068943965690856477512431829030183533951091146751371\n  8534246305851770744343216131691304544562072955779149889048547850294942518699230156420482367299678208\n  5432770817139937297136472855162369102809439490498095711147987353263361086154490921362107195786271826\n  5898464545958700906924924882052343511286873862691252933569556562440153334475671624094781182657115595\n  4756699368423562499979227723332856784786245269498130382957671588368253903484616714968014138599194055\n  5979179178582819757848123724780229627342713273807017121315934540225441686146416206418549556220175802\n  7171741932960403072428557591403748752412558364868478265305790211293015046009300979113289391102092842\n  2212628874397239879299987221712680244269570436408269175123947288580976631735219034774020783010825008\n  2306867481659929162142043785596907008396343174915704007049111330970230468766158574831350801444759928\n  5202072786040624690986245818371056631825492066663392868941642231681397853741745589835502398141347627\n  5686616221186367561134540185061230145050641464766200254793727370169115091057005880583855287751553568\n  3461355508881431374498563637773694334730779223692023281951260198833485319308413912969210345115664615\n  5817184516091865304897119538011024852574989315864723399926745372521914878779978880756267375063872378\n  0564697643526861306774761161564030889810722990061362029138553864683684245835443420724906526943131926\n  3630645579191032817462246523050868114539223790346999357618192283841178311127342660931717160547230274\n  8587000104786605983536876204234909356314679354437007086760444160809343038896416912293846293502166110\n  0210761640546614532826133025098992955391927596299462782632632116565874319551733594278724799548287227\n  8107931497771103534255438166350502182004755984571947076429678271587726848362361118065924451595282915\n  2301818089716722717634965228375068073131741445335093301055862157197336759105167204885674541572816321\n  7259397927018267765927879072697595865244447986278487669539491461017760577603607110750866034557555712\n  9623454066377584487731406580502181444145701216138894429425430127261439960397515488096841753887787099\n  7710531568960577955363596700780699856501195536169958191091853337403661999066186774586536593782895158\n  6192168358385372055171819669900290622524429719647760765792120834997981483108425338006646056465462844\n  1059597587010538378376695134144117115765801529197239328318237419072418270556211429248125950086219348\n  2545185655397012584064777459094161077898448667987879836035943067050826469850650965071424287984166501\n  3303364759597132945835690587596970583659840237526455951428415274309347600284805973744511548230400857\n  7453819441423549187838092922978318441402238443611232216885056243354185884325115447206432849620845632\n  8119410827058831893542884543650548453563300884266856935636428902027669230848663361182991429872638798\n  8068299808612394976329510463591338269125251879466945089415396493327345497299448983629947399175474416\n  4719717317798726839436024010521661014981526554162540385451779521584002495879879741049524800475355816\n  4544116079649674374767184221183581573767370489681657618646684473995745738638952849566518957447866597\n  7781950752258882987024789009640653185204742376952389335501218478599660074089650383859514701804072345\n  7768783856075809561645339216884897542598305991753761013232063543253442404886000030908226190037306341\n  8486886143876373649417887401204826095051275986339050977024247252980175882639229387079367325221116705\n  7926441409085437401485304590250371696374774586071914054256943815611701443788844188830915922927192035\n  8412987162286685053246038943565002307341670837518645953680252758240520923744676573351270601601170349\n  0806822232723412140846959667332516156575806659024310130320641153751168740775678740603592587886171973\n  6349367711142654304847081133303231866339855094943143974804840787647767832770534880159671410169844356\n  6978084548780518231995756407397883177027113564392420445203330076097643679699900409585495562013135848\n  0587537494725693403309091728323941836921932491518687235477393921275611794664018511800138075010277721\n  7130642042532655536114323907882035094537707508434889230102069364851728497612938332579316328040240236\n  6224770735848850558619602148189507568896146498647108584644537329496552333726418838326212711782724069\n  3226571570786417557289614533829164489186520495527295263300281049823109857339430816022566981711150564\n  2180307494361107813613896822048773651856670209197871094272276503470633850855008421170940405082569924\n  5756282826278137513327080529455232216084540576543785400717990812768836695374975228640671461534564901\n  1269387426711403621513820477587549428565722785336658487290869174951010237587497660723016951857365090\n  5794918186915420495148189506331367232336001791924439759401641677198359451069342721729348371331527082\n  5228587814764495406616826606632817385906468170848098019563095401910023030383772107483227813901168208\n  2582389277936139561206216213391578640790409627777430623945887116813593241244337109448308742299489657\n  2704969668919097678729567856837491826622807594707308763909429179184646728989350381665716032383413004\n  8221490735573101147560439107642307049971417179272249889362511853771844565361124353668033415834710999\n  9781275045931072949201640040438736891084890000220658968949509883554543303448063469068362642692622526\n  0480503822296566585644546381725787202422393060316745016053977551655424603074325691453841406677000933\n  4817262533785783695496880181971420758304790250454493294344080654706966709208196687180957451822379033\n  3116866601065885464616222513680755807281783990499382032540352222147912787357337924050581704793436111\n  6046575203509649920300943063385151557010396543615600425020917540836802510756962724054007061307391483\n  9978215497526962006777174612537517747408077042146949807246566921031380365590139144631933785249560765\n  1289588470395683600524056037732266484889767598647222236870457260025131465330278949073668317542852793\n  0436416844913090148229779444145397767000504764545394419974425340090220649707950657786676256257904167\n  8795171932282160484279042228145745555525850110505111853205128248170449340850065111058596796611348054\n  3157990100271163704146255884514695315016137653098634679351398306442172125391421048484018069955555893\n  3864698447097220729204416001744645744857898852191332549713302548209802199209468670551308850411232159\n  8940306060776407088621530225283963061061498449297470451281206439250952683933163016535406892928056518\n  7157265787411940217478091727995418741181137373534823204924028544437285424144786673531720397284099921\n  0753385213768521899202754763751550880323820345141044903368786105511397455564453441335280589331495072\n  4154536504253686358765114645577638528618422250037354433860841945720257808362467051613544121936052124\n  9265478557979011265815919933225542147336102522035640035827908575507305278835431594674179374264974074\n  0947948944779573166096230217323972884026016215508990745102462967183685916037890598163574392667278295\n  0299181795702806863651012454451544131814296541845245197887305202002880204338955209521262425068207362\n  5164648296888315050959701000226437213534878582602533578984284992642598493826986555915745522772230447\n  8367004512926203259072844700707182646394299397105796504924027215130909020163225789293646620690791141\n  8909170955485858170999693984582418886230434638646853709469201908664425001423704907060547944016363622\n  4484204946141454073340772056136753779947174346418696144163556429471591970959124572988939233815001041\n  2294395852881242903163818939118293640475674801320054837776422413083227337901680551345611878652637873\n  9084602983248449677767652671446090984272409221944208729050777247422712849199862752884095453612244260\n  8122367302636241666463676956582340509347865011435452230172110431829674611812712477267475584183473918\n  2964689242439083589830410778612221646674139274580844109344670914076889081154804269904644766179037069\n  1318643164487293481162475314270947951218371189543080160613686742330865206856839261480478445664749457\n  4832329837112783484945756818482357381296729860250944563100213870768049043011088410435606595632913551\n  3636595379057745086346584183793785502138550730660620323618920265343796554240913886678051764866023556\n  8680102444381998217408186830806326579344501366069588311635276590196371091221683021799431781781159756\n  2569334811817590163704539548800254386919502939484296333878802324540268683115920771472660964081472974\n  2564135237707132655865672926093521313563269738633451392323794912727416044071653328372766636069920782\n  8988515818900740681788356003383955024910544219136949438402592897576804164798738875441907101007388250\n  2600250529371571205988217997519052515481351289265070350312953887973951968071463129797393988552240677\n  1074781329661125142444094254620586560563864841176973765093222320058137389888598930223363080952193426\n  5228150675306773116834992003074978449533317392356287724988901104982913538099432346738706479293918382\n  9847365091741599344224180136090702185376839482371972551488138816352825082378087561773037185933102376\n  9015518148956680264510669556676356270331637550428218469355260793128677171630081522970525013994404111\n  0995237587821689870722832415540437859493648816597106019417011177530819779600610206107580954184382263\n  7717441589308934402454807763589859838646004481913063291821212522007280634089056273136156282514259729\n  1169096962116740824716314518917473600695966991423080878338378686590159867022321428691570141424807045\n  8972191054200479042072618389456591675766243374816523343101319777787506264814478962379685449183339325\n  4452263282389839955214350864723998824618234678333412034969696346523102970980070312729811300298748758\n  8451556284431013156099089461587840584003836145430627502838434516836793994311551940672336880332618381\n  3019065159316862019183963643881182869704116494587694221136576981495173186043944768192239400670145512\n  7928254056530324642352419083789115209165207534501147751337617613160303463500158304324119830345045973\n  1115480235291472675565285396154982517322187028118914755821925109751881474996270183201238664665544709\n  6270322119673520668256883487375964507251207969145168739639987295089292861505745093918352489864171151\n  5633710772070437194298978525854106512202087219851152011968200668515495090775699216193168057612255084\n  1079956447357236211513844260591187852361111576674624616760589490884732188251188189165372941301847563\n  6508362290409687727075906307595173734465381235816720569986154493374413551158082859997972507000542569\n  5844829042157032963296954183720611253277818507824353239187267379753901060421898213335680014917629276\n  3589739749151033610294485487554126594588308262730872974158135998785058970815642932415956520572243886\n  0158420781047504262811290442552635054829661343198347557885193222267186930364566727102649599400511663\n  0866373172740445456949737487485211033177549364625380611334474310806832630846622039370773105244279995\n  1374501935266142352255141868055104005021438767785929901108592518674991313145000872583711669369824976\n  9940841616062428406308332897997161870505765196240492431659995151896649754750390011473989031896878326\n  4557847453725180452235972687766876242850753816616792488000823409032034807146522890222308061496574270\n  4477221250266192371423562609291226018250583731811971039075175338577137807762131772452879479158317148\n  4322731473506837177881579852023035280059999869776669370082267088042043304271761036044360211957405318\n  3239775082537624353359925874480669523131409508267297420082719591871616960153406545781475710124329470\n  3404989011724031456270700708589135551306594748305010926753310504767668510068727953244323689649387243\n  4914018868580217669706551588502561741520703150927265145873588577166907411895667629416813405784240677\n  3388665298433582820992092796000256053731611957486517297171140435836830233310269244755634963018267857\n  3511105639749473357081758063298707668034213096682726128479506043615265442170363554065832901954741126\n  3216179414368623878244681088510060879820657196947315316887276558292548410060026288708470726414636981\n  4546760230690648480001950891529208834752002948330118357071474860460032318036646630113783461481020801\n  0408241624643986285802753525405414811787725784498244012153580883263111576793883443994167425526718127\n  0687048579050017001882766115402598966456382269528408612570000031201513414621462743588188113752159623\n  5509096186934825303819680850849675713080265221001754452150438824469635391354522294838227521939781610\n  0630815713947347571643310028857201156174719192266771954369283128266043960699254637219602914253777973\n  9831674438120809721881883123622660338707532678942538559169182977283327312615508417484951235989157986\n  0193104630204088365812328283393282877527485978705364732951561411429853246103430255531301949643011670\n  3792865637669569854796374437404695144047524862747673802558967408496302725388581738320957777270442659\n  6764502346241958872573593386155268081204775136402786059671489936812371201186212349054817129245481543\n  0238041036501487535674543111800604500426130787682215885144267302962084048226136949742620817609999350\n  0334461976884187903041595951539264111965464774820849603536188945761220485718626461432327497191880858\n  4172165024925561228486704440794528091825391444698761813663319439606463782245081613817787292827839764\n  8591104634556227172221781769229741153867862146057242015889821754945547494863631767227436470898021546\n  2007325013023705721216266625220053039613516788310130085680167987713860080874414496085961030410411974\n  8536983111367107082479747419717080824301691666177077131276333136381545315891337525416839840847864317\n  7506675039488466367772146792112185361223631672188803806610698593702379096318692240259119146345846149\n  7417121925501992547479600484600633459818646080115937447037316631953518908792056481072811877724020397\n  4402460212973911013499269664898978223364655365129497329341543406894694337381826637786050347493433270\n  2908375618011054934690179339428739905663796976347810695528961987646189850722086345874757753558684468\n  7233572491790476548077510392373639618546675333495970891747050103139694380902363404579903070724852963\n  2851430888786688074249816358563633931419476252306615252056589630703714209157446786673768335155822444\n  2263717555290549395328823666896153326331493583928128224584932540555941071950713799703563742340097316\n  1309864621393795308709471653612565080331578504457300009414139460014745254414038169209933604115965838\n  0050630368254566308062825009488020034180021455841755463480187653567764411516477104384366900853706116\n  9050325303146835437133581809292400768050958188888031319229966049866511923553334427159951307690820852\n  6629677403102594730225917768201325910777315857844773120758864509339877561872662539383623575762515880\n  5620309231213866578072162611618127003756053446226349498386252566652422923443651396972082378259957626\n  1080998493754227356751224109232447930724282802917623537533863708763873518155274821112448002459124640\n  5111511149966446261984339005792546353949622888924362325218640252481049059595540836502868935748905420\n  0091253386743431340734226519599814488762644831855273277494122878561306225821878120011628573521338086\n  0436525201235079083015059632454682818922475989132871694359851422675732581509249821248990518465907278\n  2376396492321190420564384917255643187344162296200604471901611612786080691597050723383179902400106211\n  6474775843902375746789131695701182264621770289457119136412685871868635824932717465627067280751367431\n  5975075657747583764063380449448206683521783321333278967763836574467462017288395723672110981540162132\n  7006816874023136619483325010446485646460364125317413333237960756729373305212297457933352566168558920\n  0437596251342030638342943060971584740953801974115495300102821650559592594591948533482273271554448735\n  2136534472942394955964530478805317945586293418901077793490276022180849918514125716531651374508750314\n  0146677425197647620461669311332604538789645165729084386151944311401615142307022471639399010043790686\n  4103416236790741850646376825660389550334773489673113343136294285431488760312473133541967098000845264\n  2740142097631369587622585910093111299737936001355335292074829853672042761269847640066766986610534552\n  0728721873818067910581629074870107673696521668734487874382771997327186492554248066842383302741069609\n  1855007115354892417444079433704231825456068386702420523393305803173064778859332292996554662168705712\n  8180663158107596988037954190286710515896821839986172264565237272159212726998561668843085968396028717\n  1538526694147931732893545844953150218593008668911797136649492410539530174013607858891547134085003976\n  8036453811115720861295639470964557427082387312687498873097059005337318346168969341709300000861680278\n  0058956741522844366300229652650701385626568435888629758589271228973122504501939753988019599295859466\n  7444885279234641037247334135338390259480773955176406741476465801453303755125878391520600273054598058\n  2800834158675087820218298029124179773152353857706406771166845213368665010906443991846647291438415228\n  4355957780524178692213439026209703590303502527032839798676548711129716415065768915393509094042163002\n  9212623423471285210839542166491175188768489016016350794990872514594428409076951969961803771282792923\n  3063139463215096579366488528671853658985428232404638733828178481530209203088315697267343925583364321\n  6320660898884580711362776399966495706481333243008044307069228179629683286131639498341581788714262196\n  6549905140449994905132275832902039733890285425751366407428377198389513758460356859331967636542297879\n  5979675682839983101815254236665985727858888680648518945970716203467370351680456789741083210206877691\n  5310505668766877329334920023893505744369544516023429794578060306718931576795190895808112827048686785\n  6517949494253179898985455846351101662924150670161176221975729255773222299579570269514273134125870360\n  2132593747642947677233855393949608034943296308145907993381594311461023743648260905274892609114997817\n  5992425233969728695252416687315009238204121285426136163532491366251378662874417287369277732668533899\n  9050914428805931696176825772855927778554889122488088669629022220090710531986727332035012560832761865\n  4686069004612176551141034532831271204435229510016794790313350534253556783869192234312490521332794361\n  2569046803304540642593143348598935298788225495318574248810376413754148449982952274890279695089814986\n  4690761644389575234356650649798259415250324263255294411659694055989586650761215339929748641052808309\n  8879197123728761697290730295301586338095431940182026691046931393035266362835832196293419502205582156\n  2811510082783702191422318615775289443074012512069822362570413511621279344747937375070858534490402518\n  9467769147420649139024731524047392237570356833125539744473636977591310167248556425227049855871329918\n  4758438211851524915321086608709389477465558909768150090915524531843711016797043942272006065934727864\n  9237655946958471716429025786327183436043870606152679931992517807196060181997889618914413296815327355\n  3656553178278789877045484925656831540484336866358934827911537849960146294330178535918922268713560211\n  5638066888736024524286151770771110671285143971739462566840777072585891951865720028302687827488064624\n  8625804514333344541330861637868233257296257953800673509106053396523255759682415048279519619749459051\n  0082179623656701477056459027478980181006309518889621379037693653372987268128208847887010630825541585\n  0421334101495828542771806949463381388168245190344480504922435510003314142920894225768313480195104195\n  3956483428383168994699706893612395299336477360596737956301617803184226182619920816348676196602758664\n  4711808760325300708745350853575490894833166708013253482497118067652281580236070823339041428117022941\n  3525360033063302611245516864922753389765333275088373087354659141118979834197708121109080471374423563\n  2419974361958142327674056004446749156949455787149355479222541764298223075736651596039395678729520830\n  7621299572905646333279790560873601966838068415216005340982287176820543030494829640714377958967789178\n  5265134420901479656996958603321761028398322325242090918749756952825023624449423568735010347018741990\n  5300293809698609087614945672871126806871959924240064653277115700461234695506725963015667229090544556\n  8896694903638197937468465866534067955971944629775631645824343862403793489804730057570983951582161392\n  1444041889422681665534895414328206155392681993338132341431398790872065564411761005197910307921159446\n  4124822986954039586697896296360224807663263111856093817090755322596581714925458095004864281930723758\n  6533109347410268460883510176552329792792588642969057722571390829119090719641708538459454433599189629\n  6182581379576619525337770939593093755869597915058546959060081600343557079220572841848585599616477156\n  1906337685043293655454747429793082284034010421477940049481806545729224483426104801520489332597893682\n  3575947758489390796539861320097773887838900230664965067318652650568283958219625803380702097089887141\n  4621585654426237525431393842532127573407453319116295517118791369927035391723508149986623779442841884\n  3345714929271033322663099327159181177798427378975014789433268497205154307237560639987729616687253234\n  7099071746405402407398765307649992827255557333971022446852281974406356741544233989522404042548339769\n  5537147315990391151995816094959851210374536599442439645586621895120731402017735567818531957450015913\n  8619106408997869328313648390096137571062723478005228242118426427552831612858697601566046431833533610\n  3972337460199915388931573028588269160920494884541300922625883777140487965516015543593745110789847180\n  8847009606077890762206936840737849633609634250958470825725633681267006429102982227999157619394123050\n  1066561932438529131227088307156747196820218627201948474469147750995873774866029631262112393626268432\n  3153391719356913789891966066712770973432280825198475061954062034493330703784267983799417718823847785\n  7304923986255856611633528615279571343531452481039163835170550778772229762397920840708871158662399192\n  3319336495574109949375410066796880142650207310666332190372968824698040807054186317885193804782714122\n  5654179999425208472883282034768584897255257471819411411100417415667999996419753284032409331190631921\n  0471346702337851518168229866134384617955922289227272479295126971190232496391380440439957405009271208\n  1861325429437494680803495274028786638624393417108857657456509859476694892184500640546563007857601863\n  3790396114271309657046386091763460387568116961674247700175701209622415995297606038534885700148140313\n  7001128029694543163723511250880211913858542622105689948995183018091417190615926369347364953071541759\n  0666788072282014882919882051557077635832956721911220357704249516850618829530889889133774280092605574\n  8231190883191031319392993345592313428229082449525800523923120354684095918118037670041104124295206004\n  1674976055582275384027855722899442909707922037347988086735001702235402887074872415687791506214652489\n  1733255247701844863336042379174274985534336281951376593862764032817426362481472009657057617273393219\n  7137016249943760722325613278742493777785892693303359640162133441364984027113913384274707577695437786\n  0117566491086194270718291744124265444598136378594344020432286589754638643482729148367579090612462084\n  3234390391923443343496772773556111421320014394443227320381369085729795736326744778943865774890385918\n  0992598862969779258913747052857795461303205433036775220335508550526418524683519492934683524328602941\n  6899457532838210307005971426445390140901802991823336647440778847072021623062385605597582213448377296\n  2995988321194341336945834461478359693702832682714104848145288290526166403281494081840243768279808314\n  9452046334013147931875223737780641449565756210605303373736314667499714281990742397055859815350366620\n  9046505844835829037062788217951701095497639603291046554060692645863021268740270333376287090086360775\n  7172312759161950765391337763291958221560239574342934468871298084612180268971042434170908330991098588\n  8888352540859422769177682881207561794396901190756634524170061632008101418475332908113003093109758677\n  0730363184254529334530976661529175236632365647421690422806169751560533305992507917682502236464599957\n  0337747610841475018859988302655204068322532391058724489413214920420150763661972890004060592720424962\n  7607199929997651568985047882085190980357331157415446555005241314901243989950767377911479714212766615\n  5536570002998064352235855946334029151965574477372577452551736846772411482287637268001963584486242603\n  7986498657582130805125486775367180449618700159104473879342430418785461787045785436649442843850304116\n  4819266671849752526707365839930254006188659463004425934986421887367466779140102899219351903419847325\n  7602258531948483933820611464807036489978670865314053173481514324651853400564085301928990763601600914\n  0767076874864987866144724164384262549228598167910812920521882291519447434704103619261982249688650183\n  2878812286552614944872433559864067055348866764216076996015355082328241827071561819631434310929628040\n  5256938017210064387456093585636653375409615209936844109006423455594967899258652717374982980371763864\n  4155408339933247328130954900909116944267647099606051366703401744118303662250489910202822410449800530\n  6393922465176432819632004447864310710645181829249015547074663013665850277505079676669447092311169507\n  4284579269198646547968976985744247120250261993627690491868938537969774824130205607630433892247367574\n  7538314713417546782974962447706654093819818294053395278667728983884828299114239277363245716014373375\n  2630480263249421654556576719767519347205464994425160098915085265375080025107560543265537727234223071\n  9696794527224661597386602174168903912272254713382591553228452515226694697281730317552536710851911358\n  8765425443579041298241035431744232764343271370654209963215706364060968713845246245663352691301220789\n  2078038541203760206341195539453469466949309162079581991165930757419826929877866650365908258531021071\n  7015018441367529138484739081922356470866562195031986519855569037476710947140876135315487181593027818\n  8382078139400086999967045174005890292947204951246680739095172243055169301048038278147544641937702694\n  2493272433681252024601571534861044060759056332037417883714753521439572777882746386184160872134325498\n  2369004837382182638400925102155997628249241483239110024692789253625384807769987524168277515798144534\n  5592180912352016230923561872620356180637137437050124625681248863511622694756689681361908739138611682\n  7810422466418488137749163775823530717510933636515920783202850748781773294567957228802702925330393035\n  6296096550908111234599045006409831462600113397660037298133881316144986246073840041038738952334677015\n  6047656476774375309135303602773064948548181815798555845871362783153768046482215248418050024360485920\n  4248195328836784036387899563193321631831778397529919375524219659608965065537394044608982289650830886\n  0509089024965126472119109692294038660590913782666359794484078326763625443829738263161238512713588318\n  9511072580994198572394263896590594982782417809235047599580728228798338367066100204159537645690875936\n  0820905304646456054983510903778477908765197460005749378268569622689236564736896640023761421391404088\n  5302285301422924022934239184746072891824401584031619657037005116503748328361213051792767920294958449\n  6107578731219312362792490708774704940277207668639512899595810379182555275737019903563985512824029479\n  3513430470149853316341488272414708705113722107326378167707957042443525424026587849103230994421850476\n  5710476292622152637991177350294554041471979736189391641364679582508105253622100956730870705995351102\n  3282255406880818424246132905503411246368206259564429291757401920097057467517837870949738346200035152\n  0235096582205132349518812880974170138280072774927060738429578676545651223280696018735927938422502982\n  3945265456615376890950037612041625651830107353700390702915020475371427789436880591732030271185778991\n  7666634257164269537166959331831417686469920393292873147806545499610556358587858035598893825325627842\n  7797527748695905829017843531703864196779140765048129809438387688116335995347497834963258404256655648\n  8352302309715263896108526328413993551737005570157924331455713392635064912691032874574336801684708832\n  1019831805725899635641749947999141176464087830985873887601262243929152513512743163114240916595798544\n  2311940742639141995737008193686324395428889189215907335571177725165886954494464905156957324223604942\n  9106113988187879781456923008256816350893376885360878491509761407672722017652632700630404298829853236\n  0410002404018299071505820953486678658549147523103917653043924444519665134251485886593572530618789331\n  7329084163403552216474104154352613758218181879127906528210805664458170081884621209532764188236193739\n  3715845416545004613763475572691672524761025578021119822121916167692479946814851022110835468697760470\n  6507970232697917944664058254587841235137839159878685765801747173575840055450021699156624893432775705\n  3162343985746512112556697615957941655004309278395806436785620176109369534322744203237277829212641072\n  7927331538805426571871952314614760851241207116214537070523460987352852535263985551737598862152283252\n  7062331717710576468344207112184896971626329212490614166624188760417868396533520813403993199974584851\n  6368676490886859104526807873062160502149585919378227149265333228609685365050398614037995783932359268\n  0910778905485558610885924282242259277447736511781827001981388531607305680336579676271784577742916999\n  7919369629629072997268103049709697061750361784872804915714553234024897008651825057184139097089981443\n  2108632743076295346483010602917603173983162988558076971443395677290152947924948925730531036288092988\n  5710977420343390389424177496084967853115875752446072106263522179995794483282496498179688087770356049\n  0697406097558151120951620501327709107803913461147510049698677195780467282368221758850855512187378823\n  8435502397135356476753128488751114558439441307561669080219404705402509256163887305799593571007095421\n  5242402389738661449843026964361569759383503580008652520663448232509342891281594682468813110767064807\n  2715392133808549088932174463059788581127442534488131962175507453904692292260778682863658751566809447\n  5047862672273570769537148972648601362808015084422632659722114711872171544581877426158697079388695592\n  3103553477448442710277279181265419391255476048443180934367966463340428283327337418506298654994600120\n  9056686091094950352084418389916340306963343519971372234045101839365628394905715741199173881420686449\n  1885648968163335519506600092884333252480673558417133749617150550934263718940232530354259938439418771\n  8742088145543543561643034891031481520576588694447827064491099533521284325191049124690543217380510679\n  4185988054401289425123258990996231232405387739821014464058496559741586595232058144988525103769306549\n  7489313506032936074481814998982011182749277815201132404643038340009302231080547259597551216746706659\n  2294443857107582935686515980117901994804535824717234503017639891490221449489021601986841517587379191\n  6826610983857384537652804189009337550323487675887576583508168084898048899461346384675835827589450046\n  6480260224707959607311234708701901229396384219925088768537111998543312937242948475788361151740833584\n  3753310906659427013258032954398152692068105480421552102479651145454331971153057409954937838369320017\n  0656410239939685203415131733092513860829839610344837564348547094563741106045616668328026369760559410\n  7860053014854032125282532232725173232493557882265939595083733400950598453008448615493760830772932369\n  7805390206948984365228679285807815810808580649532633173056468160917851471254000880722579371359859196\n  0203211769851661813820572666448797145605056476417427368418914506734245675641604829030981897917595674\n  4799704418481543956047023378435681267617715798737487316524458821001641061928767152951977309612579504\n  0132799512512304460717376533044348897583775022006741467780169732280054567344994253724138458236775963\n  9957228554593078385191403950474413617589100741462268192976969498861286529855178802499331966356382483\n  8294192474319235584267635073198580303015343074861824378325227933579938356853781132755653864730024767\n  4306723758445557066433223967058378975019401109845845303120397416081495286336512248395115142651395213\n  6199492804776145672284844312856596154497313827859533076736960149415863707036217565867010430358696114\n  5791714834458205482295971166547021136277282493540794629070601403720169035778923993263032726072545060\n  0403646050283809296100760006762109358216154880968279818045908769907558279711149674858710365979817790\n  0559920461992108621883339386436767545357823633698908816193564218210955951100939837537477554658607786\n  5594330622484912789787545081355800095536186322477894557821672858215655834857416920557822343615032535\n  5191306945196005289498694046865586452883932391961240439959477905755435190582258127024682573216026993\n  5312376217316256389732475711628596069997082939495981464546812429119289449321675789363587752365870831\n  2626129768952214037121333371373636570097496111467954738940216254866841463524981486568437129932566103\n  6903209843245244363745789283274532540101378735460870857849153391330184879650215888109299037143501149\n  6211919724372703633189011799293100919897206605891949918385269867800580939230917378195429850851684668\n  1299233425946670761777675588620801261412614640886156063703867564612888143788618168840692105737310071\n  4712755602825523846104942873199498380141927494375100694790609597627570407425605279204037351322564372\n  0532009690271261787884195824392343316525246682094254662729793482420950273277702953598156498247338180\n  6163938715477491975350493217917432066843409206201758084778305188754961244239520118964907047660186063\n  5733321398793734673914908088123513455137740715586822235455884575446863433377540313871302626071462240\n  1171706024010652254911986468430964157219449244602828173252536670353723004242498660648053112750195435\n  6523225687382635156061797817749036314750495732032582722820879015800370394722078471144085353021626740\n  5066505125616695005739908327325068995212697526160602725247283665244676995469356947594725756685581189\n  4258537772576809839768588064964418575387172908716236658429546000645728360531387581386362944104313462\n  9953741827762718530615919342612177132010310021145256576690287097455533109073858111289551403927166875\n  2247998498749917850258926890214824595782590518644548253086709605415246391648674819969569196375971963\n  0398096105803354613278943598184350869745259200054859003037296168307195762268543536417311817450957993\n  3164776907746402740259052553880918629368604586739521133104685547484403817107250663691014557314738282\n  5053570575661393917552606951868964925034468664749146526156085505037913942029819942221994735438231783\n  2230368471373302474855942982638040651298489197127731269793994244683681397971930894515313010228207176\n  0241132296391228061815709537618452022878633617842610353107341759203978291654370239534309225910850108\n  0565591877252777554800270019294614144153767227568255332141737201407471347884434363167591614387225594\n  3304949771961233842226616048964396242053267797041430802411640119680891010920634290380279255156967953\n  2441619283486641083828605441536996436593196913777787005936030482022913026514592296134558029718272438\n  4196876724370844926367550705633405026837199449354732652656320662743808369958263351676070823549529856\n  1583433119524392297003987910675268314944224875870597119750135716880807708801638578432778181513027786\n  8311685891946114301089589218392897133594139288856488545091637259398359742076715707460714975246059863\n  9896695746231577768604879720148035767956484589821970288761612319470132095592421448835550576272323443\n  4842642601175322306182230356585080470110118991932525717205499629266412977350428504370262289723585281\n  6267563789630203898474355948061217387390668535438453039293129881938833041183423778361478059757505840\n  6622541336293357809319478196639297423503908480593200697899176788339686913197482588647470862799713132\n  5613717273081653340613946256855059072754586450686465652776825553429721408833837278820102890293240313\n  2421020026106356642443696612083041768693220104899345155973211746630090867120083557242052922510628503\n  0294066927058050440068181922735142563465843548110959320734012749694900025447207973603791646697031950\n  3383284835516767605831036545270857655498002823947822313718870396521642078414038632005016875592892442\n  4891643210796200313711074626069359189558182399883659153109700423581742946007359612474329057210929097\n  6292410410656620923503792443139268903030622034078705847521368443498140066439968281777288328306808296\n  7474851072684228563950311923967939970227828083290403918794270125640317319867054809038172901093826770\n  3276181873338233299287354251791214674169684443841609957921734925475411516955036329294606721879838177\n  9848868362782909979843021720417536252229967274325716308033262679427008834667993123722778928049072690\n  6343593863344827373494687180880694508882406899726165871343751874071244353589993574950576391055026023\n  4884831930109776287518455556142797284284876039387213049090254184884269775140116269376139550458568990\n  4730039876222569569528522702700707002236312782756472091890723661453383150645086601571667250304425313\n  4573076142482529934735508200948111074026427032879613545589972387692438810975970444457279722559558214\n  8318579221168381920223766601470535503329905663899611395020035590039531431485319997339561100645962955\n  5821496162158045516324961524984625491338666155661305747107306606494761259251347398672404294705271394\n  5870057114461774359248919999779853985891554580117570754584198570746444171573528708831815566490671161\n  3720524842124067568833334632630939467440591539281243468652741507636710833294679930796012132262362971\n  9228890611294395686589067468858225888839891650188355330752331981579035535868551557820654682183321590\n  7429103474695675663392485415223645371500388621789026343137853026622744881799998738533234152500505075\n  9944529160103849242964737923144851996764003120426193110183900107455976932457439965196822111570172250\n  0007801852007690927995274819572235224900924551021008329435060470903821762340123527848387377273143198\n  1235331216735074162478419546325344615208289122378046922908509386280752677373364891675275108867186907\n  4857315117987191127589737172122200697902686270153977033376235391685730235327780805150085259817532955\n  5080787788667281565096669161583911272169869938875911268864848545345289838450017200753178809612734774\n  4030045241675032393038367061707101305504380587173067566833533745378303685599937759086951306218465528\n  5792359339174191712054179699872561324532665773975697093217056219380046148285749989375231643513474707\n  3658820981060577886541651473248981787009463013850792559222607297152262038819437484391431059409599258\n  4334465657681739689326110459870100372754352511637744161227299994101861956605142159694120635513144859\n  7195452860809748682548745244590362604731380648393797344681866249700721554710601935002386483893437562\n  2763501279258494173264366237202327855359419493045001115249370114763463415754264095574739430694456354\n  2362081212241176373576970867776359301935638364440288936305078333228036674743943248657079895085250872\n  7418326835271995157792652719876374997907620843894634721262036078308173814280478785549782897862274724\n  4177003016325501339705372417682815323516176906921997025569996205464243726535775472510240312994355386\n  4594831470194940156026684943031837836936554661866566254708258607489483972825155891603855349506451384\n  7442211882756298620633135692134350535417532546229427385701851422160479791812391358185702336381354453\n  5711277117194321660466143101547419821554929047562109018957208060623490880290406785456674637241772486\n  8119007420655784822192950106596683535208679087585534490092713251073537813112328600410529188355048282\n  5682124393180978579666414416419743846503597543167041838521459077943357731496484574214860854886745291\n  3145745893151848342050585427211602752070105302881218204425718504079717735193826444151430340000389650\n  8354760695211261435151449409699151517833258517247989474052420610045984073638435113829829335370285516\n  4153281846898780435921758197601110371882601157152121989928035754608388740947375220406391233628982806\n  6187319532355292040142200095154808807061007453865639725897080303279855124057096752994877525034838119\n  1484476396069023998008588751011612900600807691194381030260949480659847619690480593217852139982865901\n  6361397294733342452975784299759023288921228876174536434315837531437849574608874737342587958758219901\n  9353898142294239179415156131539793025146413798608959887675413694323040487028555419780922958044698990\n  1929045589068465978383379944925127160494133779070648657858949675759940506175576329347568082892202911\n  1549186488201592146177654499211827254988676568962251706361483219514060308448688429474908171412276698\n  9529766528467187010729193377929282443532431382852063570615807692592826032221194027687790429240836532\n  3232151023540753423210947605321017167804788960416851071973969399186187946346189679713546786722440290\n  5164443964782932669463584918661504011655032137958238846403545337067500146824508939635084079633883393\n  1644002155762948765545149622984945735704556398458286539010312031199558632978985996427424165456402215\n  5269311761821934040528049770013958185699504506269083218442209858065603603966505204050926529449163112\n  2474122439854552334593973602158488959564576035601123947226002909110232358183270776031819289578931912\n  0042282972271927680105785644667334020318606579759989767363004515534412122274649211784192104299302330\n  4754593408148695733885585311878925724359962470195810494083427130065971636437516574637102498705362916\n  9290060997979798208147147131128995085184920039864046146530250994914143403583695568842161518200066725\n  3985853203567078753447410182134499703959178739753496211472367771510750644341932067097848101390611946\n  8142996565946949980301501505043949916581936434061754712006023253305100568566199539885210969917968103\n  0651566276114001239394412740504065600221709854777964424685874863196946189551035133391641195903971893\n  8761054426423024644127859663201484795527322743409286346200984059824533857638615193364432098339181957\n  4962950525271704159411032941605520070797004452742655032910680168291821505488657297908306573320056671\n  1040393166428946073974276132720699137735888776468407672601645037969090673762491231815694613258421465\n  1124301808862838501872732082930493205348834908022579996208931538204345874620625236296812240775571667\n  6147083325307435180280156466152412335772666545968950153512096407409879933525112423683932555080407795\n  3890651359848693148572687489949014085300106254036984402433985738212677629454919277281927072710075950\n  5419454503790918051636158083628887001538672439450070274989843218556764740324714392366484341116062093\n  1019601825031780683539857258391335713344930361449170866597972333881453092174031811747752032581674338\n  9458264967527525203611262736721097645431340238065872011251345146117238016383594726875228176383566558\n  9618861321672998939401494125103564658336368877609065883769674182919192031194564697809424983860904160\n  3309637645292794234193002301740054343225854625094743545517096835436975603565019923851473718492670597\n  2332775797911738152474353163342411729845894129107504555042885877762737340663304160391808268741726065\n  9615989336077863307019922231846664888930452715240551174612022301603661921939366157937867369615816259\n  7300582128112825576467959494028146674576045577470673902200197698318259700293819541492759081133733236\n  0588587778716100672583596232604960016058991488934220473616132710075452300484394310989991637221886232\n  6257224723071197918230494443514033574476639708361069860714457006927639663973492029218346297644381860\n  1893766880534512777038481569085406140328036150280386094903353489323035792511739353041584113326547129\n  0567398884435930822283033032221165929854191965597971848854238871580891403693016171725700155706148369\n  0681274229550279346352264500686934307748207466636874761476200227501815517969782667374145950438705887\n  2387338963291213957303994663054340289132774681687546695021614124655037009126591798302903887348417613\n  9723433945569356600838016094355613785537468920714544233776467196313846465263157010171323583974874665\n  4423630277928541904501566645788185997947897125148114050237769026172897930130806565716312121207914290\n  7054215088898379545365916435512334174598794809276941751149031174605522455785458135586702153090077031\n  9556558995997468057416133383616416911400992334155643868362258664428079403362670105226669361924674723\n  7136409054289852051883510036926818799746564705254506826839362640699442231179129973336410667817359159\n  7162898327417728872302052609804248757771006988196240372912716284558358478403404924364878183372432037\n  1618788149318366321324242424201471879866012908295449020987399595428721390667769827563089167942174016\n  8823587653975042030244898641889636909631627012055768196992915499277514254378812946766508325035126716\n  8466448444547240410124528064217832732227760436916102880783588718437100518084017958014108352816351636\n  0380534630763891947615018698673670605014755654519125563485474406162027393835035627856152958894681701\n  6999401433231109528721244827047206054602585006670407579111413682790697868658711779204356114892996871\n  9888032590349546258685078645156073721715399533910705457420844700489981128289942160212220926244947274\n  5405610358209264251267803981905452659443737519428132171370336125910575516989928472946953424298072325\n  6290258883626842678447029836313294966054416253861474882834798167322881097848769413234367188334829751\n  3277555209811183566129984856870217344971594558142051676013631681044749870916364943156667001634124731\n  5263146646944702228602807118139928158887516372142668321214150923172057318911173288259805252015609004\n  1554777595240408913500940365197084870074967833274323358869463126879009850231317206614113210860760486\n  1957063566245230487204929701679457814582009036192806782139458937433777693126987686811712481640849105\n  2538842393336908946354092358023108172557634997996943645975444894856647732804498867623578917302150269\n  8796454984277123360252396013678890263912763167334869009946588810286310223749553599501716187794059542\n  7203256807509917230406040592447593475587819231150708603864364001669769358844410773687028457703794092\n  8349414028221295864075270639353993044472385084396885275777983552083175810709482686545514923467711645\n  1188567223807600629987818448782700527203129388479982097194320227571363520398880075609793549685072221\n  7381909642757568466440784384976235954164378986071667348604995364292157690926961517095282542108602668\n  8812876213228288701239411121356084998485602261674350348830521151995222130947223118824547392608085441\n  2153442104345431104283533610723224461095047549030823849762337877239798576467071485072701155033507917\n  6889428553256555785689141110539376812300764172733233555555695819795161678765161127158802381737058125\n  8433764454963932090336308884238313464741325415758340853287016214784675273660353298142198999001039965\n  1663985781627083589624813758112852050274683143462186542100287357984530641972173311190325200734619298\n  1287229517898245111770328323475986403956270619085455073580791658971007776402290351977055165146315695\n  4288414243755797570968942232887312501544659132356822348563230881862148691752544420425031155171125209\n  3266720935244538532857593078572051963112677159656335359564606638121569917613427105035796893469256097\n  7592291135575500449546809395941988076919375288865024897112468591619511911805736623365074921836732839\n  5749066939668994863881254658855888383033086427922354597161408639132801696867060967477934970251369670\n  9492118518268068371039329768182793490904880992685297949785573337154568122911908288999964961736727582\n  9677225427182642232866400132724327309242950923056622134697756027497131137749640216045186933589599433\n  4517013147431671669925355352625191822960685511025521066176939130589930470440130555394785866316843769\n  1828647234353248593887797337000237434440522305783385042336974867005016002866371635480721425727423634\n  7165982592000599527350286342941390667926697237987304373539379577587467043870950735671245544966030978\n  9611819455417024559219300964059380552294276921735098819503385424390196223556566509598118950849558347\n  5832679441371943347770644174306876072873238603190937646745291892183927340565244912505869565176115620\n  6981250039315388458184406490819305513822068081023933630856535953832850815185286024907380888193971974\n  1926645634161448426511541316956283525195911244283826288101030847554548973690254035882364831424405950\n  6043336372172311369797376625377898329148146768547541189710236465877932945245536608462987170976671452\n  1539359362956508416867938874745177684647019705601206291119659392716942878200104738422691208420374736\n  3388386274792663438170746008618165177012473800268910283248614546728946437703394342046484241967025618\n  7916489725183867462223041651600018564312996541175982085005633239524163204667553500133537296849174676\n  4631941349922374424722463302202185954740646378821188234593940899689958667766370114295285312707935566\n  3237832561966782136657092206028310256539135401190662142923938164112080696172160438099387993003279135\n  1939616054590672596572424438866730988394948040500199586995408776106691389068427993564695024599087865\n  6104815262619488029162203772854404310761915233096761345657898664927602310346708078390992627547645000\n  2311159881515250166756373957401905770341261342041635904480839076537485827775259666285431629883314207\n  4778261209504077604333883663580243089244840348835410287061473396328346465783579669745925874011346345\n  7623216081042397622251689597347681742851273772134888431264298689167069631623873420014694898521423020\n  8355107107105025571884627785644037605341548737134057035304716047710677529320079908300857963350589136\n  4869774715093761225628448351427933875263674570722200256769127483422379436606131986267609440621051523\n  7198485974737929740617724333077735380254302218943957667695095667279812485008486264258848457967719356\n  1466464626014964951463471490061886726013021674810746605411192668918406378835311056304417080835780199\n  9223295643474303295979135889437938009727044258215069279799888314467253297689672092433109678778704372\n  5470404969378268535332779967817629151867127754136572668369349108729256606562281591526335044669497567\n  9229497645839604031247826096808076324572917963135706380553018179506155893461920055250204212768920472\n  6523519590844163705976227580527335399057273772924589843113466208946935684628077087959342361434261835\n  7397284121665260195438481774502442968737870447818458084566985918167574593630071250992994559021579797\n  1267979286814183617945293811474383459113049494906254577757396574482504189366105015672239114063379044\n  2693276717835728234784024292290403767470039713468343855464064270710261175300913084761273575638893444\n  9578014367197801389826534243776067204873056592069332816973770772050673214000573675534498089554053868\n  8878671591124076024028764936109146485632435139228289616920538474220896046608059038230996591893342589\n  0790062237040800669979202979819440927717350270127336846820867383102707947935530220822775215446092735\n  6207151719553874896681908468028606626805266261730739559289324327665608205589264922811457207893258778\n  2368082793050500307417743535142587643209181854326694069067600791908213420396368953094525633402213073\n  0209864586297689655472486526242846110473665750904177173205232374140756584899323927086821679426432687\n  5694735191217476911115775407999719992668288850793903934061031042132964682504077064770521769095572432\n  6859664717698638291411537797697600025819272394469201049660042850854700148091808108172665045679671866\n  8806462058478809300711671419078497133939149939952552454520949465078434971981036142877818403322057069\n  4639515476946972767747706424864607939235195654366350830702520798246537427425699694577564626119873862\n  9434532805415082762099066227743584448627037670924884313967312656356805978534285819844609008250228150\n  5106367269141887603978831977318626572931421807329055093538562444488808705158512055619441373703285405\n  4757221463407137369326552108693222709423907542994089944254445906867574114322524261672343521912782585\n  4388455951679782993283236427374574525445460529398968062635137335872148508088202055186599580340814883\n  2970125378123505679305081881856850573123325755554241960542735831944797643249922882266043555852334960\n  6680905502905216337784746351934749713022329493965510415987839740167516618593605179338950392466205245\n  5112688373111207852572442457996232944501683417135951402520951792646811568298203136188273964266233216\n  7644152469548755816408435821258504424767069969380375857300390579011051541477955717916931272909599822\n  1364115981595201458613678920666663532183944579112942949372746424648239215477975615733670895761840575\n  3220985047485835708917663527278094953542744825251137393829123783351841471827848818093776259467255433\n  4206902383755976584674449885729710015336570259383860983788837055966165661226188124546387807403643775\n  5829259340136451738584462455407649029616220229244791778901424327249245624610572832994427679678314481\n  9346705517570835029425673263352649065141412102378610932967188631037171704617628931161672590290677122\n  3985883659641492455308120728570841006607616854351666353034138280113381967791228997412665524495134833\n  8934636181282256499053411503179141167093830767768774232569803429140799802919107611396530776180407622\n  1944515194026040634703567993538832743785881520110804064908851752700820562380205128642184248230026324\n  3205599799834692623266564470195635730067953905724415039816423908213623513271771458619121032811235726\n  9933087662553440894151205179902731473868182626644475280406727464085723801550389418912595893739926501\n  6877527437697415337481724220377071286644907711626031544171194141083486068995295074447722033627442668\n  1847119656361571377242461545607047965087831290013343491113629297558360906017594945379686150681790850\n  7607566212738100117918293076118629911635574502602021275654360951138569094815424476722607340061037334\n  2612736080448553121475788902375590577113174550094118597486529627058856391738971595159889870141758696\n  4865418532486377943378050698934555388050523312494984188757304644473314445985055247398653997073462338\n  1939800857730435695476169828265893810030602411218665685980207253371656135335099218859560107881521955\n  9929848307371141617648399503300378988247903454105325020549556935880161545989189368865721247489636136\n  7186281885464478617924358171011255185131787177450430735364502976150729230110833080255153495186929484\n  9716900991730394769733378956502295614877878048366582834827540230192303690385819788534303828558273006\n  7215613042476796509973673898639630845953309944673660052789535100775106235405180950620729591214778792\n  6626338542879258977595863058064650448452623913353834262705043086700946703622040633976725299136518784\n  2306583966702262580562122210733541161850293635641616655779237766395860494693244550805903617986442755\n  7412949830210469698616449313701037027750848601539616658645128535453048155982963829859815455625924865\n  9186328817630110149973720692015386987741862165578208788502897085678297019269582769523940825795893466\n  6666883918358815549069436830703532763207934945109365399450972042836730670351441963155288753214822189\n  3259671737078127140513347473860809636945635120190184391605573384080516638291488624793513794037131979\n  6687585625948294207463241614819626828884980096887564131779026576910555080254322803125858998458287208\n  3257358894763134926062496271832200731813542439536437705648192953995700144554383910878449144193680471\n  0651634740311703744824585051857881806866288441707935660426980031632363491203029197537009960106661938\n  9621731876226707182631485228441727943340681810310183841753499734969790135260460838986493841708529346\n  9279158345594247787414758186260672246624811772249856862298974404384392184024560360919123698959782488\n  0644631955555593083281673460231204066700724877475998063268452732025570156216876628405832688949305051\n  9390050495049587015400348542776024624858846666734238597445456716114198430383570639742666670385556096\n  4523903570201073652328352769206772213666358574608076159948257589026155644286649673725692080468511746\n  2670246787668603228796511978576164426500255366220799720399986561469155119965918926099875691957219827\n  5509506475978615626474235578645011389704199350997640667655712085029584211559149472907523553499274100\n  8512949193855962594032638202524988224921444475588270029003679518705235762764423558418333071204601246\n  2993991548419581355125514677093447144330924763732150118612798381856025571631417442644210392318412486\n  1561304709814802473388125696051967726943832149010465240998150118339414506008422291319416099500996449\n  6196330766171680279966145964908485717408237805713129439661036877272697904349031896749323216657233190\n  3721541461036471884246356801971257097712420455992771894016308075557915318038863852263293491228689445\n  8712440718739851310980729960000540296913908632667141792364975629719250212883990970848468043907176319\n  8298386258976031273818102754934261012824458351039724617260027124726441028393060367775439840384623746\n  5571177660427479404471102532275260708819152596238810359449121002592156755099903598490287366394653336\n  2227856019878524480781200009226725563043118702187832547386880440918833104825515033950623703534591157\n  5694871584408122253546614612133683291417713871207911325632996961058630638814550382930706507642500409\n  5978377200913542843287311066940704199932530568316953318544062180960834613197799338171659170654879552\n  1144399346369103913258534977738053801424940934503627616581368950030951261057084123445629601328070394\n  8714675890101664115170393932146989030266726605846735059647527480561780786795393551032684912986766565\n  4263127329885291927008247087740022137431156586969076065899085477980877564865594130890270456897729741\n  9559655010922193569323849781622587517646552420925574092571769546886051901000316080128972898705286108\n  5422973909396815077500965971737146008611522092622608527082988364373624387798127745117082236808061077\n  0774136633479557435335472506634409792898991840821815020062629005813678154528485775952733595359748408\n  7245005388274103999870195212623316986282803438849726914169586295036202722974886898490039741471616745\n  7511413346027344974235505878072186655258735064125308324573880356085157662659100847907204770453688975\n  0719974356650630663167587611347516441890509949530441171998514991673976622942694451662140808774913553\n  6734530651829997758201465753081579408167503572563130826897527686949131751660314196274122716209578299\n  7451259507368949976478651309830445539167618793163664040969778731171580041226555288637091406258178846\n  9239036439876794389944195963322773315106241711111175895820421382268247158558623159366153128943219165\n  4892821195976227665814359674319046931897070954625498480234955018692311293664029290996670086387840042\n  8904420862483661779064302063305933920322434365160794325702465868466897715343280772170987980118148551\n  5792816444921354300152529961377236010772921085951314599524616594227164157476323657025718806117063487\n  6292627323600831252569965434321893745077967445291542789471272289470446481314744124221166590081005721\n  7233044387008737360533164683029287005557200190699431998706454465506242821727117124592068124294810550\n  5040470592410528835740065648454724560748756247634725962019554163080869913086567869678755397008127911\n  7686691949683813515098808520958276792948785481815843390389576480289850925724608625300614888628650306\n  5719865793656157955982572991894328947716189620569354672805441856350184626344267485715560888443376776\n  7751811195879631684185363912337497661237712587055753677142553545280102361912882466084685673608493413\n  3311957993354042333577358896378053183909344428049227035216223087149443606730042311797968286390517195\n  1575052097655902730996709989020051300226332647381845202399769112952460615572933669965418267875614644\n  7436938872908878942599227147563262066667329080946986292953431110762432816432736086308641338648646683\n  6833403411741724336137908604788056800459754328933272140608034447503284344114611719096701762539842822\n  6686468388170610025364990074317384700086148176164319642146091993738188776548270699793984153938974909\n  4610308060895210562372337339552990648545654777111323511505835187239748697076352293343549725610030112\n  1589126783284926464529265711611514653003449614413040707869371417923311666247696408763548739901747753\n  7102018211428142144824621320489013665523144244134042877529811835667348556593691796255853153675107980\n  6714527966374589942103118815474548075246518531702182499670582009281703471433056490611030296600778862\n  1864395862030912621953745931915501116913315595473394117208613535884052045859273604632198270224071542\n  0614033109614862990759081033133065914757495394365387018430653038342790401430598298810968662879396068\n  4213401058668136877008625504106696553622430760974869206667440684275559470825940375954543932812646151\n  9786010940922100394662393810002488578082153053964123626303568044502330247943343213441880843146928161\n  8392368201869189398393330782579391518765988615852658830313054820647419923861166216919045975656253336\n  3184467689507529925867773089781132205545268932341196377415807042979172961849337651669375621514648813\n  8417266217153236227108027841813774596097865572452165349267876088009188070751445179559189320746484076\n  1990517355858488913303280635078797052313167676931577373187959490721237263799259715349422416504918609\n  5916392980515375415305601083541412442663508841170889542644097702742282321287378185848137739355097493\n  3555114062446643689420453552379302295569902568889247247648285698792777177043958436924724006222094132\n  5554943292326806265100656067112487799788039988221458634529591716662481653228741155327526411248966562\n  3653627179051708201531002673539588247022352816399724015346412203202579778082731355120501936842815520\n  8185549975149151101699141271160844540090762083005141646188255296346203608737167901905825189468389540\n  4682662971748668008393029512607766929924069435225777438631812759679506943700156062505627855914341512\n  4133940303277129532531071186174802577223494892925219809743089521223146195766620759235563597266907679\n  8666123329105952796101834310690770203222871625208361195649481175299713274973059783552852128578547844\n  2861816852571073997916448507379463019479486010937938364054003035089249948913801089313227030643660409\n  2136152251750336475912552993362345087462062522116152134533464059073152732407955939560032748790973869\n  4260663614314509347957936425282076057673668224556127797885798509050746557599952332576801978516473222\n  3573444661249477999064293351032029241706181476957105077280191727166542272028024548065568292656244457\n  1074844343809247355832405957279281370093179495842802006781667030234830107405474219268605401978802767\n  0617733116985490100532526580700391933221832551762219500495602329543188072487098922493307375904553488\n  7851895773428251250967651971856799652910171995101746478143027813335716956422319340757137678346086967\n  1224381217307989693831217042049112414515862212057381989260281325336165063327096126811273544576450343\n  8627183739199389437969585611671266838339375985582646154279781331791205782912378998922762772561595125\n  8427540001446320445791065468667324140533658619184280422625821688273710321538212290016053895557458048\n  1497079514288287427566570758148260548242022106120376883410734370446169531356584731584649952332889740\n  8613892603743654557103135730978703051579767418648833308333468306177619964953332343405916867838864524\n  7041275531439579402788421613759684918282328600669289116050761181598098057229676116423560905478275530\n  9990228360118255687572387881258582934211212064353513623423335454800037637353922844133746644754648997\n  2715324870623432473939494074367849041727254265742675895182796020334362260618434065482929109694732775\n  8106315005802505689492133983705710619553810369925100616045006231958956852776338414533870921568787580\n  3212746031128492488714697592389661216541007845166518759992660729902045834562796342043971565244565003\n  9332697584161527418689052810339622772868014570270031896278770775137289513749285389160134511814790912\n  1245542835114507476620614502078740552719831064913195084319393794051393560862448712063282330972563106\n  5680671593587120399214096663322511910445083216535436219937775858432812272309717649727002825335202360\n  3346945160822872847275228184687773750722988339131876836902638244934888564346061470214101593355370833\n  7592611935438143753258368050686926516021319638590042494502607779328982929749310257474851915475821236\n  8427556373977810151502777188467396734397418256427158653009213673388007912311266160418917228468906382\n  6787172246977341470030337709486294246783622917217912573978588957230493800358591236399689631216138583\n  1046483707963766267992976156682119846593415593391674446886200355689651840618965020995787949475034213\n  4510646829418913576240994955771883376474844936148903373387364084487665128579906005691803558021757432\n  8223720982964054139849176861425411357801923284322356622012533756997103821037145053611352158087544325\n  8875177314981234159790077484154852468747186982843716427756796612188225898363586461233727087316163958\n  7829938155273415802880622289603227447919731513419589488384195292905675291358284702889972904682421781\n  1588125445002757734897566106936993830600284424883040855689756491161569382878286204590171592066183555\n  9705573502183092691196050687113637921989163882647003032398559982585297372067596850212232594796092137\n  0133154369004734758005266973163662808767546868431544120054451810963963317799632707332700784242615943\n  2871983671001853052211000499358589809347272782613245222554744663365234690260799520188298486579293564\n  3341058619206357658021349497123815423332633081824963302038636180607430078936284804945727476555968976\n  9047963077258435896097235562688527717695095754854674156318936544434526825222687331658583367174104535\n  1860168973900370511403872160749256572866941446343428193422010787994447931528908070441678372085914038\n  0787192020468714895404296577827423277263006754826839257204742895691916760052052321538211408873240679\n  7255883699722977039781747786554451339369528046730979198754644054050153559842149017649397089933682368\n  1797861826371377477618992421396475468152180235657008465062462125800933823937589398535255324737030726\n  8761318693261257733337290274919695015084048179987728373665255064027193614777325988089081494639422730\n  7546211379742525447857306562061623275845663368716041054565558219632284442580016130922925611695217058\n  5617429297116993729879855268657367981622307685949173321863761507735171533780533639947253173790467038\n  5755272237382781358856453237660838981202294975179584990141689663452187860835838411893138472832576864\n  8734746219535389978008754241505867497801560159311365405520709508035255004812123123771815210729800323\n  1017591837862540565962539948544710762023852340834150142189018389630276690864606288997315830500060541\n  6610521126183324563088749423761321117383235991026715443333980903010767519215606860915099297579489847\n  0913404847760372533164866332739977457417078705885849890364782505006075652766776667301814279834629978\n  6311547247190463813082702695027155243458377713288884011332285612327642475805491414533400430735136820\n  0167103048967407913220417329365588638081990240250424758979906199739449424061393859002043745081712616\n  0362783912411472682090856905268374225068910991937677220777687371267701529071296822615843757149665346\n  2961540352898069849819902381588132490072828420316645458645186778718177177277928321252696832297664124\n  5496739715278796804347658957612653385245739151343813784500518738591532963414053689484439722550801196\n  0792690281162293670434371158371953865778600341946713096653442535523561350392637433355902487780093167\n  5855665020261424517552023105180379792416018681653272134907447418792630463793570195725465687076964902\n  5628311394908306598139258771657534329051829883074422093153945626718913650932778527585614188691505843\n  1128180621164533834614564998610279908878315999233208349703499009644828973619972608413030501613834375\n  7350335026967919910039457648503139889980405347620797995103556280094271198077141386253746894200671129\n  2903794021105099312881767863557121288220584525902329882784488972855767643376551320983720845365197273\n  5662945407520786837748259937695085474585377854401518668703212703251083788575535253274224674561655301\n  7529469704928603493523766319377581531269112157125054564936628404613157549323436161143868941551917955\n  2116040327941387040597365968287723555493695367249260335274498928882204488684436527515895468955885890\n  7183172928912923457744284419272505276847550387027063282979975853882599387906789963676634726367997091\n  1370005004519151507050208574470532031134283753039645068373494746515254316164069588396569604776248100\n  7698125762324027656324714558678116653563357384133203756328577111457947736117758910978449597487134549\n  9454050089749431237026691600227796215160164431446321556746579869691343020917375379329537363102934825\n  9418485153134577006494373909764208589573177423145767288296790675029922315257328698330263412335263163\n  4902064904297082100632648815676763242544468703921333767894896001251362652354725651702225595569986284\n  2510886689684710787260016733242215625124292721308055932622130721409368643549968987874303526768849221\n  2318344924190763747157474462521597457646635724275279522289150406427767865661151919331918178305671646\n  5304813810106667342459156864174457688390624192018654102252669706153890999072549984285484195668192454\n  5197470930614227531512984453091827577151361181673035809321460322584723528118255047060621542622432455\n  1446896457269382316655525095989504109342537430859997971370042588583403044972671096299697632336077767\n  4373479878835673010286471384545928791637490145406647519394899352212362474366131747830486884631516036\n  5922435767627623446665395897964687905529239027020107572189191382148316268524904958486754329312418264\n  1346627228209365327728397667557267289731938129341943057239620723292007186386746670306364601331111164\n  2546802512289430533112509853860120123607044969978521095859875329303277162267982305510767692680002207\n  4188490301650050385344759710183016737826819436124165696392522947410357431851765836560341232764339009\n  5651186326079173389912627720721351617522225524182961243396282518232869686254441186238123306403453315\n  5601640695747232038365145663557498734411685994161655182496042597983926781613148318090253450716466644\n  2670262761185976491324768295272780570322383435150636721770663763740249030465909628596027197972553780\n  0141820199810181398125950423486624834404392113648723666292020639396288453144837489010260840361484073\n  1200674156229159669636694083603264334149637120985454752501773669601971461784645155559941672637397085\n  8649598779532421583282184109391640528356790706864210780346607571979891481554005420051073009627962347\n  2724997011221778165679844919433222633415033856753082446773410455032742856115745538742140007192843017\n  7447314230098365760751551277796281014722053066817420350596794105098046656313637782517247091409925552\n  4710368126705138246752117200528494295219748862848985277878356210600487812711440634990881645924451898\n  0104429357083290472201607269660461984260772247831071714390934928973795075056471053802916187491886994\n  6353013572935018732066873115017315310912967948625497958151216822075712318919091383383534471023659794\n  4808047123388274440350534679995291335460941392728446513911908360762265798398156424638291599904416284\n  5276818935327913567474032273515068909877547218155749984883466946222711943435139572756093318776721574\n  2857830330183042225170496329716122968367527489832947231506974978874140021926700672065677292131084935\n  7294076359289561828129001109784724328303846519743758573685912309817836030314052823008130266313304139\n  9253399217941576479853470817863611377200140857083863943770352918349740374183511622370040173188269393\n  2630875054875664529093265665030243944536227279170800381578513252902365105680962589179424001638714961\n  2121694699254423986747262060057131153878388338830780165378838775211593119449359569491793940578848860\n  6239594441849728928723084955792607211329771213723886969863602368291622254647108806210944791323990154\n  0667816028934694282155062721260541798291781738248919973382953016826679061778013533650471886339784273\n  5335856232791853579779226627038024456968296862549118748685305497857965989184862186237485563935321563\n  0489928348655615415406495122104661037654818060250676549134033273862941691177626381383478511836410569\n  9966094920204489502629446168466855106066242088314537401268779478139859577769903987707399417032565319\n  3556130005281435994560612616083223589903248956595675275769853245744035607612886079681857619771788765\n  5619852375274472235992720206023891671879081470886706830279398976837802333757968374847167920420561188\n  4614435084238369737859482588497825952141431676898495921319389412875069596149193271147035874533660814\n  9437546971429195290310193894356371835937491483074230449340295962811166523899581106000938622216226552\n  5297661065074527135894973344740728167392634862226297134715553293624445799465082319790876907445852537\n  0345709007744081534167863870148099674124003837808523427397788174691080535330509119443313873040838043\n  0675060306862695321245229016675038563185858593174377694941574108105727494443840013991522952924016806\n  6745842469660556910769759698731095078451825185768980009394286371219101669807885171057114466950703127\n  3706962004730035675368235205815249186823908397408809264852704581680063915340134937352547150923527044\n  1619265721100423458480853223980930819701215864173291305325898717158855168420606503405569968593715915\n  6219395459555855700934771168117983599584279819556435636530938905094196464188924341766121771175457371\n  4429402729377177659183107443058151531596094826350633655723861413920813075414610740512741348138890687\n  5208965175472864434890201501872018366138417280798827295820189774861263383603711094140868044146381899\n  7551441905115201402418762897868823386652887495647401107245990553799217515564781980918495587675277828\n  0803822629818043941563979561725694090929518577447883651594478720682678596369454763706238206696202396\n  6206659210812781832191274680814530314217798673533684893808266818969129998351994223212726387715975764\n  2852132151588371714648542881242312246840283905615779681998978556251027107062837939943190735797975362\n  2873719947845210383168668521420822019266723155810117372442375609151489386343666526579426037168289281\n  5806931590571523794802566191268708876475069508501113702578802333818019030210029759755926818216359535\n  0706418857190059497444679741742025213094724619195027721323724702570296163168146476218464364465179953\n  5877759048091724695567396794553734971032219369455962778937791938340697253788415502062958387483096195\n  4204615469902226843474617677113197374866000879354436073024336632808653684733506687074089001847030676\n  9821475313373154286221515513181409541497972467067634369769645830928679521201994140665404326668344081\n  9686918622917654410364920807857292423388755061809836591222653797288411120130691018576030498329532694\n  2141884259428662146952768806320825719648671342246985264194190222362411863391302841718447248227557233\n  7996970748200243758037179218073420208053693574061876566416960773912090981349470212072519721369964234\n  4209305478465069237446490420888732630226156357919606309236991602782364930003449747123779455951240858\n  2397099465702753667598133047775050505366345747155165583727731007857817871530316132768489253576078462\n  1147886035180402976569605848671756763665930874801609992795078717891310420384947894328608479705150428\n  3326524571886423198399932856342268607883443745309272893146092544299060787111736766959849633062177514\n  8848993377878678597852652805705486612173792135521247023953256081906788528038324229680755447174377489\n  5014302315014696122549489533836275694486930467419802292255506508742977275807609510687982710919383714\n  2290968268728596321942836727242477443909060036804852784543854819955828743344189095523099265929588482\n  8977719675054392057716689385523977360925820906934305789867423572953120514850903846524931400689961737\n  3173581622229445541614935787147750627037619249803638440016091361171372955766180892638646794027936567\n  0385305779912988573944783757639092679443336505496770742285963808721870399582714758000440222404214003\n  3035903609605480047188473046782868077409898322252624531680320340844351093743194993802990812417921108\n  9542392709654258219584858667992411578844781521955749832225833567422679896009803200935486510854946767\n  6713405310343499864349758000215286835835721365978208435732604661260570464409200520643748808684041999\n  5854086974773160175053902530649036204494584764408820400538605715251822177935180194147116600865329482\n  8106002191594469278346037982926881867778488378271314816066812848087479043023420037713089646478178559\n  9461837510620688441358628450630346441913942893762354742777586769014678228907006092683252250324639953\n  3375667289976602542465979519632609027426151574818652781929779836811013313396516257933184194070269649\n  8895138692396126127536959206022969008742083472084083318841582683801938335897322433513641224432117497\n  9404766824167809635203566415433254150964501977910541460943749815990445792838028880133562481814072611\n  4232759728948241418870259574549342547227469899768771623160993228850420280708381008140918873526333183\n  5842074074844657339783842980534710600237421998721176268333490920907386533795907492808928303010720755\n  0472450851183334676304759820661789998004462744803370196555021320441396423674506953708781697379969379\n  0616378482011697962707212703584804794885806583089632312886734029638482411287659521853624112569697491\n  9905747828032629986123172479305032363770584569878577453161038667067555844068240891051181842902580329\n  8514096157331538756311438547792152983663838215871358824082012778384097362326475844352630281664756079\n  9932214839271563212499908370989309463295598599287284335212524274334943790238249494457851649361270326\n  4233909454480862002835352626175298183552529788046502813539911284716128115341446038970316546773952587\n  6538384445746110351561641809273346254142217903310714720310599294953895958436885773489495225982103831\n  5964206232730714837166917989674445418418903725112728353005929827393747375710992776523563703606473487\n  2478483968420374230975899887438787654284159356597358834506093612992449258746769154280459813281582587\n  2999110300780631592481722052213206010771492336601003182710066727266488949550942336897935481055796423\n  7715449541371774079951775014666954655741008015579341795983013187154617138382203332872631369978080937\n  5628169857535292539023656811435865539828428324170005164199005176438351200575693343042180293152368541\n  1424059868057389737717209032816486238395498050084360235358582554618855942442612928921434147898267094\n  1767604522251349298729974353338206276224063310048837745273811887225818199822194282936766660000403799\n  1487001856867455441231957351871237930599514821595486770105404782025853908333564061826222520802864866\n  6809763156107137641890902360603954124553570380667535676524726680367517673845564696693596022634258001\n  5557208962384036477132142966921934724207987296298616757967460829597127485706790346703915786585811127\n  3825743251903978299544576743057529928302863418624254502249624197916398273490435941139589840434895757\n  8332464822165249725331811930555856140503105076548589915525542652886287528895545773678742029770378468\n  4756366424947670848543073541328403616349134710744683298589809511102012425448846430712271748865869643\n  6722375125740766380757796859385182321580379013885132456704225278538766101351956828652339460402003567\n  3386025205513475307900746894526143616381246602094339688182998572534654355285404636104131214993769216\n  3026148315182346942096279115494171946607206655284400443565753266414389342772209055751842369120803473\n  7988670796922839869375088816146073838246420008153936740018862573073695349973083672528101494304364563\n  4975213545319519500350764823703618453849756361633974429430988638719898808188086747495831760222984672\n  5019591837178700154647194377440245879644193433052737786174502452497071499070005187269292834587178630\n  9174843878550639754778139797614710297480525893069221666222523537344901135398626602814192647629370976\n  8013187204140666876255459542229249384946271177550175862021378876760029805157411237809551927818159082\n  0663636540356868332445566200951604633752256882558545829200193063815338736565179457437025887562647321\n  0773227646623152269937958253816250741193599257543470320751896392792921623091299025904455121720931896\n  6179934694954150218683377015220759113008886890238579915282639867824654608874627852622681424733188588\n  5724166512619590003292244047284089619602649237730727930328698350719950917336222069042662113793573787\n  8963398219271111792437518683817576213472922730484110905289312739756654644015991089205635953955062268\n  4903481778340163888074775859106047358664560729940094200063120435623081164981455149655513005854611735\n  5240521671556660413334758759879204455921756775632837672276901154164921122464223603954033684550113426\n  5424744898954599679203644242966524827350687996495015740462148251111674016381288237054926766797280057\n  4632906194561799730944487237467063062834619376926372843710250629430239838747180411277944515182108640\n  0015584757912846401287399509776297708262263458825052078183457605053081571276816461601267456151310391\n  0717697384557873224133003000553471951166901258113520801563037304690809309792735365856491357471135090\n  4412759076490299193882008262173939592861233365729706646410270587838551318934657962685933047956026011\n  5450359677101400579933368890040220753848251399308637163433660079237124064576176500364106122054356886\n  8817740625305700602301898291109153407117751712442370364363715890220116231710263565013024399121540427\n  0127303916604348528921717678005443537960268144769874794055715993778356399662100669274192714681089620\n  4073611163472025898624647440819612040336875208970108806335428443692521801742512119678569911058334944\n  9991683094494698470780636754666776782538372304052848929117305480298931061328228524301397442127840108\n  2297992256374991861619095395092292352403872656334962447446903480575135659465046250309625011185996363\n  0240365418782445707402458948806050741683907150580324241837558626796044894031184207156184266389930059\n  6835196088099155005408191160942615617799649455573893623350956021693845302940741535422017008850593410\n  8021537744168969765523900070011310946928000344435606360766131030272873892742266524989909815901237651\n  5704327731921850284488111933201103571057194443871218352322554867726440866734045441353674039901046417\n  9288114132773295705233233998780091602670028929046700345506321135518225964545636558027046215314706032\n  1476780387345442039887757315364197294374658678276336231119864674608317162495938051631791016021743160\n  0363721351355065556811627671648322879623900371433163480958689243847116904830789651005911049650159928\n  3143831201893252516676895589731051802070915612821279478576823150309965487013780142034235086218894451\n  1309174155201212503779765726305117588445579181661243191479349987937188974667677782724332922702482645\n  4802849998567554945269468703275037839400366514426856820813090209490578996221008140773669655662797895\n  8759938160373929408189832602311979060514597803844941218550734723444046413633317148297819766986696551\n  4005181845419763310556350448849713422360339130058979717346782373472329230517388505004636025681998062\n  7282581124555915860150184390904098641809717100754618847739349112735711271075330950790361979461708733\n  4466480524178880606773110645588414287431205536864507541312378920501641824559852917028552982349175681\n  5198174953565040453735880040973693100210161974099408857233681398906852305802152257830798584444988490\n  0267221549288886129250288528135271737803182076280866581987021339186121133602461873626491285983857042\n  4605478859944208240180919736271175154047465634118048628864398751105260186007632086640320800588098124\n  6682872769158288851453555992972145134318817716645564502666336275157142261212702829023587031467862427\n  3023359989513383310690803679122897592232090053533983610528084879743470505105124297994696958773290081\n  2070797287965358392324265767339214438047036170652959567299323441686930920186625715820350459222746011\n  3349178476867831063630236724355370932562694982307261863131091050164320612674246086791670377930940669\n  6071354477720412401713871525414787133745660229142745368281009292055889007950848372326787186595562128\n  3765493043122746445977381115639667409274991990309678315704437927396416667510978926409311746824187884\n  6539287943914280719137228194506211199604942014167567514155226569328596939900541011164776752925649440\n  4287958357100368450907034580190874999930927342332379066474107462898117101040277883382145098316061371\n  8505842790389539496134598694553433217338838044229221868482471011714851583471060997578697619681601243\n  7330230684469271055789326166001295993498597491718450334461056240840010952490311291513102073536606699\n  1425097441671089180442792638502557662206256643470568888120913431296547816198453967515482108102441606\n  2444931858735121428601085815587151941939765526106247809254081424759646627019194378550718698349687692\n  6575171350176402003599383530178302781767102202449288655654620105595674157711590472858301654225614200\n  5482685137191627689825272660007703368359267689271174661458864432562954417051216860837357165976102782\n  3884860670144632963682136373033174648717632014278800674249348568445726886782552555092500615469758288\n  5492108122224766822902775116822369502543987324561861209996738050145752145346770108025915298160421223\n  1163287602645784892088144425417823517877294636849168637871033559880293528797513166009650345021350087\n  8614816527569342549157582544785878977900421015928011354809715815493253864902115138985775663927058200\n  4783308103193586172095928503098371977956384664987334554901336566062958993312667035425517958589534255\n  6852221670572063731668209322415546565287062082026853326008665800583966090695049703022545349369418434\n  7991814854031752161531889360169898297123827273296188151354041870492734852626566640813648637887168029\n  9743419921840452670036155802038750040963721886553766105646252585967623112091455580614923744622486559\n  0525941467834123013364881208645131781450546417941645672385775090452177054997583323609161824686637311\n  9959742563739243193683606633468788836648939977087099239751769429327043157163405058351989947721259861\n  2465956758031364020077933287978651130119476790122849334559372745446777306994245626020238875493090223\n  3573983039664285659923462394343075435576614858518612844661731439799759776844709297927738276470935627\n  9494509375749758094022971955437014385922121605808100423974385330454346711914387122662709140126153844\n  6277366108865182715566402048997387185384279740871780398587857487216892636293407937055160183714050877\n  1496281607873833623355597883713608096663152189322875105227403710184125482971285689541641949279438506\n  3945483861715452863298700743447464614650341446025619364938925571934232096238572840936220720551764698\n  2530400643228756038069773146999660101861018409083474528089280983391290914925830365117302996765473925\n  1518450277244844953768047638864019063487296774799021248561273166399844273618623088551731823996788171\n  5818320630969964851472957372369464794425482501448372786430354266996443153981527716867984468577777317\n  6724214993063597651813595392768068710323045802519156036464184552722886148251459740929971994529105998\n  3347241041854202720851360543073574876227384079200167634661510906147191081330087692439890505428382858\n  7174596002008845764482519031375548086017940341094418988372652319407183137053799835234437595489813215\n  3424084287482442809898880471971054529233998476551717751441096350331443841574283608079013413016396157\n  9445590873662789091442759845229763054393408666782643140163757170561881345065363728887368457730018975\n  4353864153639381737629018229633304944189194065973057538512133986275646249847032791841511149121135250\n  1046851190089611707902188891880624882538422836411906558748088381207312323141344233353144433609656271\n  9210824764039272060888862628525885199283013330589057652728295714261949791649958943631773247495809598\n  4149163996087240559405897409518518453701084239110782354479538977220797522617599737993180176602584167\n  8345852154531357858420969913069952099187860988612444010607411986374471530993510334286163756809485035\n  9275704744265896795661933828768847466738762703577987555965494014662899892099869716485407230339888393\n  6761101330378404511307837997043311605332621995442577030710396843975279691973081280251126223600777540\n  0051308597498304645404951309704803426138354091344540564134101462193716056552804448400880453039649492\n  9738268650227452822994845774673433786755028009975605100915288666465879026257768957124187931583948729\n  7388771483538424812931191683160601354302997848368635277312029030297107783027747389581346519427561606\n  6742843607020400238768610459207769656762678781970656061203397304722965481373446191321988589232186743\n  9123224152577419290782257091414018156957284573833622918850794868329493305335931935720916763645955813\n  6799238696355674929865113248271394607316285501241323117372648773982965149234267413224728863284602104\n  1366966644267728104149594302767238763428606644807904842677191598564512608618704025727442774514307901\n  7361515617731515750059883996401418804973069975506691012924075303749581557846276831148373516100826421\n  0568687863568408589201192682524370390352517666900923840826467526170926026971040704714815310205739799\n  7681579182981289235304146491987593615632212451682746172277968157330253255735223022968339827799416034\n  8264985693826397360590562321392948550742764853294267105896994589264214411960008453533311450406865373\n  1319571484348541504151723470687159665889346879477616050652520532551887794276200067792917428629514803\n  6393715562492149219289945067840972054346001956298474409674862465363711302087381417548333816616561518\n  5111911346847323655382485319878581818145010538694131580428941053108502625828157123111145551238854904\n  4534798670025707762174138029189276234523893914028052930968645560208707475029630568566687239774998591\n  1356208348594264702238540331396655512294052067722982107716988749068312321865667889253484373928939824\n  3039270631046016785592875306017870222133068112991425648726649716803285494390895401159821493770170327\n  6762092987636152947610229638640039099466517428605271606511721401325095927055929483973612998179810256\n  7138533177106675033131782787325121501327837748650207033135506227558130481080029460517179886418646938\n  3014272229157943503979917780164905282771302956245709102784944459005025001264756232514016120398203255\n  0275269695196707423516842119109820901473455345247385160545020344886526119484579467391032494601754606\n  5949133473564878481268188018707352591838083903679072721987136512691128737953771599527413426674052986\n  0582672777608419974697064196590299595629560556000221763788281809646584242944311604341015403241618371\n  1241183341336908604073818218678592966006015260979204302690514322256814365746965542007161049260710551\n  6213629879300555912132665254334472375154831796125640786777424307070087662202918140655021360191663843\n  8599988612327515290352987034953210752896906114040165980218828037680534871490208308719178047753136085\n  8414106596751960432401798589153532443423362991003390367726189914046681027614857872154303275752435932\n  0503117165170343024273760823271009896214950638496910029025774167136585044898207551353446944194185199\n  1214566815068435730758765412713166542356681222737222333875877673936228746034106368156518664932281342\n  3042420400173053913958045034059680448257513405554904641633578438160588686022799179151567769918483857\n  4581978981362012970538786726606889518850722007442610297073712835694266977933820878091270526740228190\n  3448878106828049595910794308881004695618358720934323233044096976123771968962982119916878709833961134\n  5262017695940034586738339782341473219138249974991406589677344743402835803153747984899676192496998518\n  2240176819305210022455108578603846905687663641289089751554366506561650619221818558606395256352043478\n  9459161679812323605749683748234389055596433504292754772607193219830825380715538852177309242994131441\n  9026355802110535798866536264151014646071198559829289549075514813694409360717649426291034038171821614\n  3960417698528173282088210369061259770468314059876589814268531700310662742574082809102331168159759586\n  5485617816146064344765193028717343009218001005873954834544037627646013824276340532946558088847737466\n  8362561690834309727006997481782424574194262607770979891422900350084332119239773590955945746815664694\n  7811010103696356946867890309337571102762086607087821065555377926088164133752939155961539106238153813\n  1481317662760323198880497921677961104910238832275063964710076965247441460982262594476729758448101388\n  0841014521593298873538518073069810094601261678689308602437849860720828026692445109815391695973601821\n  3287944079223067584129848490365630343690870142583141989910541398522693075466950199902772011993438099\n  8096571948285919876724145591715959557500060243914734649999094962280732089018531774166215707333892838\n  8639164413759397417797996190645277409657976928253653487828864697225365575452522803168847103926942994\n  4017744150565410839248185380972246265514689030002078212754945052791543698175496661875134783191865741\n  2558355397407737334160156114452815017161751179996399406119110086304704795713409531582791149697550614\n  2525966187901940474528757334388929908002976987789308698733990273247229361876519329728094639215880105\n  8120917330356069608825523217970057600041590448817939229844535803797460712947076082006515168336564512\n  4128112940020791146082742431095203360028505785103178129690111967320860994900367426065788332367599890\n  3174678418827376211282261504373578261282392358326023506215025388120503808761075779234110200663883596\n  4616931815750428606621212402530812757970025787253844905787402407677517611828280220570076803317314373\n  3222497208953222317699148309229185252467490518771658719283391451272224391076880381467647768256051991\n  6242899466641586857003358971005817274611700131317272015264539575067017238873314438527194969975372458\n  5045185112124532376009243047239954398933276325847419966021261252980566184976823050412057268302788959\n  0129847903701012363477732672039081071163930328926896985898027604285309812579195732408053145359995068\n  0281647637678616204990872205057179263264470138021032744757850959815376927943735399559906920110868457\n  2761587374741497813219922100979463616836883769800680193267246356331393619802284466029082574970887611\n  6126193917988989141472036055993690883893058053593693391145031666583767906825338101549463368505270216\n  0528658989694225709635345492408795324498345015230231036833493083408235168291518964166715750476290195\n  3467655050454331891572657051498776384149079126728380317905379403906551343242579313304132494807608810\n  4697312495453454578562643292457539754436311066043652894034438429341310299218563861969039536229361901\n  0163993528535010572993277183944687864902771924119694776679674321691661740183719065604639000765211961\n  1483507207555929101785378770569542074600725347546329875918008302027150297749789152839894533255407195\n  1666575323092649513942114255404511537786456966234680050010557665686222565597532000694853643862230379\n  8485693682238749031954900491665783397436698609183391998723719472588452887254012846450566305472362710\n  9926427857024582922373042200103989251437607418119767998004961158488903136574404814727769349793351969\n  0791241286804950501774453583056740426732857897572640251681129144017289388939060078622033980666196507\n  8580853482490794371510593186923206404967386563531281304079107222213576654821878051985853001988320719\n  4602635121427993700694070856559587246813655434167121600702677482923620401452985056021224418548337825\n  9554164191001106984416061119361341572843855737682243702736802105490498596516582972944555191824151604\n  0655118397072027202084640204393072986300139055434860805727208711812587793844984904370529210374970100\n  1663998151949476294999864284937367525363175218833130871088807978839241770462788936077376914701380205\n  7889504947811588756399045026857550561741605589946250346009210210935213094767593435082242287365273888\n  3742321134710601092049395617317488537802273146628841603886788153423753915600377407866832869398483480\n  8067071923600158571920292311134173510221745594119959835444561375619179631107040180474480380943839754\n  8267445519775059366593295007869513983479298733887810177945608175447381355918082998124982315003735066\n  2654337764521831661729592356655050362988711935601204167938372520077159314190351927245801694493938939\n  6886129000119117055885151579807832197586364396223411559124784518708290402202070552688856767767572084\n  3301962157900852947127982339707670466783431019043137939095674184931794875599199055140961968939225573\n  3193871822401654043894242976165912825960645565767896269500675457661057497034947209854964172219226415\n  1810279891105903306539154665967022021495454292522568011997322331862993012889772600548883051801907365\n  6178487244896155732164825745475381614346708401825711363753394201684005114429600303082324276272440249\n  3439561055939330737827909395440108058510853811441266551615428095286811705096078289107899719529989342\n  1677946200201699898496514405533694909314415663747898278927807417117097798317152252276910176290637536\n  7829868692728058988150048230697907349216189955367079070334793754336049453072079648770163350386612477\n  1679889404617208901243370958171600709412249362154964957549239133890521379284813256006540708721929520\n  4117451146578362108110624285418078166194941845801094848226063578640095318038055317525908824674419440\n  8371697512638377222189990351660818503784010369641914891107162792024978840785035770140561634787422640\n  0006355817468995774598161717654247358213363439055746336700418263131436114181603329667629676001679942\n  0553340364035181666054990897216378910193314935297881620939541968206581906428364266241323705903925680\n  4645463665882027057632649182915871363604687363845054497488839362556344690258479973397243782686679200\n  4894254402223869489172004665582573288023324994353981089464662938621067826158527899573711364825491949\n  6669990046514833047867362138961073979915734993372656791738205067948903357851703480156848711905733150\n  3073236481575437192770782678884988301848646539821183228847745990682339746215612585382662372283196986\n  0252043378627735575155507201016059787121746506973699977488505823686182397405962823899061718458168239\n  6699394042340380271521493416458066506094255166330604931071671973308360331180912226728261653649177815\n  4547133361395136935789707903812910081720867497056696396275052837274397916287648645576810769790438777\n  8853689843730036014312948664926231077274903705956214258751429326687828478807876284781862459567816866\n  2583026820364459788509829508925259441721135355859411423995153512414886100581148133714476205748937224\n  1692219063913137828116201787876086438886050658708324086986394651945116888379527746353597780059964225\n  1188127560160179159022475213976910679863209283384060086102184671398118661205103771796785864715889119\n  1978082065110498720927329367444664555227833315561279846519883483619760801583131790674551241002086775\n  2382206554614559397489786921632321555311929060258852766336700281085004036776020246255778526526697703\n  4006959215776156476425963474335647160218551276752648922167599801547259118353017790110214847022673250\n  7958525275484231626158929674912801498005754149289437240746443811161096891279255334866504394777647016\n  6897046624970217334733680794773210861934434226421608580130350246371110894166810265036737521403282434\n  2933691937372637891689833875137555791026545295231372878571956727250352327250114908852401112212315223\n  9535668141756360827968894201993232452749115000568066190671007305621131256401829504993342817836112004\n  4138708304541177799082829852391031652175532217390838633772407026085160186509754722845119753912039762\n  7596019905383829494982268416069423707468528511859666876879722986460275718450299124692064899469489774\n  8305050135197459222778942804945888936266175575585016684911380345406553384045092547795648368531413220\n  6728052953221775767997329750000772090302585104432463993406745109433124358732359862858793613228624008\n  2781507656081553948158074626359271910622864529121954899127388993476898406306935015305808395651394402\n  4323250666224298765923968269410311308341511967555361378398542211792194114495619165388491859795707643\n  2673697459359381066877511045939056158759634966179567758163129073143952002117162416023638780963299013\n  3247037859386552914051894854020217477434941180746937803653261313994620894555749060397697094955008026\n  4968790833922207730630331527199447948997819818289566397872623599650538450840226160712887069191795534\n  8341272915563450783929095549621763780941447603926762029912097978526101261615871270753558678860701332\n  2937414800980534901978765117235013926032028283193813753046174386185487073152287896043801626021519321\n  7278125010153660955395939482662978500964721476963041420928560836755369714576744658251377926893003498\n  1876730953665615409401818121381451571893485211413763239747591249359704551181113512626385218226841422\n  2905761672336221741638596959428555841526603258173569687347871528253854686617083171567897986920796685\n  7938520386732793631311097017509091536397157747854669238984188000859849849311591372836081341437393598\n  4087726813881576316452990400331700614355158713210484908604086309955458293249851269415089658896620196\n  4410303356985757879719137187474794198902398557644542753175912782182067919400959794488980216551994749\n  1076702194965961007134306836058843980625029333392918050437874958457839559752191849939915665684207644\n  4015770263734973607980438943732337103577946294959569752864241690766716259743117028013043352721392098\n  9591016293150314406167603304487131088893032925209532460424387158071374113333496752189467842043520120\n  0510171558881014072790337090139060829623257365434902251585715973438396432549682824253927771242235747\n  6365147462686304216003673739057280974151802633253647788062977836503169624788766304946589041398145368\n  3496483767637972403013154653988084173969361425867179381914048143126221184901047710700206513634019865\n  5824595491518936088602077543374425879392350378338502501167727052720609919380261179501593818710043945\n  4786426117842514617256027238047632869979661131161471745987885542037896030485119369471921087749508553\n  8628995850377779904479879768191744941429000980359750244314457216387987325933347484330457394081255124\n  7937720838298860465524871445206812031443287202182491713332412389413032203595572780514404956058136514\n  0986160079051007464455743265393945391647302445540904493591899500930070180617233371679820223173261954\n  8655260653765962406939391279640892608416114880330646499405407464597314824039656863432159312994393707\n  7821600270955871259263938062653090637227159030214454082789035367016709815238983270423840016348101274\n  9869965938331877195079369730835694367288565061102509453520470419059542468201989827961069973226213662\n  8167363122989056247377762923755761011654006559385237273915066906457679463920589716522864977434502284\n  1403508880830934461816836667371572514163826056268400920108841378388920760123000864027233105874037792\n  3680777236337609996334549142295140263407406950003571920163554103905240352907273269823891464585498060\n  7121971683395177468457273270578300165043438522673289066041888411382508341361379961981016970527367724\n  7197959326117762234453981953204724407339455212937548499646212828779894759263556471124809844788635485\n  7684404007964540865343117844698666996315507153553467533182789421749052954084700236515593719130070765\n  3206101646242846057544591362740802494426430247420387231136814035011649167388033979628128823708626314\n  7773710950925211669667728400056696523553312357273447122505849334210006543804671533515249182317846165\n  1025808818016446049994058848908523540861518389404360719340671292367260694480645999780777249220902903\n  8624407445869701420590221988806846096515170948230600096465701436440766806637279687569407135156782799\n  0649079063277209044524503248575792807082252032623968335485158606931459783852836169456336186314956895\n  7512520542758340843376543877357558113323322445874169130446233328853040341681853276507962953325671968\n  0304662622269392924233817614740621769438130181644683625060288786882638848622844076864987050543822925\n  8065848704040355625732567495201114319375477540770919620795371814882506166306925483188887162368525155\n  4848108075745353475665069108998902579006747116536104463548486258453296011166055248123665813348443402\n  3033838766947308531146822952900928520339707297247845950326397304709692877275566741078792127067696914\n  7191629646778484264375541857569851081658718271514749550361565003713207380545212738607371349328329950\n  6794838104667216961316674556498386410665538519571147797989780405313153130469535595601250122307301351\n  2282359030897413153187246065767650692731207540535622805396956670940455433100169920093401603015109670\n  0708703308962865869548111711644722242956459262470228438373631682761826381454527381901157150895220166\n  9555895255462206792074276777692308115226475110682443391341650025240406933025859894563392703641944075\n  3978120082182135850455473521574804387050965377446147811346871656555888351972792131850455068355394307\n  6050369009362962387836408667012944398938544441878508815883750876290001144469012888129558556775237521\n  6598684934324220643331265915748872953995338622517538068215345051124474409469110451163239958515057551\n  2312582940123674771515790267854663437832997684375181671324663954643020788768384514133131120043836272\n  0947289667797439488890340393339347714916556098784406261235812235129549256259585831916362448449112395\n  3657658710507880739670881097669121051336720210884909249834814108085147197931198325601491340711816926\n  5377176694886325677385081130992939242797311269677458349060895901467971121975453286879491003849694060\n  7005645672377105349189064450652802955744757018578593533302534373141442053035818947250256597419922390\n  0855033384792966237076723346362903759950087543075025796397415020398849590375857682910017344100301639\n  0174848563306422011752017788579842745795912502607278147035731188031082540722337056184039814643086670\n  1326413991073500244188772556351318020125185808148975409736973081487305408871737347442840919291643424\n  4021024496426392873573982403810584200373458695310703279798502293094662680690179272417870980625238297\n  5492674271740109313390844006031771503988397175651715664250661408635197545734597473285460352577081637\n  9080538731580692280533069866107176170472318941722385413267567686410850693619772850880899912059322947\n  8701723659957911254740490230421735611643954893538440386619667832273836309911100528583707824962506145\n  5188256938516357639930307559070740917791768960090942166268639945930987166518752762806121677655991791\n  0290609779887602911312938589553501801828282284251271767414232794377249083446842157094679010491342939\n  7381565935133360706191251839663489878904947087264413445808102413965253897144390891777522524117802201\n  6887498243016237329016542389588802987575006283104455394872770124930831524949797471267648110417923690\n  3256497908621475914072338569985684899320722812683150370989919313076022276809177596019419663136065337\n  5426514541707897265642169499127767201935651871297423897420077422706008183314686892660294098085839553\n  4529813264337429483971371578266348938881758528599643215246849202217050423643862971531703786120257828\n  5472396855010947264868652733936132705317091849608428679730630043616542134626766101017003598757979069\n  9862232054880264185324862925109616879659807695389765453614545744554001652239142481489297293814279062\n  5588597012238728348902405738552464234439119934502720657717152104991279089921169924264097040941620723\n  1803949694168898542656153032807224682554245811114270095732327190155988537895755711619245963123390013\n  8923872721527861242038168148964678214166675876691828545852443941373067714640373433094041364476929357\n  8325756754722460492377254530663122614055017563811599943197027883656146997453561866251992177475878966\n  8022046667762597743833899566039040362829861482702138619053606636684579151451491296624149189690080815\n  3987865583853781157034266034430482255013197866047676271115191413296063961296795675148556053596642717\n  6487338775484216680732679344682737453566108015086057433991986215295787876111855924472352713169009007\n  2760229277857204073949284081028003889856654021555633375622291458982640581718488090352195923229845591\n  9169463929579675300915498710901410398873834792493628931057971150462061769010546893013669125649607645\n  5191053362731791560064596482747654805723188947139841098601302864866561626662957625009817839445743520\n  3937949163186162324508410436164555398170233396828075408160676789235051027647052040995697148193078321\n  5993225562257913369017793709375425041782576570705962239705424120671641874246415575661781751832110091\n  8462648717765091190334572307787317880484937765442539452471494240914793370735134878763145769851002496\n  7498296725718389578378464947863985440231214546407023160932103605559461954760831841078154975855244947\n  3221438932052337349758294772936978542447331921658533831755522494658487593974612031368176924912879005\n  5178403707516106150863284334456738495665891503494240520078974138322121492467179808528463428682044702\n  7578369882865730447370179875498833918216443632043836027526113090044610037477990279490761245993811240\n  5161919960596513900779096342935831190343056243567157340950561636287482782058761548998813622840063195\n  1119520178080967490670497658942820319324591324255961711416431669441618015524066188633117399506879643\n  7781553809722292974598686743643437724460225008217013149369918140245420915767683955013168181074034283\n  0411268652549868032645793231845029509774520138980553581941410191319848338679855548199401716615848836\n  1181485049186467563917728633058374665125190995176278621822177837392160428438123658550359877683167988\n  7691766786403769600339672806404573452597520193285403903843278475185561475310226363733593846397999451\n  1977345685665446742838958191103508750244754207501175472655793430406416448164000185489617235736987650\n  0209146312440068050665618211320293368595675472266646602468685420080392607405662982996622827886673306\n  4506550328841629388295625887554096946807070658121980508578924056678207301913200670603642168364916525\n  6313537762548308959484205360987229555827524593150094334190090781546711225727107985212227375561583261\n  0302392053167927886141183298226459755765340454234610490295722395875331195796195022894605030835697403\n  1984824793750389739827953899206897189129627097026816017999488236851544102490634503793304638505980500\n  6893688509215960924934546170186966470225326193881930168212264843687779523961813687773501783987601428\n  7972084836641077328764288692535871469783972618881033845033371181517114847157535728291113771363131977\n  8212024568460969777492196379684737496910945644214623527467527261285301800789573543032753550589002760\n  7241710824277977227327359006266638666960135223025608509729963153757824337925071621720744063331379638\n  7517144392662381145539390043886785184247175875379030663666093268883193121032320723514090703360541657\n  5082209060337201668113885031468464451916950436558866152125950693828434458152870871228293140727555933\n  6996812109903515910164212560711075765634430635117056731674352895819475495216114251931100258904134528\n  9007507758318181226707486169370511374740514479454619795301747600610679345348377394055213592998818346\n  5458679825875860431734040554601182336493553306359083224391666806121029285929309962757245031274894390\n  9642963320873077467150077733008339343158859637012443376957769454826077160976708615481666794238910350\n  6090461460441303968713689488679983508780406806438162177240634791781191620062957777013993709343944321\n  7249722182319521253794132602753367456855860884410590851123027060655379689486119033343118293391087619\n  6185654145709689387436957061234280197733557389624076816315844335848770733607207064012636724168412550\n  9830095138195768861512464866019104419000405387333567120152878262611453144400194905011564171801462355\n  3003346080217675891561479950371467332745815027281127211826466922555444131883985950933419623985945561\n  1849476747865322071492014140435873483891207105258163644906920398813879272899285398846067946999733862\n  8784322251003743280666592641993060846936167567748471799555382249785746556725055674894930960003881116\n  5025990005993740173866604706262123885284817010946710138768352200253700490944667104755790008627486998\n  6075801005598973977527485320741834661939937899976107539930251144261568920485519723078407582278483831\n  2358647816828634723970507033770155108037216863941507175891202523520030936445381610008908813050203916\n  9341159108232754929969978413544833229671875424182246552003796227904310697702416765482939497616404950\n  0283098389394260224304616904843558047477224038717866934915392885786302298924314368417304703015701090\n  2306067503702447200332641348728560100321972365652015909492934148262122999823173320730648796012037972\n  7647315563630376092938373423468209183320342088037583199689240992749363529073564984723927517964835646\n  0381131807445271846223458597944972284318052740625000578442004830052382387510848554266486618405878804\n  6412068103591989839609872713115064108184549045557992760943542184006717645354861510528247568296268598\n  1806029377282987924425294387085412073102529404983278917912774900315217552148825260347141601819538454\n  1767118062521836875819415407036768156157661817204779986923314640336138033465204018426158039026418253\n  6185722468448606128873686999272027416268063766621120692903461969545811364344741598714018921166046622\n  6582661590542069763943593123662045528756034216500347360119434225614914032015794171185171542756396517\n  2568645384670954524837130594898582559745277564378372093903737606448757805380896666613991839630554346\n  3515315481858867792629127253634262889852568544646981449746189241495863663671981400650685888608602242\n  6733798812768796940649702991545245272132575428195324917311506620858665207749095296510075340404922735\n  6548282957025690629358881690414651069717772420955446130258543817863048508060589906373809054306950261\n  3842422270537535459859099326696733216515194817253453274733360274472585272453947857870490548475863311\n  5718366332359132347588259340641521039072871936326796375928473313161233978154985650774595742630192501\n  3613442181778657326845949803925741969699998764598249567094095595490645143192997532969902929018113346\n  8491893973167337404737610215349790280131722337912799863914710105736458088249640377936691442602252243\n  2918220359694796522963241504625930376366432840865616023121610990271779794048244237437724217545327436\n  9030749262617258880652233261410603381653209323202669910870847586819856399049857501176199636905969925\n  4104368753291819072004157598262345466727015736971133357041403209379345126606070799065586879616157998\n  4934109540903212436544310873161586375727374817450178665573793984866922911759920434224760064859760054\n  9782806294187391474966456601976892636165982896565574458040991426890947249706735220470116191536009452\n  7363253066644020100232018732278197614868663489891327347014448203242931178410091528333303769111970512\n  5251189029708294297488398137149977805278164934370560432600535269810691898658868981610889926992043454\n  7815535740465293822554757923965125781698498673421821853124073431152960821411209199994061601015821912\n  7373016501769581186190366897792756904678571018105939373143881192914749443565221896260286325866365190\n  1745365921218638768107774209158364690909165182739807531030664998062448492774756188452973294727139148\n  9972684077858977868656048723305752422857172473443666741818123270841591791478616819780032875242194648\n  0119315937935152394174090419098412578099090388940779420467270491534500024860427455307306836472220758\n  9308219944523472145218428256209291437681438780213969363997860221263221098220773571441294126406537652\n  6428543482970693655116806728306148155350067799273428746717408366660205372922048484087025230125857179\n  1456966579523963596862706459037207268058794398134006676701411765812522334810483868677174058797368961\n  5599621784654973073934095466043145860154049561577645616734472126427468746140830206387935980428496622\n  4722325504660952317681724586362611284833874076507582889567745895887361095197420723212623335561519338\n  2471760218186838953006797502120769043883812835625814501250071190271565144346270648149505901969961390\n  4056079067372607241129244719947702838483531863329817619994731283314491596877750429032797703476193806\n  2955123840138422910035767692969859590544398289266660878010344059670559052076683702101595219513945447\n  7311874107235279456084435494667607928826819356764666589161362140424785642792681562544850631668526832\n  7524656002747765241279427053419348280546267028159924539124873937558094012591977834653365573562593766\n  8087699752574602702166964925299837753819693846254708518861510475226475136489188335738189169712195832\n  6810041957653770211921182725665088966824675048666996598850420411916153320898856723809260181428117623\n  4479558294288085813698860737275497491213068743742194301486676625969169519536885691174938231969755955\n  7940217938873722515159971405447289708395510365486662819650368486846610392745568414363590177744038756\n  5120807714563648777284438331563572496836756314810394389680921192823374145076186305657777377941453330\n  2578207887933713552328193066778103474487881453302276711598246301467739131806469901714532318195729640\n  1713829934458665281042390292044042050301085037228897072266732041640758383521162554729354209770671865\n  2620762946720436336432735056632041125212872258941499762804689148555075973614650511764125793028369745\n  3203604650615692381197213251056180613452134381768173276284141810216441341702491755843656811454797775\n  1958280662844249750379174772362042042450573630609111548402426995643360035301436665975118280328039534\n  2105404919103056731421075413023579348772342390739593893004368913281485468821970534826806406133447603\n  5746590906564609800971717699575204375563545216850442243908278083480721568003121380513744755738663358\n  0661289825695253557232663073951954063697946913927391950929709929134880148676072714978516827026905071\n  0767896576530440463362626888722627429312028751738497554214315049989074564612156955425357015201474626\n  5873588291544869367168210972638770366929876270333269267640511235659178773632477046116118752837864088\n  0382801363490414508513182955873803365715923755404374036600943126624937447350183694088350123180570255\n  1089418469366688303806236043616899868181504628145439937084394672379528195303288606099631547805411053\n  9798317391048191798793376309918240071636953592567835866999085256828346179992044849215828682554266066\n  6948065905588375476747789006303076397732011916264419312313733282236418119343830505865855449829986899\n  1146681311711942189160179373602575963218532104868749920473470299426787127613334237668342822565756501\n  5748972028034318032062448495723097390057150931453891843449438283973734515799805156259164322627014186\n  2062369447593021410508502812036049109939053684780560216627046368552572741329060422899563510252284751\n  9070308253273849955553304495780330902592753163522180988988262911598033711257017217676690454568064922\n  3051574746891557171017567240354189350611288873024043144319869586521866760733038549036027746096354501\n  9525296534070301597032409851150252930588656719011250832847149680648943813007837186239244681790216217\n  3569122887239480216484647377517681894212220710356555965079794844990082719355281479143404037138717208\n  1760903198856458746108109910593691774379471287936895032477418648580648196799561464367082487089936839\n  5131507203056530300788685982036072066991673761641475665428771935359104452116916769281639636456297834\n  0737064788274061834054357077412161383202873787903785858932745536149564461255050554782668745445509088\n  6889469271859889494234495074838218501843413032362004668070019175045926284083850536431267686980340268\n  1158070981034589860413084173550995694415179917543233480633073261339139979788000382109132766014549611\n  1570428580281606751623381353863052429563833095032019287816413249223004761179535824956059145300042464\n  4788062130246897865596926292576357402879940135692116755390400269966455602568297236950495909960271709\n  7381666168678004832729299059428102968161574696306060610106226717021253966747951389381374853895351757\n  8329451364260069361377774400056699301740201136677317877044694506012922607496911061576207637893345041\n  3733651195600329078352359646532657474974352867211162980756758510838501606998969358671522596463057009\n  1390876287416492541708169096847309548860233298288800101652962808976987723196907421027009348880934455\n  5121881883365197843185355960674763507221611787287356394656554342761406855941242591214170781163030801\n  0192587621993809895894305093968251827713033033492664885329561879526644631906349389649279747796305818\n  2377606580354022796691081809322672514261428768508550234036395970562141251513762046722444289799785545\n  4131901372056002945670634038242991780751257244844635771525893472233684526800050490579407659261183404\n  6276469983532198933127117327105112938774627200813172632086712472478310369532505711668466933919993838\n  3416530133092477294293584707438826342400701321713209728274947961163566782615071566282502125206276389\n  7515665851340604552901092611263816622423668992710649041886270014421128735923939982500565800643250607\n  5094589358500721807293223082461082581858746713340673344326805154756527611229009421546556183103412687\n  0172286541622690757446663740257850581983903372668539128342511388977610370155470596978428438121104166\n  7496423619368984063561387622795954521514689288132823943963661294501387816765909292508975324716691236\n  8348275154607827280445182434537596550492568064853230999281451475345509275552779627941424557440525521\n  8825323955625085721179963530195675811774436762550973197511556514845137285424074904838081995588091516\n  1179392191042619092848578161390514823147445531015161591784145999471223905165969441039727295741158339\n  7459390620500775807095967658989249614373434878156377442083749991461834513411785721356576510028821653\n  4378838906972299886294622686851956288323205705378942178959367844899972838082251295857374295653148704\n  3040321954330164722045813979057452880207472858810311408587987472118632864898447340531146044004800111\n  8964742165719993115889037205900314664181261792091194088785006677801099918546190934892669185091189985\n  3281758015614963442527274202132308326262537829753747808496486205747377298059504902145550108969348064\n  5109743330059979855532033131826917519159195006558488436551656335235079497441486995545934682666761749\n  8419319232391985849314290703397249074104335315507161857712844527045561514872082178790107580994599078\n  1903407684845590803485256121124463883238877600772564059505857614506172929101763421062016322763133570\n  8698416113338433519159552199342391045655659731008231699479978456319598341143056370588841358572324394\n  5999371608451544322473332574743269029321113405536052609072416883753354361412870234237825270895382357\n  6585165964173281100423670224794265894895420024627797793098934507602136241713703106513275975961348992\n  4270047047172533326422774262347566320225179842495249821276559511394568141270076623154851582573596335\n  3826717922669936333918066855094802896639701633580306357779206151292995868181602332782682875613869534\n  8983385807840486775650291623281022321262862370364711672590911162207449944470337154671719355796034064\n  9572183991324315717586890563578201193562277776342162367247566768761722061015213389428844275546380391\n  4298293409706376846651169968454977492484216234549879019005901223071102488058804992082026734152133452\n  6194822718040452465922884429554190815449214580890457049392729832168834134299536825867464108367284683\n  3132874321981230074513031444007683574024462780977013002142187123511884439078142864571486713031627438\n  1405338857603885294690507769112439640284427539211601124684855885908711120433136983355129831770447543\n  9527351180945626273650721342386754878162350966398758989078105843337220397544204986189921453439457001\n  0766993023334045070623558228321979391210716339044784574064959683736835999610270559810934327545718226\n  5819162737640832649194463392541412570472789300121814099502881776632184985453085666790070376265770583\n  8273174956120917523247601272848854422298986799882662839508678945771438815809675505801148163295101341\n  7845494953248474350246166826049086054349862607076952206845769308881019936388602056908101664505187218\n  1500574347274692400456628013524424290432379684768326499597859954187679609888240649742665229584406972\n  9776191462648978315102874006697923620332060404453547944198199894752531957170520855316177791641077276\n  4613921571177402991355550151670979661965240622229141609972270298654087146907919329111017460401206520\n  8119033479335074093396733543810667764425162109106409782774039347240922697139986419324018336762578795\n  1661669211485708440347311098577186041438065703058114089652279903370706792777717324019606366905990239\n  6600617475966027436477233417132112564069573043007387189697608262537784076168904565036964121017260551\n  1050631805878307177104571678917209315551005131262488507497125708827760818462973515666064138131857756\n  9232194221616981981833861591091112129640683476454149874892596769391552088999743483482510977171733477\n  4849042415704476573657457752887031370873919072182505772993177204212596617789094627810737489396727533\n  3669497759775761401339096400599495991247742405822602276743479140436597750071174906872762693456375287\n  6279153861033480986929574289849008704137552160375946787643984362695913728997237720073145336673352699\n  6836629260856570583903882359383118961476361331704366529764436074940164969717395660023248475312782613\n  5116274516934985914972842578011566354011257488383449578205475651348675253533930949298777856682473832\n  2471363412781566382459050230733983253608300387302483963995418402866298087668996005436067463747817597\n  3859320010970384009432908482521486078558007203028392624814842107356768943650847829172394313537730783\n  3828620452560793714347989024775448000157389116577894911436600367935436393206776263021105215210135921\n  5469454499705888762836579334060613239110233812347891165133960648232734302761158534325707822596745669\n  2639944506549281999054027881507062990362135050452317325013670624394106180766761378661414563785766044\n  2074924229269770349845012651492167176963310516767267848837295490056786572397844276311347324977198906\n  0076187591408960730665821513844913456155557115108451321597382911001114287389599461623938505836032323\n  4420828814504339150737808186319372078380311364175837348751976507933520535426106483964680022831803234\n  7662678243897034382828567674099388012245584182825061658871841917739713484249557535536154283510624483\n  2821141075660967969951048252279421587069315186868228906599054454289767683407842846866351695073592900\n  5944652517186518412045443271163745245912494051031774974327164330478610425203579403271210384808446436\n  3330137152901498842752377949834574799875281511965159434402988721491706555591849396373620235346368882\n  1813143720813493658980418852618146166856463897428391505955837039471238321734527348213615696128326308\n  5165038215295650842082471083485563684152892779777775636659828621565022125074611675903211654209654147\n  0122942838545756721417389929799800524641816847334818021732521988211950351846705828084292711592599970\n  1537509747900795093033188056558010139808122984565468161871538579928128610376600684408308498397279763\n  7004166030652461482660428311779328935587420559345188132647605029917983382716373959860235887851346092\n  6732319515887297292466770976350989467701402822922459093649319251931742859694152366564659951119254685\n  8864800103777931630738794443787115163435808683855098036167341177467955250541569632555175659300110987\n  1034383335920075203177187132116942973736665048161622813974369194360219793318911371477579284604851057\n  4542832874817932872278710961589682604151910321603588677947479259298850999499049216484971385441255339\n  1673798326983742448741274547096206337139047404836079415752936336390448179541411173493620260485120123\n  0536055436888793862914480787910052555989328252773354359247067399972692273992775653397256696715240967\n  7307351761299221420255506531429549087426170533585033317774602589152893788654307666139718694743502046\n  9696687505676637825001336654434120149780395334094843058804080871386953158989175443230557614844599297\n  1287256207647002380883308255786375448067354538598763808584763650695267362809861199004026798113020461\n  0101944598035927435305744929624227377339552016915800533206697551301973113370391256119133054329794169\n  9192948293905572679579528177269687932911425777320500214760199698152202061524517942389845818526827978\n  9797440541656480562100833028605473010316050320145740518887619845350296999926465795650019044827824173\n  8609540179103702546381436244525088702922663923366404351967800356654544364250362507952964892139065648\n  4140182736971450214526431646621003738099504185588748963082465740733426300253099497815591421287519705\n  2710011571017163774988337879565686539344266119544077414439924874232060422661597714780065489643349623\n  5839622113531257289820135598481565702045748210917373786628025393070446554368897474906584779494095981\n  2244787432218660153009734548024696172671294778795194415134401730118832367448720447806236637003524258\n  6176568380848573688569023709229088212227208341700897912925654354194078268993055731519169901180705018\n  9588596474048139046260970734195449422706775403353710296483606203275561731021591434684415539095659097\n  4654992791537633294735996020089802640794682925361277898320585360585618611894514061132224271286111668\n  6725025703363488631585717397116032882123866374918745662604295318985208791769279853205968708273206077\n  2049087562497623985063918737880636107372115907573362989705665746883773515985230620783485667267399450\n  1972457061604170286561431266850797557168950806738619613357613077933856652942611789955761282203962786\n  1630366976572927463176005226248813002620159344695993323013044439085141440696129490951435113240437281\n  8037803052701614745966697318233961655755091009447720112313016992708211043728483536465802279843531764\n  8760439520807362259586407873458191531059455825240310753772157432145713447781843098447499918919885723\n  4881539219045201566171925554299875334540023811097485202700537114712389797470101585475386268028132317\n  0286201290386585144236448649286552358171372029388017529410102252028569118718607964501087652984253297\n  1631174418650752018769292746421061313176203085067906658825606161624512329833385602122519961320728581\n  6407020906231271834484822300789404092439163274524087456678136735570039755142780739200343533132128228\n  7328689542061881883291418904239295829349293059481391941921015430324356744769924306848954952023954564\n  5503065047097125895308641001156968732728057534628882092894998037694276715237246907452768749411737611\n  2489070191987929642324749483718639132922040334047627285290480570200588772263597678817471579821421764\n  1766434900548515322233513050200474266084260275811143081158773578536814136568366713391740316070565037\n  9085284322678216464359301519207099123433844476197489701363751895168498630633471243935719934533251192\n  4340248672268509671224442280954862096706420714603892359340106844004753696386497513597358331093783260\n  0190925157443192037612293770890557454362847738453351375649811641233689229522888668519991591629961786\n  7208191837173473070068228127018606502753029833901466999574794461070267161116027871706500234454852655\n  3180461527980301358894310966438222475439771623046764635318028199644937566237115116051978758708342921\n  4674980001529714109167257057969361548756157178235831117710135901253539556871274579972017592606546190\n  0593796089784619027221814507235879548427149913315039620305124110916504419669755825132181861783569427\n  5540614559727053523826735711023180819720853948601822054826898663602869566818348668524544614408406952\n  1826332804876044469190082669676296454907545722369233274416649131955648643994588993387758700988054331\n  8639985540493230677615918285928743896057804640984208974055068329611397239222226979036469776787551730\n  3966644741574726584654780659639564895358195570035797166891226946992715128448647722739811741814886633\n  1928994659470600892113189894296771965704861852768613423688150000417238002829767005277922765540848554\n  3334861688984973871867886189873232380042400963864067984351716251126972592465867872110705380153194957\n  7164948506298157989469417142820421641655866599072861984938491754802695846196422947793149812238364153\n  8557038089789007613901032349717969632547196564912274558263541323414243643574594749297927856960776359\n  1484728012121820571237229125443324556605340748495181446769058959806952003492300124986619376210850051\n  2364425478264357338213296609669731653535425624730809028817761133739720629836430505408619406221838502\n  4498547566872126006763397437315325783835487482440978097393361487310202390453380947415977664560313768\n  1106298921409016612327003900505022947613518859124106470656031298014608889949278623547812337075637352\n  4321271800610530855171703405360330737630187113669353217698428260176112186006358489653414360670914199\n  7792464097211427449546989146355548286434011040147223008474005897193942555677557844039936570126377009\n  2330401772015709714022618972549024996396256689084858977504157130429271592893380146276281780424512433\n  4611567291708721811698669587131261066558109715515556963348198442249377278998490016913340650139225583\n  7452536445871131537749642845154005364042185976909329790072008362962024673223965883741317529058662626\n  9446735210442603791931521103560615613271779583324238941011378308624546295140958171894165381882609858\n  1362550702814720744101032283856977012126679321464728011596824377110164058829203812229822825505648850\n  2000903159908409669801425015995974256102202631836172557111491392144361101853384556828607031576644860\n  5768250919462158506950828494085301806644991207142867598986688412790646539483571531979162968219164287\n  6269125672169472287743672269074631085341954406113360848716300832207815371548154354645837025948503616\n  7470707302758499672313280960162936123357408505167586704703228598724739808647326794039491393791308497\n  3632414139029439284576638351984218676346643018086896069214338319604221009472098439766652282254436830\n  4222054701432565119426870397199293424806391183114715967928827659016065848116137229441994332637690168\n  2224343559260799088203400234350990585913929771576049472707702830957584270709136977043713575902026722\n  7121355344973304305067410370544077345958430922769374840395638204885926470438636211199354225500002561\n  1449708505270500916289296049847398305977089314120419837701870006385807844261773612787580995515950384\n  6662074848157250182123540825433798202752568074574177955302589468194577646065374993269932888205395151\n  8474085147443635682109242501710525863495345791590287152212995365959158076973734068649381356148346862\n  5939742529349372392299112609535278901474152094619169375233960791800588818378506688578822174089302237\n  6707892649055901783573302904986104756624088404630174420916460792765924033500521369750536665803340501\n  3128071242798970006273729152590701666746437245667874325600195554242094453363343939195676804590871330\n  9834479621296632581163765466480890071124740281515643434631081445327339715432334544926861930744837353\n  2903424290227063234450908155379512377571610492712179818535358509941553871821944942708611496926208222\n  8311054505260176469442149847969162493833508643899797943725725850349473321123642015645445958323210258\n  6733821208272011023617181329162813476936133623163000555185416994512370308747176934753063809491488282\n  3181146014847359176501968305714704713971680541712076085415277906148408154352770547111386619355191825\n  5549673768753756559018915892076743526148852937632107873123875720648408237375303288464023488292875867\n  4575174119642595547325471299887844133769717447828951480606297501598104109651792487372542415860607092\n  6343451122180515157680503952320798390703844559080248976751242811186831122353594495362332805156428450\n  9116382532846827690377989405609730496598216774794290605229064271154090759630490750045786694806442407\n  9141604249897363962238355342656882489249030940135322759829226761802139944680189960320675803429397947\n  9500581123563398697279023670197762898407331986142970899455340903726057682234474886920102976488719461\n  8758629342131709327277769165187100249899666585508381133567896174811392400806920441462566538294522339\n  1551604594824870277524026560308024160840633583104991593130853947426907323472088411918202484707573291\n  1507212454468985268553115998511179393810802097734738174933999888973856536994038759525336217482394715\n  4783480058946039366591889289962175210471630466038444412373450910382932483894560012983649341732042243\n  2165642758286269646298705494370864746342771185293824804393582160198607006217119659183259180757449365\n  5660319057421033069753707322301404429391360729974231482186205712797240843229742225306478470222877289\n  8891720445413641683018620592669478106500157727303468399829551105996427519834420909942982394136155832\n  6538840685298375019610026743279608322676608982437399230458381935994455203647109590825189916629159319\n  6398638609984425245591944423740980765055611750578961464359199255642675963119627783751287465379652386\n  6525681695700326964287850720184716605737922725209523210990761127024194913962807481696514943204319306\n  4899696752352377801336017153557941527226744043835477478346154171361080719710473088602374503121389008\n  1325624317204976886802282925502433493959917827467695941155443098503616431316394425732596746141758066\n  3424492506040232202802946987375182931270655413778298861958481093502663645207509319615250820150239512\n  8106961883020837877917531424737800666136610712556138095687549097630224818254733695777442501363334650\n  5272962419515030700162982343399091000615550249467371288432197235339945293806722341962170161634329247\n  9375744591466577156266828511079209801382360277908524908614061323820470296033614212396789169499234232\n  1715288832979939112946652538472686405318731979322677702760178715157112713190221683641694532904519520\n  4615033553473446978714152244708770708456141208314980110666716520746555367187872873746904987162762468\n  0530857583522804191995607327665917569577300287920706287306356228290710931722541244102899656219439303\n  3935979312729824901885059982075302805818268734536262076988428838928963551772699775527089280711983832\n  7126416498135850566092974668194143322037636016031702386454010380419337568874559351238398276056529937\n  9694631115736236765803515756436802079790980697358928950333631027509478478135700064703167653179843748\n  9385931992844679705050146584222778269606759197774314228489834622963809575224532923435922351304412034\n  5909610127448589140505827476775911036197187481126259602724586676557147275493941205551336228916904263\n  8208357399520615723946451744498991297021106570959449855647567105391013640465590616591177906243645957\n  3934607185777117061118451700154545080998850040593155875095120616554563146200738739443327439156540822\n  2265516671149813613507373995489339174808637419664809327817100263955025914047775193472052693611721552\n  9192894891128512312563105277097234938677089309885624797358932759808463423218516249853050362731645550\n  8600244801128794870890218752873453929413161466208814826808614162015915549122041986025984886099100100\n  8935521986004274340573101214273402947594356726977628542777276759795406783215499987080260583813286902\n  8183862100061003376423791980019442370442063331998932146516974334576991282231826114090708986144154081\n  9914737474336816449824325266081666966973361969533212777691297726357984301509710815856277952410140312\n  1972539950098548370069915726381749334231984170867848596330912936697738356288707840800239223578231036\n  1229231334313870871375607264795530687856767876140867978538841839750850468350928414471968343566924539\n  1453969726703865703172962418389792354536870706291053584095862528817292816924710463959137654339775103\n  3038618690541627854067967188564523146253468346430020306636243007728041839150504839977463906523527004\n  7668220337015691585237701399054126383476484663841179107634163945096265761345248340913898753793488871\n  0844082251502479447198768883992003573792607365768549301553430268438483889314027219668203872768490406\n  5078641498395483862399144327100354841428571466367581410868575684974964249205885698437459468657448018\n  4934228027958235637756438826823262418776221622607090451984593267734773501828543606939352416589601174\n  5073761140640689598829299446453818686066474728889919098229601789297804735791247963218691536870365595\n  2944433499542516058090830492735940881012512804591065050476649626758222413393315802709420923435482413\n  7545730590871565675676701092095054671117837732104759766979436357024999172477640990996184223422593896\n  6846991544188772094653007034437183115728705732067398759578214079407363342360849638323335917902277126\n  8263032769487753200468018475770539434300795119666775243961591663082780839590538322951127233820755074\n  4153078897776286771662518810911875351973300986377174786188154764116022239030319559678981537333332582\n  9836004518897341313857960092977745880614240104591501478206797394363629199355822760236751034782755648\n  6627121882555285317825358601035108225814502611204747092401718602564690068461731767990573490110072728\n  7689261945275883358758221947384320834578633052807557454938289523900598456827291413464323488171485846\n  0678305948260145359687621596708124955323057637815649344565257825522938249626575117074949886687654410\n  3827053374089892104036867736560454285845169503140223236337570264179657785208175448924655709924081323\n  6655786985264535388801118891932862519259222135566768155760927630615575930662647392608983278347680214\n  6055571315939157513419736238143794497888858119633437282923219663203357801261130770108572159898202801\n  2452701419440551082110912628261670708062742710620807375623747391179018806303915191898251718666137575\n  7275971038981146281320941182432120115782881787555919083128416589810129599397245828288503470905302829\n  2225178972431329487897374321507341389531992364509403300894441779949785506114695615294856553112229462\n  3526306051560149924641646941653581717906597534647747475189449033886376945491013384753795701243435328\n  3214492982757320649460057035879741372847308556850024140578069949444209656454542067040671269177034205\n  5893545921475139946586563795324498939480729634535959897732503522425366975520262596619022391137446470\n  1515637749468173440379453288595394926777638755908647972478088680068172355853131435632975431766043925\n  3838540575689974298509517127782488540660920326559828127019571356428139254066130983872519138828743230\n  3850700660199215706888715653136986458667179283657355256586271881440144317143679374810596913709321216\n  8062424716237296617153934399533680541456986793897178488910159860309541293529874616910919252380974294\n  4551488558318499498594795902426366425548655563314934689356150341488374884631294653005659807467697736\n  0194559815286306276126267663557735976758113842161237331459708729860471384174012488889187971332736362\n  6251131133467653762929984089037789520000853939976358474428197985767807210489634599077801542669717456\n  7542617238402203277336476397551754916653384472733685352496691562976924834362650474619882335945593854\n  2388739013641770469453957981187527121597768442511799580716945466861749820038914136757425295199235363\n  0286409958477380806675941697155808335426239966791371918119745650950142157414450246559428230866854834\n  5475504175328090492439697577338340692003659626982380632105842116831153608063960003029834869862501418\n  9519615977098530989341590691826447462124298360754346446243464183758912699382353801438495736433235890\n  8803400365035629450989571731821193875360604033750257331182525704669344702757566572460202434358051761\n  7980430500157661220685910711916447836787755287555765149553864629003147784335242018223228186288983604\n  9955671009471307362511750465682887493345110800437057008572073227508319673684109210872646030862698701\n  2176044090402806979491118396436605218431492307351631588904445480567978322555962857732503063907386237\n  0333133937948649073559546851796504296661825531052645982451735375632502837394355101805927205309010514\n  2909243352731278690015151305587405395535952649030281312758926687850268380277539808784196954244470759\n  8265277147636801344512270464696586160140500059813554266004555304125645385648993160312805596469709727\n  7176477513623793186953564285143044563012761042826494036797480293301901344399860928405868810026888328\n  7786069070057522291637884595429511271236416290417249259287033518121777245720634744414071045798701168\n  3486538940860879346428858140532372205220333882782491606550751428498895026730473386894146657715191706\n  7007154628493341305459532617825762474557786052890705568120939213636020794840019045348227175019919985\n  0351721819829155537394052447488160840114286829854219815417399461519446756653991108625702661728915721\n  1616708612807864422596878065405524084076980926229798908974388648718812412152858621071441713146827394\n  1512454023152718464160210458750969483759431807362021929374001190274750271765673435942473670661803986\n  7767305606401858990535751230023066083708711686914757913363840862325384349267186066139046684337879651\n  6790070950960770044545355631362405135816161738439970087207800572797374766973300019518157166514482156\n  3406218186569555695230599732096135279604360849164645440098534029608616745334380968998239436938249495\n  5094716954167064128394245171412601916247382708669769311806960971015572581478531946257461453503976260\n  5546512543502145241434329824924138121771320340323718671520627359281633744103154710463963111770834535\n  0154482594576086659775717391457660958775366724984051724570082595821245485219616437893131098824817003\n  8422332063288500432542084921594423734706930124693333918887639562414254068324429613965686240316412840\n  3058782564652342818336566518958550369909432595309425060808246841425531437037390665109896765398087358\n  7499377033458953019495195170217522645207320360275463941311371161162228990045708028475403614063814770\n  8904136189639814679360905829482054185806765374568452152011414513584740042491714183497910852675578692\n  3646084051029640568547162911479605166051298601164218923584706774478369791634369220302198889638490152\n  4172648351087367313458395344215022462615533663361483478643233561380530074966762084287575307448476761\n  2212952046402684256157402198984963409036109218476043128882969266380818247741624321491805174576051652\n  7671485956723605854481485440213290753231193378970542137669259894146244375806251615321799734696371796\n  4554733535492490014056074366310647417667998572569863025283994443463799305182425984125798358649590627\n  8906953651854959181602825231129648862454662474149878023489619904934728196665830714757725320158683554\n  7077836728257562399243554639377454477973382960292239539101363924842457990895204656398045121789111868\n  3684611173674956595237321588319222476966429594969400736850502840377689062658085002467172958976399152\n  8855287127946920792122067201320528093964522632270868221231475800660317858618410693450455257909777395\n  6618012334187417941362215786050078339034591252524540485754363277089363734813762506583880204845701532\n  9172877536585102843043037380946458279446317034769613448682880549387474207836072091819669560779780786\n  5955740709604430297860930907972073074960701081558685015948097534353052729341161714831747339661005175\n  2170023014799010869034522977048775984057286298941810215296900745556597243348361850377715055086033011\n  1505317616416961877236613812722787109865173452038573787302166127222580623945634238951182710638999382\n  8193946808908917142686787488703236974236982543558888324608458202840234836262358836434932664801755904\n  6034282151721956396349530430084841662178271514494595409011794488525950494726556911945792036793654037\n  6113867493761913528838976548861213181153030471606196867043644288434988225523312968750291635458654268\n  6608894604692937059649512844897404856780035852704039935626048982822152555719969935257945452617407432\n  7085989113001429067140022594327469021898299517955344274871811164211742934346618581259577501754135341\n  1801559140012523994839390176617521611923006320392693503074408005564853217364811681583302031705897646\n  7823292023818247676449092399715748466900662684870792697974543610502665979171872565458187225995671847\n  1895396896356398273911694540082867722083973564852019605960672645551934292523068186375946771657471639\n  8510375801026645131490589465320117025939029809267215532618811216870595841647293227196915373233155149\n  8788130347398894896254271704631085200203089349760747480969523143814485952336287596393157034764290005\n  2519090875253165740792449294631761411281605006043323678149217024471810409000252357290745094008754190\n  9448501323427737790282037687775988388910224289465863071885783632584011400402958201515727775055220497\n  6717418065229681281445359630774683991974361507755608490148304881526622616887549680346283304068496724\n  8845831448961089841116418534724679049542984233687929502850535622738086930362906434961063890273423981\n  6444371298967524622134998071790983253853751824514318229817014980471474405208206771734829307574244607\n  1778472524594618574890493050965097953905422530692123607017038379108571469830225772485251738459145607\n  9105588537047066293052686115149625701677756605098715221893119931908608040958932727146520031599118043\n  6374064955449852221163110792402530841208587432750830257360467355905024287620096058217825407072535881\n  9424274822906126115650670990690000964622866691935026133569804484990306069770879179642034494706647343\n  5831304985932397059589076521205938976976179995460990255750129252950517564633281937784817982728921626\n  8839791503902841548928484050101832934301693930859769188207609832728889211355169823445644473332530729\n  6239857923564576768444655740788184753280032062040912485037907903369696799857569854811754811838668849\n  2826248933731346365620962364360176047562884825574687983523166892032758120831192672738707762830879194\n  4164060207462803182215764029456583397476087986917525550317049629196191712150721245277331363754728630\n  4990037502459348596003211514499284066215825743674227447550106391222421889039120688571499028125033222\n  9301019625987938312748207951457466369086901110213105305738750610287625824804729782975970378866527021\n  7441124608373700727640915037133336149717400905160213542870186599060553712590929896988757268780006791\n  5869091084574078027399010187258340250270675234927908455645847233838793694839321219370566310273581109\n  6309442346293573358743954610171509748417603259483536217516712490048287878693443178634077789561343147\n  6530447271015873083591865442275335060945004542709438295952345006179508154991222606770536954034708723\n  1670377358003858882018536060774078592030910013073668615332051430948329712861083660252455592697326600\n  1032976141119174374276782789747510302954650308104060484212662927492258713195804378325583814279728206\n  1046716445453966782750663376119561547180811410663728904450860711216506603398923855553767532053879934\n  6850503492185865362156116256077378507833681394845092505697034605431168901434565623077243178045128441\n  4990211879930904828898966619644774295261486897574573204681701313930905117056129681336246565767032752\n  9978842563672610468451395578761745542614079499278851594193234557306458553637676662779045651946875235\n  9050707029026423593768921741125833571439855472717969334716699045245738576573463632340209580112235447\n  6444172330199688759484111588591938802652082412625415775923953557139009940619257885762438343967082535\n  9850867717452030647712597168716292719811087226407167316203119950574953533507855790580552280567687094\n  0035886214508419394511021296641803010250719004143518026258391841696334287108392447011217284273032774\n  7013437984117330124469137759748817280837808632835848060410924220865767728752209963240080429944929304\n  9868849898458249983713858916691314115948053797704200159706893471118315733890104746479878081565219264\n  4112417536626682168177076943238146633641948679086382584713414390786785266254202550798750059834420864\n  3353203403385407169700485895423819416463202364499218696935197625148758953644751634449406416198941671\n  1341044350148248437987463916000978580071488654135135723460466234792972728314241559208002510346789545\n  4275219424132570402630697694654016135485468798571442948680303910184410863890414481123754437128533082\n  3993732836681962313029569185695856627411377033885853664622747193167250336110407331565700765207124240\n  7975699950151716821900645117887028746352292980881877100729033972992256642113056013757759771901399412\n  3632672808453894003190961542149931926133641122555360118366273278385267401987547818763539357339492847\n  1029582528710380997565439732567129487558224783626807452739034903745390658115194195726455858788269618\n  8599474918395265496354475713650412286059311783277470431717021755542733811316446122057779146073657791\n  4630762301569877794279947080006669333908086631285203725804287139455275693441864382832163075424935767\n  4340668984292481754076245634843585997894799507358408972112726010980185913187269858204360215449353734\n  2282099832151279967547715108672556888219897690679432319918500345646597546894209085865186885415650053\n  0177043477744794386727039309525080717481143880667694404088033700276228922940394954645686946736562765\n  1215744427275561854727297092316077100833032761204644001950108825543666118384017506433079878960184957\n  2564092270264536383848782826443778467646788945218613735355436563776064766781708984505435511469123142\n  7414164836797645974961007517515958073916479931951112693660164858482939073318797391690878819561867435\n  8831373515539061314098627551521295444877104580897721910582763398947484910278339169952254377681439407\n  4186682375671244233235148234658676499645194524763308705364406871414568326066397694548019309437100867\n  9575123989119060859807956189770286170467140202639004075521169679039679720071713355977146779184571361\n  1149407966712462922999331477634216541227783574825862753499006792111978060307885749546973284196464487\n  2481549238845041687488440326562774709529606774811952785925148107028490709150186522875342941836314061\n  1237085873262940243390981983868089791860127462081893950209887488319592020920204199143110243288618404\n  3867214698447218058827477611885531433454775949915708112154724304881109826753085018792712236067265424\n  7225549511677834995137607049303136759892216457674176156088948829950931142765681879504457390726038660\n  1558121381695557713584204354934789536420233897464954927668535362013175286570550588094409771668261877\n  8503565693248837006191686881325769898892153770164294154770352800561194842247298518748777495354659986\n  4731283766810231684783864208035715066104376080275900992417626841020731910411686475234925060364563867\n  7729618049536610561814538747453647356295576007682838500265390338220423592553982932841939449420500089\n  9887248918062112870490391300294855651474954344575244822871583406545423074678494274930963470015143263\n  1241612982110976577978086462089636434720880591553642322648312645150216051965026584720667061301204933\n  8696992206072120550748469831325044567903619793751145105610994059722706102455316434184231593135390530\n  7277364315636726458013226763772668618633479296099412432700177449539823043204002544985446412582181492\n  0560149218878884850042818418295383774717036791912893763087010427207210527934076159095560569028788415\n  4359370412944870677376427126382152837911463086145996881385154958969349477753009109089564506288798749\n  4998791897733005539554996967223113032996223735743856778002884728964213358326697472583460615280371262\n  7432217243252933925759249244741154505859760314253954019027327179534824534471181832675337725688313193\n  5700208316178318579346955506250987414808507383726201448358464003533691270556211958906298935556277917\n  8399088576495624037971430883909711102642258974629317668967223404012789249994400301464679220203830421\n  6198807717346647351646810982056584456771849874997429162956952777441709563128459610269014542233395364\n  4324790898827529451163209927530749937938189831475679444124595963726257884877982459217012800557580271\n  6147579216877302876772414278390459073912739294267884385771923968052299403405334707357333451836725155\n  4265826396199993098367307950372448686461149373049576129415707070662032891811072389155275383366638170\n  8043033055670727526167741946306060870155565744523087465583961240503014805791061458163090131489886188\n  2107938274751304764124868278016019084967844218901110183925596780158884405085393976838736014191230960\n  6008688848409587590939798875457125098902772115401440192622172796546564989599214375691142902020411115\n  7924873126508075595972847278699682789162682786949115247674585192281108652677009819279435337913553500\n  5146898579382371388273535727171789383014221648571714102900699728235323288484621928112894081707974024\n  4219054436930380174929970320843401108733211145368423599993209089515669085964915227766722963969422424\n  2341883180352109911640280643484735443798320000362808190976855849256117523929774165820418448109089512\n  6836470846247411739612714881019329455867381943250861265358837368559920259078153960821287907306065333\n  5449059883474701016808696373177373258291394020149923292096927067831675968147669667520807748268071111\n  6784929358461984186261721109253221606852538815918559880627768721643818351604955385279364210903131036\n  0781624389147125433165370049295435731311918042841965032161578090425201331248560532036085914481767170\n  5497669073927648951405521520609254132916570249181716644372036661368578767332511082859038192154476652\n  8622524635921917501303428439331954912297279269763953174862232078789202684450835204124961260947859764\n  7640505134461645779957974192093941387311276724057940541046207559701574182718191565611832096658777408\n  1467691697748376641838608175254785968515246948077528179062939927065252312930894866450147904547107615\n  1553997996389545735499561642096460474745985377240519452042446951551105760149422144598507856289800520\n  0150144217236030394428342444870888738111756954845868810158847305082029360514301370104506990268158198\n  9459515045374857234879807161323689988928620499341347784459648262388689344956413068869396801624022569\n  6097259058369035914478304640969184582654758153494500776516075819566412400743361172866660578064097906\n  8506843839086550136603417156612177413653524666292403852731631584292475107182073761997425700526636287\n  3424852769709124146326043911646825719384474976527412791288332764753400458797875672197285080251587765\n  4905655892204714962052521040120166987644538174938761539621762099818669564349377520407867045502757495\n  4208283438265272799066404046308555601579354158018388708877140523005777747910133607583463708160374140\n  3358166217105237795477803108287893113898944795861169392281377248209766223153741655518707243003784468\n  3873444610185876496624830235355290685620889367050129145033747129770829859205524051878310562165213224\n  6122880034754732559325711750916176594166482394972913352370543886272408483705528170029629809058650804\n  7949546245822401357141584900673308445738818119674451429115214342793926996556225719864391960677530383\n  7468667222170355689084250348329476678415036783681989747562636076056173959495904537872887088011965418\n  7892476530782025541234215275554653752784851164219300210400696015444285500717437035400703359356505398\n  6517857070065820998041957449512358764478124861041475565904500553778745425732766313738825020172648969\n  6161291010481279326374567313473871166387709984542067027002960111722637627272674521018118655910525861\n  4533881970128991196384735029017400070680631462301308053975457760287247409909750691788261928319716472\n  1284958737918035495590854500617988132119821142982583753056350978991235940544860179024862607671948351\n  8442349058719075337294433959240918535280295720103839420962334277562087477231701175275687241012245302\n  8153879584509634857983910451921318634956903039125641139059641254019436292949491921353071715344840968\n  4207106422822898118640267635071607969350470210023187810985613567910659306600789776255319789825006631\n  5156298335443916444925805700780106162803210220195704757986565811680933242300056066489673694876242617\n  2410119907596206943468594040616410905711553454537680923271287235399907443591953983973721101334949165\n  6927142993028020314774560505446618457532305901707861564430381970179149567653940459435606066050701739\n  3893132134625850381073195038674483556019491822805167730576850268843254958908956081419950752565189355\n  4022636610084816146203865446477107121879516306983362021407461243273856073300741729085341371467646620\n  8233265300757784578012755078726278301618250870084281877453320787977894296485859758192842049964829620\n  4273540733853100546993954125461947347217039952702270357793858512968366440678898374656563613544478066\n  6838466976517661499961854398962350237176711027408909193995831451468723612871384972420690809504422367\n  8551028762868042518816358402616298518072115283322375809709057453569178401938160024396543257825045445\n  1969403488409243408578999827719151230309473805540308231556081860716158343395561728106373311060601526\n  4964148156840431946235604363017431750920771304908868560472738551730953808475014486517604975677360783\n  3154472292534335963845630215217104987385925310203978958143336638415592992550894460278070179622745210\n  5550671191316326265279936696359892383006096981600167088134430020391177191630701637780038300371126418\n  2414601498704171480566260338497751756038495491915791417929536849597062863297174522149452643640004011\n  6851275873879434866688375722889961342993866402364058944824529124282016580047816694184780636604784838\n  1761856515584017460372897821585659083148930651177919857231716476472418930431531999088154997137742072\n  1011833196861968494405184713480510376244887581817277233442721570874000852493919493398103083199952288\n  5426263085181455141049674896425768172031457741976055401166514371933763721881865065248544503999376609\n  2267777074793998014225808662149871912470138746989567658098163424079513570373348683994607400148381880\n  9109122785049874225639471028589036178924869455199904917116231709297408195172163625062371420825261190\n  7131791876380037382099894155167362903105494029053725379895773700088178658870490439209102611278111129\n  3551942277819214700743637373519008329473368732239654947632992827531835181262400711892034565885546809\n  5030263042519219879777374432637260928911109005219868755372281053055764147614824639858637189772797761\n  9373087670426497044115114128900621261138853060373672295958161170213950300741417661128483328860167367\n  1673203588047015802478486463980799957676470792331064456626033730736158992261787526742601353600729527\n  8511447312992791452450623340290963971759232197958011191466992839606609054620079823745212245036016910\n  4115632219532972695445551518284094539550786740409371853236603877962805143126766274036439823983188176\n  0597852813466394695605558118458939807050113575168206806948943855291350882854473482815176097154238595\n  2213273086132204129233077656558692790957004784303955681994015964223359594550228105654377995470862448\n  5590800370695015608019307214648972673163938925538159958617022059139730270900638588414953461627642604\n  4283738912519184781985002549826303585100634103443763340733469903127035583080112435481586611646799047\n  0409954792381287897186780109815204978806050476668203662967250936939607313669337472036724300318966620\n  4997506525201754713578657346438364676379268501958461510696765363902447489954321997231906116932962287\n  7894612265668306435189561638995745077221094512799188532444937648778904054422423347097958726521769377\n  7637079604073278970245582953869616412632465754921044812238089336380764949967196348615540609091415949\n  7678087746191227708286844605325727180192324631999466767892603035979578118279000471394092171939987407\n  6000999706958163447923360510616646007787559395457858135619117973484724275643954446900185370303889947\n  2199830805883405836720473010593371645853777333738261881997860740674509062922554889908344358447071868\n  3462839079294708011696863948511850811643813460281234771266500937086434980810611925116998390691124112\n  7884922501074046700100249875549803524056367371564404834835224610219675040334226809019609191836769753\n  9184488898103076931360368464907518519208998079674849520642528150398821992945016312244419290790582175\n  5002124641564387801147363534860323181769769925688623422436511614137835848603457291845645973101458014\n  4233910343661909121175141432240043381471464957028036817478157339925527876758136335975360559539384017\n  6867674304746201122791642138790162717829363320257354064982943159500554714114406637280225906499077297\n  2153184835396210592075094818702230994825467297018483782461121232263919435007317776200669540599603740\n  3765441062871924178666242088214648278279438113619744675884359564005433840353292127859574881400073749\n  7083250483278575562787738665283977888843093724219594555535436816532937198863634368179075180196127350\n  9345804109446551725884968026121015346697273811614985607135933184212517820869764413662803131959266299\n  8008004999380179915344918391418600149176520095550574294390306323540512913272285289533183861280090024\n  2018592068301245576885159986036670882144036179949757693010158168404896369505707194161819229869985461\n  8110664316242154343885744834338880719947667423092554142522046461326333021925412332655422517900396237\n  0011877224880121899739867454023278310111558138887625327523466564979284560911758393972476956922958164\n  7917057753460630170075274314017131409347082620758055636513836577977785668667231433899715854051283817\n  5395172886726792433519324279446404274845572204271370383384282433585631425510375691018147458356414678\n  9534508685629018486760916770619988006592305344363957172825088842599663928971247757401309355439247332\n  4079182045553817663723533222093512540132481590298902642974259278789454750065499469212124666206626082\n  1434932002080552240572239843830449363282819228454889328958740225793208207774992126360859118902964660\n  9838958881002923882049246229713322929703775199313610098035267052448685322637447804638432564630100081\n  4486291219945715644790099446084293682847965274461276533324488110332420251747386222344906972367553788\n  0339959666403072143753602331036965733231523772298744269056689617796282321898718909625100096673816079\n  9485616991125616466451101755971637994994874517358658677084047168447477084990976997944707107221646280\n  1394627545923362533618584457602386869037340402342997958662188971415880457537565078504261021206974369\n  7096921440941134689942630874378569318126994043871459489599835002482339043529602141043479871030683534\n  2977082983320775180715284808828337014599515736692340895220746753110902000408776677345208304107255415\n  9390052576034609120814028417742037713070084243715867293605934806649256089060062140073524622034669434\n  0437762973714172956577384435940054753577833647871738588319957253806398099602645405327205628731511229\n  7815716086295737468456654236008290043057653315412716898974622851338510767066427511106126351131616092\n  4243466569700709329952178094757112910514811469846816362099491211915737590934654666176085925249964296\n  4904995300849587607819636004710267394007407320843624420034614494703242395176785324245348099377528028\n  0525924048657628467141218672997407703083930742617401450032210497262071517016718491281343898195596976\n  6521920190813700036727820825480844407705488949773529007409396411521592813098524327606824759522533080\n  2824831409114550349648055883363143637880869268509840227543561095303877707012120002898032517901049232\n  5077885025908326341435485168772200998294771996023052438855804487383316035861722692030067101878742606\n  9417860407069990250750049323362692993214094658099646531428589402950507599383742467138926990433088969\n  6893171221522509329615283223140401522472006962251931218769483286742002917366443568066358210533280417\n  6726151562302124288855432501934774716280438341939284793348612220573524012877500894115331923097650828\n  1811189635502495846710684529264484555742771213474285886128655316929049767845662596418247266927783440\n  0266072794741444083706645758512376709200048312194034837292085600229027797730864854147461858811157024\n  0287314904233747102205122542105996607035383950648233459260971244250184778080977172673924731940165503\n  9607867012304739576533280658508348412526008894658467311915729174574224177949335497989190078206213086\n  1080386551622375812464835540650724329292911545092667131859296769309032438050050470579802957471634654\n  6186859666334816473756375825302952862923734367894946601088352913613146663832807119837174914550006429\n  8208172745061751153316431785068605599580414470505145134434661354349132377733690004775758504046993549\n  5286508212310688552096189971243934341116809879539624817085293385576090027022794974124179740475717835\n  8915130101948311420886832494331481780233765095332429955285944368343551972731851780494655835099194309\n  3702256819318024684488318677087309347278038059155250231204064223609470988530160758370543677837414644\n  1160534217600459326489012510109436888394937501080782355178495090823589954072647462043742888105083964\n  5588426654869276504840328312182091922525491147266406362203079345506603988385724860051085280789875092\n  2954152053685929261987791689221592205220551985320147926147108591884318686574115963789931121609989761\n  1097963356544490273435909832894786788397496610903105796567898848146337793780972063390584010251514800\n  1880401230886131297554207215369649270580145527502161467808691366074981225162163435485100633443491035\n  3420533934694524974769550862656936276212610915726891851277303763839795715936693067949298648386633844\n  5448631276085510051818945811041464708454015362914582274572901534105798816935405528318673603825088352\n  3047392021460703493319106727265127717991413837226705030042889515491348029236323928824220795773086577\n  3544300787149940796063032576958992623920596601385554180341966989324367028510494283621790242444777381\n  9256545997264421416458801833242657385618786789598523634784235368090599271199955978540144835966062156\n  3295163890730042756825400192358883203001911349752328613006510978769294553113966895558347643708070331\n  5692464770566831708735818394804538875307517147833711950768797640772884648664979182318450231538105517\n  5873407189625387985376214371724368207104688142052492393655087044891355416556266667131541921763666664\n  4546134197065884404803958628401161360336854813455050935903141657252576055258698787030511931907553636\n  3454402515452339582336587160381608528218500714103549936084662784075061236838764462145891921779142593\n  0064973124185463655995675129585020308227841032613715113519839061241596463339823900878973879933716728\n  8720356789486961278469180298840007702404614168435709646116237948458002436915344623192970276370458105\n  4668618648920064818578844704613762942820614210703480363084411167800614815023913690139665758030939659\n  0441591251209695297358127309790325832927479399692824383149206259029330928601033239174038383427457113\n  5139845774783202448838602196807671633165349867303474540139992159822111671115125442585376091673432769\n  9904005844974347590556420630769469347283565064991077767958926507983234810840182244891170749665104061\n  8759184748576972103674326815148420195697220747344822087928699608362935876316538904783900487427479351\n  5152841972707861432196582841706939049681577256828050122020751092363465517693151572323810501802258551\n  7518247822341364317881652068506613942262653446972893597805755792607832166738898066125192388000169534\n  3252262005288995610861328799507595735547495524742430832870191803056477082736701434453937593763155017\n  5093518515879850506946390523195829252309751407405254595631400743663136531859885757737887841902614118\n  6895445650421603370647862526272470854341759779500692649026951120275026309543674058016472131592679453\n  7943694975261018446608580007831271913160212350913829704258702336416046448461284709186343151986536546\n  6090267618224747180122535599681323522386679559736925806895975303712648024482045813701820343286908637\n  1659833775710858330103687434657741106218143176556339621006385831674674809188717077376535589866220294\n  9987382744425547924116346546794060365024746024561895259093499667359512271273205240111113918523027067\n  6142772309222947288101331929633399781855031829344326322064698010129517045570430063250156250431508365\n  7628326741230020495063971736784188910051425253052496886256738738477796628662164973624028836930961735\n  4373373136677583583570179447145747081249069802297768156882572257089498908991206605540252060801322450\n  4825120813756743766198679642641298605943112830005408881881233133472974731212674444311867594320910668\n  1841781026557335326213877374737553457827904151159313218518285887774417722966204691386602093496942560\n  5364506621333173259619876825885942987942670938011410541539939189608363619248741879169306463578448072\n  1565839931203794011832448020155671414285986372785984697074047554361823481587960114136623524548067203\n  4561475693978012289565852162256169671298369008539004383451036299591188765554858501038242000728257383\n  1915399075270712724127201395819955356637355128909069762510703048920279452591556500485530466782494374\n  1234171084511127271602210941931455401579997525759706235711965092077965351455828496946412471272627520\n  2638568898807683516345882147443822121862964661262708267422635057195047392386350754121166483026200971\n  2767100489826716132451910352783620701285444467011130523252269301508703063384519741892706340692454588\n  0913768037295753346806779350468647874587707376219253052874813619851138575784542929107665429283407134\n  3502250882818892915244527783987472190081314380720430207245467931758778466626656846528861507688403122\n  3212187332960724426849433913948234400487947318100156723452617702576708867907794884357597613518177223\n  3032469991166575966356154888040497320129756009526598823496022332949604235511787278552924080285877667\n  8063370228800022181033547073381937382622675719292593356370954061572778057244148311164042802001173781\n  0453773569712267028220634931269054549816718499502811568901079688029001125658917905559234547229213785\n  2872328218121250345182059548096772277660713101778603438829573318206423587236993410098106172349638246\n  8683009133256534492346840680693901747353201504440611383475519042887754060775819161781154130039925740\n  3786443591301907846113155981228743338330985378397280207272868923202989439733948198177571392474916946\n  4666678961234291093703387932512337739713880254983507066465501643565968531458265075610705724702998374\n  0904860172437641981422704314803738452936874360053639126726507615680781314200412241195949403929770163\n  4281240787208085216663064592305670320709816172252902696023063081292602279781774357161381029192980622\n  5097290234214027211916938032713298320083728506679616281592358286686576099904415991587203941836822473\n  0903669496907177457012177714467268351119457992357643789469356535420860629730104673071982276607743930\n  2309468861548281095152021597052550236156478355794196881755560913857785219222596477699410230570038366\n  7476235506978823189655698241465028678631892113122406061809386048832645173084016950142082157326064292\n  2288691115250254993602180051041932609690738474883239140241558533260115285070430660932244424825241441\n  7460744488445341855282414037622464301160849294866458299855205426715174054544202062807034332941069337\n  2726429706689108153584840149094569382462168479929707068737877406289283254513422604088371872199038355\n  5267472209412312676596338155725024484611269592746975238144932164044468989516224006928370958627380688\n  8336291637240041875958645520463746275695830507984538153471523066411007256923629349276393671091313512\n  7040305457696996684553584714559181928377124625835214124458120274966078477181056994570433605081685095\n  8945374630795183950034717251948443599494854468526812973590190690653598903356956031006447968263120457\n  3191011544496555112268417325152277386303081359758217229059766137627641766163476909125070161999553759\n  6432115575343966216882710840367511929996000886246321999875418094360053087413396269299820762966801548\n  8090523558718680761698556060434175392524049679996465176000269269165516987526525067739508513040805388\n  4450609260109643688108942026856159073899850990825015494639182209700648455366366899685892286382159711\n  0767179767897501154280872303912887886996186789307198286754991974326270934100026851032592963268818524\n  1489579124432764872180145298218574977142929436668937836438222965859111417940518494207357064528325988\n  4591225939492744455714667765151145692903139525375804633758579641581163621872276615189824122053513224\n  2248825616774245967654125403317844988384111376073500772008569727762648736527833891636142496421063088\n  3493089033208487794286440497222682861859946689343794851334855905828206964612394649757412236283139773\n  3819087455803316751727223866473603363229422165312776358477306315342973727749231497394273391681398751\n  7165017810326131745506377657709788695976757422149371635288456874197560695360039337332020651649369708\n  1492295834331163103727409098662574705051470227230962962287676893693773871239020465167295592539637570\n  4229682701372159784961803623480433790639703585582422108823529872394968853577050451828950991937634747\n  3203519382811144209254673933678229258496532200800152631802914086468882484513127730626798081559547648\n  2850417271139264031553850405835488218720632498225683083781144749672788833320028717670034369690112633\n  3771406814924856099222370955185473844571790541768739279171785165931986828875641818677687684101914918\n  0793996112890707515885455246994765082176756772116466364276819985224100965213050465083407275744849661\n  9761614608405906074102214449762236679944848377775461200772349048346804799553637492002228711271851356\n  0661682291232392180055827814185815990440624052625463677109244383173398476328514706535000797831849158\n  2401175956590053502706403840870712334125490430058925526833691094710188568063097486389407660730095765\n  9146215650501976073448899217067459599010087108436183443327787653682587723082233443454329275264503508\n  2751036885278769677924752905435163484717783060043423068025104169270984042942326154928313761218792561\n  5980554961799348822340432228376565318861257502640780451529541971941954779774061554624267671433647051\n  0868155403216644525162310712260123089371047550682508603240463908671443690773244134398492841467882847\n  1479332996215272656768340104003538027202527541843522537228344897065811560857105993366677451985660472\n  2008416019086000078805952681826691313841734181990559010582359290201354051461037292598408924440579962\n  9261209829819631751214535332103905565185435755015506330230393983217424163887658141828375495738248135\n  7953537641564860019910209763533920754849348388692816112409042860516889724156259375795831898950072924\n  5960467988554419093112332985271844623356777359933348040747037205328034706976370027157282023073057696\n  1414871966420425572750491950366323004651395418140725108930709443978312110733276687592803776507172513\n  6087557193764856367448558888257887661339184493021191882292709019500146842343636992753199546115671386\n  8570450744143216339040780299923490581446565204496233515435720105541820604402629891318181183565214801\n  3865548465039391744227689983209599473453261485153380908818440673726935784293194085081800541112501203\n  4574453033313973804469488527709899805696000519141141422794776296903922415244615981368125575139849403\n  0158908912839039690682371596762282654375590561603002045727456152794596519182500713348715654510175277\n  2344850870016671622088134714559577331251876805648529105407392802221120032862781056402439800380701905\n  6977396529787790988003162006689840372155196243342979928100956086160201491088191150979379290036944991\n  2062176537748237195532458063615013009808650442425293478356985149428846338401965086282619268181813314\n  5352271022161786885639796180425572709401969041952782218972371157604600163990908887257182510468842834\n  6189131812029696413348931760054804610495092798975176311147402264219675764519848872453240032533025182\n  4830774912325256688475616954239348897784619157579442277085582057854100616348798261398555091924933763\n  4419693864702415434328232827684568414269943837235402540939373073804634343828207196553140326715847016\n  9414833139149967410908125309984316312073108505016906329319101821105395585567039824196291695207657199\n  9272307176373081364238940148232626547055090384196166395745836874762673525255811990719183623735843687\n  1834305909221799544996922233003428708226933056544676836776755877960837571832810682555956854316804574\n  7689684479201244439748747005737572457408749217827564247332585933827183601185506372711682381424624589\n  0459076029692142808180577856018865526909992792215471270895924017947650784451441464551717272454847694\n  1607662478326065735413894461988583756749847678053698392957632660226472399204136521623736361466640323\n  1551854151548111858108443398551504367348070980163062524751019715046695459749141410113086616816368604\n  2103388074565199493245861160487111648627998380248125394189901363772731113383426677853259232453334485\n  3759664716208338537412263555308937443901951541575679942453238033408307216841994789968124268884616597\n  0608333973371771443649867987671879725126150631972885540631915126103864962031374005154413457210449044\n  6705194515692273936673249768573916031054311481689222515925766878095346204881819135120128416258147210\n  2780965979991944160344384182326231448081673218912379946597469447371994734475461447290698588542010162\n  5230641968059723722842337324511406540283755263039707842698045973210194934570025250559594698145422107\n  0283690676511133800827197043045192478092511785627291035262791697425806840262730758419021462844091789\n  8442561629867390910053700297885506985823190928855440993457717507878492547917137854322631465566615358\n  7021169160431720984265232313966065488930853830196834019241368671420697276336719758147787236143301726\n  1255520558300247566655717115576955972073111366164764921241000743253672111718190269864734965813010136\n  7113732229307682146982330958626017552721672584247759443215834483251667717953813744964440656738138326\n  6457517449057480046505684021118589827064600254984222932072749822069747698062260826601109618485569352\n  1180662292994038015726101038428296088987460656304679850229299020929193246177160616038480142250886912\n  3734248586441731267184746634512149080855321275811894748251785940175844722914259381996647903390875103\n  6666615416468654700720220225459753480984235013648485749478855474592133750963767821654279141354746700\n  6281276744222299118827998135726907378546909110155681042971730577884247638537402679741523709462463943\n  4605121639245148210507976032685986609400873234156423535667666375312276348010107704548905103240579565\n  9667413083115792797480966954347260724741069201533920909334582777447339616500935752471124170750635032\n  0886771741219349514666763871263737284611604087706301583760011153364921219020331806850032466637922173\n  7979268046636376195583620471957455881725511200080419911461363395552011300394239159753566741136702232\n  5519019341764557314694822022252295483332977455605137307742517709774446598076075945466065931031273487\n  1555326438908338370277382207431456894458643717541210660493377454249047001490395946574594377123789728\n  0058429396210552675039566321492376729814066350061202360793595072500261188229881702440932306066540097\n  2298243353765243779941591851493390417225014699742533537805043621410935772354900881869073902695140166\n  9721483626167233238511176389727375572281168991998039957293746032217281928453409332584411696304062383\n  0035426887429021182429856451245795207347984627346195104552425613736299433014983937291110870529969519\n  1835336505348442428480463104765220834208593651730965844961302858336548195435981867562202941613843211\n  6325768598256296720182890678112418686878459731338714041872970071191986770129310629309694989935481392\n  1875928804839845138740758643027656157147335183544073506255312343664960053109148813032384462652043513\n  6290262659333068120511588851043585699456499388695707061119235727571102941969289941876554368842569280\n  6386143513031063844433431339619697973356152324266641706639024036236559357494425103835682493854306636\n  9565628381349757831909024277049909445141111241230206043422328892597491438231575907984423517784541128\n  7242594935333309857109787553868398175482521217518103082181765051555634524299484539045775626744657855\n  1759148916225117807053288117045974059759864583008005610322332538430075098113431012045083319042286546\n  8587799440122965616563890815959223940343922260010197221765736217116359902575752900033866022749259421\n  9355961294755185136993932496927866350652388267689411676389089823146190959683386123118586714957572705\n  7568639974542711303659181838471780818084175201006556621304763267524946682059974639368806499907641342\n  5808930820409023632383517830632217617206433632011040344099409158405146878326260477568040712615484260\n  3468338802680940447930891937342390363864402549244811573907631680266467996790175567187064136332402887\n  0508745716587139591642925361440259784029087134377444175895665581130737629688934752717371131377900031\n  0082729387122487986914124280084502725122546352721992018762423508027844796784337023680736143992859048\n  1111125419311013509593127276611248889546891945355636218793299748845867834814486269804703990091628952\n  8836891137461673156170241004515775700160377837033957253926135405325011465741922480121824316985303536\n  3945988575041132622240054109705194916292574379281916876204926756847774860345138396946799094353055861\n  5004279444831120630905934432470009375367100560449265560347274778079078363950451876244839269798731353\n  5284348463888133230439792774802201529619235548600047342730950786780625307673643332282419613242705655\n  7794522660656950161892625626948238005695033649150471162428579689682908969058363758278283892895520363\n  2239309604204622878106376581117827427625323405055645853432873936828810555823020155443402566605611991\n  6083312452763767493832195233495631786258422134166574826288774471793387032908362503995945159111325505\n  0506004055193310678540221401392893077471031783341055948291837130769245697952206414022795846705868857\n  7578468725289470075085185004530687570783974666384507360195357370737853567003625855820667372433386238\n  3506635732352725502987473715710495782761939356350167592836742308538385735127612882617320094878087312\n  9781099401372087532187962176750723431042040983005430754543089347560999967053006260089395875398030047\n  8168171271950939341910683317924294515954385112109091722673218321181622795705954478225361268295095486\n  2217231236316650725721863453174107239765038264726120658627233900281950908857409600576878745913537314\n  6151589768102894467346086010997367803156129155718923796941378351231627407516945694908680544178759792\n  0036554692634446181773732271670034442667760460949248120587970646584973528807924153156393243441257891\n  7793572590178637582569380634250443054588279581374107560228758444781096542765176706222370697241979180\n  2152291454833956256228460783866292668106052637667735843824873378258642885012123329247207096075960682\n  7560580289356980680090424779414480522461408019298274453591426130067315399742203980804453750119539726\n  1944848449519911402819066003262802697095448716577923187991552650311232355363968668453024301596197349\n  2262352274323053604223375606417777316238560718050405591823508941421612604389373200349753263396931768\n  3963974083408761489660534676500201801809501790152475738159051446684042332046251958596479602895315590\n  7754720418751680422104882739795248273749674258822122908418426732735405062974739562518609784580701322\n  7661151733251592801250066103078456552279339066119554676984670693114454341653858729999117725534075836\n  2673072059819231864158196833440775617358760115854106288590251485970663025662727818819343204435440594\n  2641747287444638497088753892436548269542567705195500503048573967192593691831322499523829039519078750\n  0747741928834128339315143605456554992740034000514752860117649136881975405835181301064281918542772397\n  9888911556544206132952148340397465595374693176797126059326227357889369439528140371554981256229183602\n  8970988448351999590927247614292738476113427394270764659658609967512305032437609252837453544759855871\n  9279745135456040928446312383889192976387224509486946643316458586117087884072595663446488772838981448\n  0697593346348920920847479336641147691694830437595998302984485104669711676118031575670430748683191350\n  1510866268148110806626764448818763734119104630148643395133316943864867191253051197712222605129272066\n  2888283651460221944708196954631978248180623064295919343803191070756728911303416669390683766514373340\n  0982917691778335023511377237807008013449375124805050073219738123851625063208104966695365173928688581\n  3977490771907824529794195616886972231675210450667137919208653893674998631486641017004445762995894532\n  1955986639580917941851056008686137283520554464203327542845960428433290425439861323590988961610491104\n  0370538129550774681638755768131629919025081570271907649077578436021697722790417283215248311154673779\n  8675348633009709840718852917729363837896867045449380220171574243059909227766330242974417045007458994\n  4751500765742782902593896377634935315947832002254243267251842300506882020825497212921405633725581581\n  1271047415701853893178293987877127982748865671504632246643855553484887868766413556127610485824205891\n  8651972343533639572360994808168173974031190309304510004396180691234477085551492472966785089521986109\n  0165524898357700496192037386165583736313265234598245319951059160583790003979969517770697952469522983\n  6760743149900854856414332722003498903384042853124211234021004981624291858924222434957536080826030676\n  2401546957880647296192668452751116009590537854831636712454848677882017252054639855865003582350020215\n  0851642366350078776071519856145256264951591055507477278537981540632716819511175410228892983782225453\n  3675665190251216823016918198394259899975941176958752150927946376619633608719250944468590221362185710\n  4072204996638635871299053055527028410467726202127446674545215457723708236444533570645225149756787051\n  7194800500802567824607818185487583892258881641762049036112904312816748320766934852285776067934846458\n  6576690952066100878790643016816753391621152056810844678941591233741463682113883375773261402746246664\n  5150989210440638180830560804013701008907417193766295844421691227908932831982677233321279200768091661\n  0268387238432454420686797560394826736582067345155042676308818158558039319161732754429557643651620151\n  6644668557593725940971151878369217329993841578827660226709252914746182341866367219311226984236086854\n  5204188312801997803348787565882710587023709613027479913234822581376961217046227422496101673375478801\n  0634085514866228699569152716263350178980339827364487742823153814829001343256788832287607165110115958\n  7187145010578347629752887433927458182768600045277571772478802098965643852942388173879991874712975874\n  1165413323915565108908775257686286616807192109034326503014635427492044749312465201473231975770361204\n  5011747939862821525354972026717908950519508590979562153891218056487899678573068849963903277813229401\n  5207305052020960765468832525175264101355065145029802134353365875559161683674942894412148048659982256\n  1119879720866930212849950166479523817064956427351552584684628920014188138574351067080680393400649398\n  0278204084501559743111297779680235822043997189182740819520245230161759947970828058600328892886741062\n  4713286909469466843904201205774106699462157238511091569237592785586844939773606880019229349147175801\n  6316525474727285404111782500315404941649532114745075496654802310185518447420493368214986786738789249\n  5751470690246623904739663020066157810935792046362771350394697843435917414264377803119021954752269208\n  9547968878254856457071355666985023275461239882302786890131757321917167849301636501389552913159011742\n  2489607374946020294851279855924507737935690813338697470374157396558258857374134903582781434074625542\n  3551643968904607795838664996649445074756579699351493513597320013303372081166289167650986948072944032\n  9917612907230111404658911382427272632968517609428418793980260523956540664593300789657415766970867192\n  0929452539315527437352828004823457509144853354240491820583021173669376049738422721591348355204042576\n  1699280642854714019368556141102765828085704034232587586569465009202308498308267843272774869277955040\n  6611100435976476867865384955027225588542249861365736317396148099893608474097176495471543340623707326\n  5869752764592133742971412420705112256449499079144192444832839379138042063623800297002820623931807561\n  9226485397394933083251970873138458119857017100249136525227198684083184047846936429025111292751766993\n  9886203438789175172675722174421453857611002834874321905243332939928094883906152940641101879375394113\n  4303171916852635531673529853639867761635066119682247234864034096810385850460672960147613107402400742\n  6534024368037921068446153419708080881220768071106438905886342157852825822877436754701408310031138429\n  8534935282493585040362345923926688311448077546710591069406547237346587789419248732364370240202401751\n  7597046829540255079677309844431798635413464595390227657432035188431115597546352330452355055292850636\n  3115240811767846454714132798134065927467320835452822766343059530547343093817503778723176464890964910\n  4425587969404117052776629702325695246367177584587882202846053053054661817220965509818396754440119356\n  7027827210833556064466575228098058628703330757873821082112921021038961652312284879203280376653872019\n  5820518561825014424096283660984633225284110157417361488234146028737749849149845904629889032849256083\n  9573991405910241206845576248034590472359536883927461900635300602528684434546600578574568725002887974\n  0781269950143596964947641493185049625552169444528557452948072324330277365557456104296608835697425307\n  3611130310823800031585387362868849210917491803390548285054627864100013169471998948894209530864465026\n  7961007150484392620633117118608612081871573273455137001418676869219670488590103624233151677601727174\n  2233050495306158524791962889675944421346235651931221942844071430978955055985886244201736282607350511\n  6384635711187846834715883490623342588343614274793829548341263417416882602888735547816653238321540768\n  3590968120548845481718926920620367096536056408987592845081574274786219413671699432294586933049535372\n  2967997800487191020347824739491797171976726253884952817305136008922705243085564874504121603355151493\n  1039641863808926595190343501979503662299371070610980328347286934541513596718150629766374430994932369\n  5704953495914193527271514187376586945122363671079380115242166244941198004465572125975358046399910239\n  3279770838718475347998543603066177468548167430253509114142253635633838835435446860011086384802147927\n  6315847935107106227221232890003040085551034607680665195521686567189181334850680693770039068701376254\n  0552466849767101445993496184224689804170186023510196499013377865083234368694437821639202188508599658\n  1311126588948291773489736110174739245996397882377084643593256464055446635456450627816507891000060357\n  8958471411788114001470455657924684793389859044356095193955983048411907085968390826969646301033129195\n  4054835663347075482559716224095724560789952275137431729204329442145717570211196649273295045892435115\n  4224989284182930968016279099901439100065160664654765723303846462439511383067770124161991030939928940\n  3981160616742076033829175930656604400871622422948641209276800548402635460460212864312968617604867685\n  4587332459049044581544689760012917675937178287781574634474974431747224571417824959332658959901232631\n  6543180978557825775355049571779819902461257772849446353525217033433931343645138304258981514773623679\n  1994181688328599187157217228765199470314248248787596411631008191276660288566473109611646667671189367\n  6347212909630086923962342070886293386312556128734065346790974199382881663850602787328004850544918201\n  9933787113082949339025444084544528311079067175578158009386753600386035576806398106423575109973318402\n  8068507709966620139938302157057490439491154383090561583001130141099139583290325869583767619707448919\n  1132631216409818434725600876621115969513338904625890504021039716887529763411565301637614017241741275\n  4156775733851563340968924430140617974975371744256647349345457924696799301102619433763644866753756108\n  7691613043613748330479441225952612415148981699807681018481895780038325763387804353118569719951740840\n  4042921573207178938770895931557022742728265816149740801332063433840086890238893918333142004515961400\n  8986112156292436416947254313561701811792005595928543918333436945191945143171541350074200639050607167\n  6581905824216202897696844090552454470012818868581435495454205566898387862448320752121741094873647410\n  9157860409910258555863940130915517560027976586538407568236397358347233648255335205247722960881930540\n  8210532813113048809262550440623955759039194431714152652754080895298657263071634073224395037998714881\n  5126244606312813852410741435979408576657852516943899274655621805886920662325044937029212885127459270\n  2137674834292777741271892215540626833008286009017921875382948629150162454072477788669988900709805056\n  9250698581837390135076394365418723293031183658168633364477932900707857451061139914809110997127929438\n  4939136701584241896910938623802725764521667814022361322904680977248778268641881228779934329767071638\n  7056951199018963230924589999021797571313451742593603251369020883958608546750477732292906284648172031\n  9507281491180095950512581344757157055467848443623776914819179984052906677154792911742669334885856708\n  8139473448486214381111595475449852804057422506951464720084246244722993215792264672178814520648208302\n  7693611921738523678567409627910852342295609063266671048028819226371390907376844480931844498969929310\n  6036870095308727241026213678870697269856973400228036350475523688004955869735903902069193128307071061\n  7913556767421587725759822191294318645745477205132894587827375775210307119425545175288583633445935800\n  5524008931209918825706554866392314480862374414595305590030658095292440426176752542067710335536849552\n  4654643577010178979641631303867495239610828903257724489918622996519842327827499595893408310312932676\n  6102724108073795462818807634269861761703310093468008306518347713287054254996232603250116192827302129\n  9349341397996342615126485063473483275913631786824728944493214660618479650573040671874828415191474168\n  4169089722956160670072819776610831141061869274357335535646272541437940981346383228624336413347897889\n  0912641531873040605317247738103537082669410654440622661293766233632590613838197631940130398985582094\n  8209539186024819909896648627135664987570149795340067644785868204910762709697757054915087961976919441\n  3901594125683267942639579018278254556896996803223178158977822565761387167701321480211552727673111734\n  1653118922038451473699023164776475938806016075537483382328545825950629102393600165447353942982876682\n  0737121927529990736974408113423720201314234045052593169727755905856570031320224654790866575834512665\n  4568263055461931475471873912792397211846921778376200632624668145632249687765602801045500696828152865\n  7542598234834009264710128328430643025697652644694135027062145831911049179319414349301770348702633346\n  0168710291836083741253275877631540223039562887768447232803021429872949464749395031464918041335142023\n  9388152487593737159283832660035406428953541698506199223530382921861048691825526902557498893197784720\n  6199198050179722622476371814459796413713846207982090839588211870480155631852081343051685237415842174\n  7814580115630583117678770897709425691536078780911362843548240228283945658041952201303119772279659598\n  3884093635835590118574270448266505634384216253604983408543890402854304926899306613530295624400202826\n  7343672871926207940297350617969254101291753762660825396822180621641812462173118967334743094220887670\n  6063054671699631418215590292435137843643506322620931206801431691638497810122710715021679247205626346\n  8706739088756753944244827083825087882653565581974416635778492417631881483621644122223236354993894299\n  0784092165099611235325120110314233835506549388909275961105369398083023861037130475667626055583092784\n  9435785197856390534743267450560490940770859188651065545300819826445252817408774654789916151163487539\n  3067419302334275836504964156863538834492970269883021283850750117307225319474121886030606608665654771\n  4244902618109150955830742760829485811035201107033030587092579512353389221572474247856716767883589737\n  6761772117513058693433553676490367437388170444054369873859392664944715350381525963250553002049067646\n  2445852260521393121962997057825503270457798044858956070209902153446695370684284521782144523866710469\n  4081075061673174785697189794278788716052834504290221224398343390694767646413145818070481842165818603\n  6693764098943364938142679991971798152335108415706476165027604538632999522443033893844869869487964925\n  4150996947664654689769216486142392356827531850965408813353323603150184543091811589795300960882380182\n  2954836466507308346158753739094675311255426108040965927527145627225527350121765782432201282217368454\n  0188340911256369605867417354418830302910422954093121391632516652716281214020039348524629267702533556\n  7801321211000746875104927292150677332824634054330514641101694580152392810648716511937484962847145205\n  9228602216430922707329113148505514626087654910369689708578112513994774893832884265980561212183161153\n  0304191551869772206964070517065583074542955680205586064791985611372083202139733715897180100934195299\n  2408631804186229969441590014844534898620679645053077361183991361144007305930420574967863953731729127\n  7835848215629148003084298917636403425821977585909988615422915064881854893919464924424427073460653662\n  8241104380687463464244524892172700800269889684009770499068790618994349059987912329939316865429778734\n  0536374108604116821223280321443018450796681914202371152463948220177093142729884554336272986473983606\n  7619735520646544148606206582731163150571772420887655624872226829266602037148511214624414964999515202\n  9735696346895793491184861387323567372723628672295693070222728261893624209144683434264680026607719950\n  2216509365191242991298909496734886916099755708415385632669799928723106696812003873504357001390292512\n  4556125259003322197307426285577090519268291420781601592068468518949602680324164502321797845493500368\n  6853112007439987867535318804473478513954317739606005536111440635364216181260212638657309469059325590\n  6397219492038056287678828743091909615406869152123189362789249870124538829074308381607486273896787745\n  3782363709467889116034175404550891697540592273940492666239120406468558191112089876130221444569725686\n  2545295013041121719980910669115415746874858495998661990839837817126331068153364133204083616858950592\n  5150168276847524016347344155357829189499213859109112248318187172194868838657130404829477742444060109\n  9690156383523782761290959674815107225829181329982874270549873596774842208562067520671599421809118851\n  0214643881536079623454150921340343006129978686825796029384976591871270680515270714186196057390318885\n  1282433872683766410207671757126610927458223352290512994852828161359254699066916018502759401681624498\n  2303860880138242498830699639176230939613485459945178006710782255193242050873901267954978440156989887\n  5079123165277472128947915317312845796906128837001975189510916690850679856760516587307479984144568492\n  4921279790288124241008840884778373159193613204548263035674749277565413855998730321590540762951436378\n  8522298669818514967083486052744652644981763753211029230625903686358567994891492488089604126511073389\n  0966344359338441249583269826824276010209896594546047736523987118017518651367339339449442676775423211\n  9108230942372896868022034743959324862376943741086660282017476556319495108722588920221524980324583927\n  1724279586677378380658016613729297771184466502501152581240730709630180406940749655684993087263042183\n  0015704120137922456787319402582131094546109369974922261858374651973232203681278216797854825403853579\n  9586852096711956323580355674470587232686279282060364871793666055944117539018089837790280843442247968\n  7088565952716127883634043276080005804509481613762417573420339477986303223673828425719406058354743783\n  8904464154065790999931856081243084635339679917228812637887991600338337885884554719823167938893362837\n  7732064114661702595420850885180512900843163071504331075395455419907964650902316442883447406871971893\n  5466735649456812354304961298884537609297708931994214630482207660235398243215761625487612842541210616\n  1133133648822454132448975453566265349142408224913402066175007211269430612496634133218785546802945912\n  4917217464103818671362151457164950732198489695727687268836431105360442715715428913668157127442833213\n  3397633430005081273956718748263504621039314324319975491958090961365625700243201665807095188730589919\n  7870679368295244048534202386527588450776292787146342219301500563804572513175940122856113554368542010\n  8182371586901339410613178329297920410991327454105471307174533004723383956546187163445703401855604718\n  1381578089815947036849425786821926363634477428221860596424745794721701500258173333022732047386573215\n  3469489387723270055569460064750620414873316115686228526907416880934990174691276069271989385055648400\n  2433703265597529368602387426960159164509565088854902089848498876250095069667635938123169779034511780\n  5540667349228798064769733991389207356808640524705632218673824785071644611430980954948809247373180071\n  9660589269647674380197026822410328865611136584927486696312680737684133674344484354915694758172853359\n  4401006332275230578399387530325507216780079595410679816105128701235325189048159356172170323986252992\n  3914117857155601316674495414313623225134309093811713897244019512308210327892658362850240295904940492\n  9415327768642359797838724580593951390567955604890224296007343177928261847519339555645937150468756199\n  7579743169015357214406687580868655452485004827357130853173124413579232099358194008478035530266617899\n  9034001645004709491013833401772294629926564233454788104605647714030170786181447811161624796255323924\n  4068009690117909228513527314795503645016130130038280678845335633911351731410242678439770712448559939\n  2643077445632719090320883935185236603305236997613131733483452682577284960574391671553951585295633300\n  8194184226563499761732066839099307221655802854054586971189012219660240669460829422781432154324365761\n  0175020591296018436712618332914534588474962392709765816939404028638746776848598592213820703486498305\n  2250484391685775345481955113749471895212461814152399021533658511335253541411165644033399101481716030\n  5596064373428680323910031407094111326232632399839699537619227136973500148398583884971448168151714974\n  5907959017744927744511130627284201316358437641792093329243167440055461231142916162639760706635603860\n  0656083714043830300413434746398954845945112697033377583290553364122253592752497345534833372325862570\n  9633843342035966408972856443178958761351810094275452037400888010727884818895951672312621189125001920\n  8737338613365013734348864042522520017704620726688200704465618473896823556471471078268263004521490432\n  4105536355452559184213541968651137397886663097500814256431984740377591458789590609845742607885786320\n  2314402576460524637248392024315470427111900318904204033381700098642286434180747777779834425559893089\n  2290697457018720204681829416752491348559960619800989484474891662876041980060259700127365693936297540\n  9320859454667562340804615013545821550863207226603893401376730576253406555169815277785599299882419464\n  2665167687761191736222702092278336052507704807075907180343633570756382836596813995390760727068181365\n  6575919866837510546115218083781191964755409670958249560178282456727368563121850209804703624641761986\n  8271774847822246349032781088546314151737181432979288325624993711562971573739011583631087044860251030\n  0496946914258386937065120377046630824216489443358000596868730214852492879538242286100073642036496791\n  4869424254773064472810425508729193419606670525645064096087900244040642473114135660990065146788809327\n  9138493846480654610178905627645635564452678797317660085645985904575945045293632732291403406240934385\n  1631402526002102085325002803141809837523389639583076237367334254811893427718926930339828412036495177\n  1760100346751920815833829363212820663131089145602014822523045528829442917400514389131182798098198484\n  3229029838696282514873944582039109406532801887540772094907478611791577001719038791280637623661744014\n  4045207022924523204540576280696579308502039812183784020672025012026675295531308349435347193634177273\n  4063602625796031365119785548566937284640420468489277157780434586776100852896073693144133464873773525\n  0159245211976597545908769502060561757819359107740362583576536008089376532813708436943902272298653222\n  1828843740013882581116297155345756740321498609755428688657987436900949705097986093770278357223388331\n  4539804939892101714335826189674003122527997303364571061607284968264026682347704558301545855748271713\n  7243584709948613726587130254940244957385588996605353709033892511454055581245692941378882716519900043\n  7610796725728059987482047989567855938858499483469651949308978149972776347330585707179027093568227576\n  3063930497022966339552876337991307858593142078113351114320121026019873042167062601435758411797707904\n  5808380884980881666261853588355924200630530246434628992308203070806494107304156759771007752398558686\n  7594573174476709455684268903853112849498801814477456650509614898991517629924164287800047413850804520\n  3295305391840976899463199695591278676949319592733662054309181205566924621527407866514323526592070708\n  6787955864168604527753575020748767143337706011912940315857431076777779521359026130808289832488394832\n  0949988456830767241759299430340209439932270827548357388507419917136940049879858619423446279608414447\n  3566520379282953170163351181530293127230254356291055458639577778022116588666112693357407294436145574\n  9056372007128254481135578340290160485176052432969813550274714705263542935264813662388695848981951679\n  0476124747446800847725887139455273671088784750842568825983963683066764766451330823429953840637149396\n  5512602596412691663955329422216277976078749552917485688421824863746324747783244929832354402571567607\n  9286742595284943389896764343657548230757547840335036965376873654980223987801192035440491288268359419\n  5397184364725540905314210556663207320463884838276837926105500380573953794021513641366249674935373241\n  0440434862382336249204953544285790530654527726507220346592904432022017163242358313783512521095764152\n  7412446577626167543609470974335640076904143622180682993551510913855657373411948903218456220443877152\n  7004821101276120814078245264988636103832650848085252951495226355426460671844543042653382666861006655\n  7716951714429565559054236819339387175320386411552242884740879638726559965035453160178728429959062489\n  7569431465725329799565644275381025956667255876113030863545950868484208170230903776010731371062342933\n  7807454750823785605494798769021390566558589286009199045602603206378272907615539703831101800844901121\n  4811927779674839102728820575597820535088346150021903483765764631105684014250421063783316509790934725\n  9499426617045207232691017186806893159895008062399758694838970524161223017172894039046699849427213392\n  9568126161004650902845621267573941439279503195865023504811047168563578354042648572127540263881287194\n  6209203813254648116170313586767106436587660551655133113317022718232156877362195848216856465284606970\n  6619054395401406510630973336513811963331659490303921642708535422804979802671491189563642517489134412\n  1426361554780892145283670822169402598711263211438852993916963048048178929629882011238074901305294249\n  2948016114353302390080670657213781679719856861302903012993994451249846901001989193605982791697305147\n  5943464960288332896966081505634505660937812923613349058578055094564210353090736019584463712165073198\n  2015642422013268456687741832331024731921868515643412032717030573066078517538509706917170791725285511\n  7436278713016009522089202424050305756402153727369592667997478107072793723912355777093468284756010763\n  0127913119953917628186159430382077839824326173196631333620637934967687508952402364246923190454167386\n  2358360482837439278866547759485902892040201939593770656732119490991043352855179871403502030760557820\n  1914838828809464964820842417669924567583122624780703905576531412632602429224362037195329185547180915\n  9644318568520578823501030910761280604457044251479975896088802812599786238774354965990492967322084497\n  2443458243503689780365184909951214229401566917453416838309035284779643067608611599763678720495505795\n  6365166938345210212057124671890236358379083391190802068995968969901881223218552528693485736518886301\n  6045294102817973608068954952403606648894468348535737117060799430547192164875943131412697595251661025\n  2290957537550950933718544900072907676126346765291664645580371533060205534741620555668380872331011456\n  7060821971360199116696011772653512414405109362036010017584053344689875653490024475801849902851129056\n  0362815437279676288312381657743751766245640457837049648569090428184674143410766075498411465742153343\n  7962825237739351775877039942552131816901739901861642141354392779733470876597369481710103318186376892\n  7283763660230192059197929591791482244163940318041477900282857125177644841059315644675363309241579702\n  1262648130428083893377067239822865434173173648142456296618079313695325091128754694980155031799451669\n  1228413844646308741027987820955877346176667793320063616141299836112387852698449676224949460162224198\n  4818828441759725089650432388388267762115386944907223140800386409667479556596033658655008345015746681\n  0037154981215455917708285526905878274626801895484098548064776732259308336464326667895198132303438478\n  0554257118933244880337102766080664261976800040145768192614123421421090837882603488039871589674691868\n  1275950354190406896727813951321988421183256109487473527648664367133593683737190716713615344289207252\n  7305707780561606591615442358910784646554736956343970737221781859123010944369231395220301011367407345\n  7059526133029367437932120406159970890681203507862354127805416826582353742593856966435762710973540865\n  2303333957492497719953466625694281212119266748886652563151697066072400219396266842825154475614963579\n  3336584523772409968735795322759190097974155172133484533357868142287399385190209367827402155999142045\n  6446438381600099906505371881484938160865503572270641774386629751678966655499987889572179026230908454\n  4806465185693092556964531722410894516454267967618197288329584139351338445960416728545739914150804959\n  4466135343984501427618054220965984867109944082508151323925213606951062673373679223322142599523022293\n  6409047664596154505594842048813114413172046469267049759749059935116920439027605157446677396870803247\n  8040634377784167250219888494354098282116000727729150507598693656847220169410461894445826185511600415\n  4945106281588724851403451900555634666152447374960766113577874837400388629388488610195028128078179274\n  5034958405752928452983890915764913247310105633314781346402650462629156753779092137247828970031963259\n  6891251330215246561205435837622686092820307774168700459043526358174946367245517897849317506753904640\n  4160336384724054649807500393002457661071466060571949510914024823273526691221496016070897220722054628\n  8100387307622968906215262971114289273463392143785758381679957096512975121288247076229375657213489062\n  3618601418995950002939343301174633003329729078340263825278379605300004735592754684871892997206561365\n  3375153747792196249551796922008557314794457428822592422876777321288598065370465402461993872964993594\n  3563230213110848242495018006757189398611897262182430778317833445857036118160941397634465162725658288\n  6168782130134255890738184057342227527909440150796335069630683158584259597583441339316667997304805147\n  1042051621356217540904877733022739698065649590094569569853658432083562061593452925424189291617305222\n  0979352465712270664005413539212620953741607025988131267956667461709323717405236296319608936529844425\n  0743022804976641640382829257137163603061762596724995717615369585248664493172010960853457234236254503\n  8544414412716384767262833330818958559364760061635249859063288744503255113776818130533466466995015477\n  4932420985686593504901062114129914177309980459978865399855599720886527297388216508774800198668603163\n  0561230114449331935784076334183313859772732345270212652657729626488462044050323775092702644091599212\n  6524862677165996591324571541392540015381169966140144979220598528654631198814587419187337551855095811\n  8710196924176642924238937549451631594772453110198414508008761556264407882172093511259342618446830352\n  1073794000418382893605854407065172644916885787285452650728104911722412941522346848448989734965331556\n  9393268554021166559449075153103970832462344595701968564326756803854451935868733514968195976960082012\n  5379900840010546335233641891279605446876357037106514135683715512448361849192509499414144624632178459\n  6766719116487767444895994644315839584871818846627420278441899928803275124496669648679345894132986023\n  3034829288762606371364458073713401017269924003140999628987593282399732487871382265254741903488221774\n  9819545570796378004278014587919441189077071435801103026624542936251505434616515198607934238562390664\n  5515459086899700987275783385647691033468638899428963619169533138310635144431946929978952150427343027\n  4505489128224046567516837384091737414843731819711882264119670295140010484497368688360489262885407453\n  7124601578468879477813170839202770185008395994013507875106453561461548450353467874901534027514090183\n  4645675419760454833086921693902489806750922992294071550692377787826669912301589909380813372850555299\n  0599347167842350786739058036553895201811147715527516138372665668705503251456831582959065357006080657\n  2699022721433791492375242219582555155273904766415152423084130932793556194050053244414539506109491632\n  7038715303701528100887540809332947909865917839654089741191987143734113651271643824052441584288769757\n  1497711414714279508295887029927924683321337051526756439423113502628776890344646636321844459217157587\n  9241131996329875413120183252226786967899641329341131763665388968320511916362239963736400650624218691\n  9822306441981351532197319859101563625698621817485470888837822021617101491243249216532386557690852747\n  2547859682981249480686066444493519183037483665508175542257335268514038987865030070402899334381972301\n  9614734086482834761260730198222686144117989843675583891590084699913140541383193918165643088434978829\n  9151717429748649096383896734306517121736027545375783431135217215018269592914932278747374257245721360\n  2566263841389526262793021300099661963003232522013138218844822215385253127676763048551870068314684039\n  9268185487653840563848319210024722319166100913439507678555138370482142849151016989753390789756323399\n  2177890388047633681374846516892263571623071840641566324924108669239676012160108144560923213374291457\n  8448806124786377388264102086180249513057338836941585087823197098151586711709517388028679580151067880\n  4493390248068909905291953284466968288254552920787080905016614853675330813369070048013388285854616540\n  6413320250693835596317424365884064726157576009934784114084062998236648235748554353359050536126274282\n  0018784805295304476986322636627829632741637011531118234081786739876610728127325778513921138076815418\n  9444041763294630490061864780759891264283257299873528716127741833680517563794195244023212888549117741\n  5065311168183622698953190049592292508376260805003317433385637848674958223105863188940739807614496920\n  1791751393353298858853433644997913001657128680999951557636883579690344998472342604194318599122046582\n  7495644137636777021611431270014347716120164648321329271182571328791058413578619311893745953236310239\n  1270889013912909166527192377458686417036480120329532875161201291706095927090777356167401939117441244\n  7124601417849679728249366145899072550082434997089096809636416891569620898451925626719343047171456304\n  4323998155688693543372623026149800352837166513591216931783823097964852220628541884734869393594384325\n  2998753765119249233509919666893106839343099291774291126087972830433166387584023702201121723945611447\n  3365412763340270584541778577485248631649999170485476948432053120929273998661075263131976433765380295\n  2214163742360237221850677911388725805767775543742535744238997963358197140322779356139744707119461141\n  6517615151238823627905648863589472686057334479728309257094391377951656305853890416816898769258083650\n  6882500936119261078911242709881222693468531985170663717420468096376655728936417132493864433405288735\n  2790255086899509376151204649845093084820946460641779407759272735187506149345281817675171084502365204\n  4236776815132674319325109519200587674918493027769559654098122539635771169467112606023606943945721364\n  8076464990166378437484109735730098749733872155726959760331137128831583803062490323833048619521149826\n  2358667333635943608153309620435231806990586725316679671989775739671985056332039162769296127845043250\n  9302784936557570466366500504235380700021043379054365452676915632116230708153866793287528039918102228\n  7966754927414138146006565485087779489944785505088949148052882658768844456627293908196144006839830805\n  2403725695064114389933181166377016307519304450021566160912397787650073874339861213776763163799499160\n  3580029425394150936118287792564890199706361151183343773228780513781700685461893977078002754504705746\n  5744096115186501688721678158080161854864108089863222334099124749225808111853269987957362030363601202\n  4863397052946712401923986888626998354310920045622791699844169883212018095594550534885326175425495363\n  8515063118962530921766529165824315900458349693970687658654243281945647647853735525153068989109796668\n  8781002569839068711319214254198866419286668754537724431761446354156657628714055353642878518017662196\n  4712668996243194827310093974171042590552437496873330365968721460188999669280258230500025049474319578\n  8736177439811819412948004602950542736866923100793833552779750038359156208164728629951618141511824304\n  8649558704764203871577064527587236770808180590408423523775775754008846877561116658139251193567319094\n  0209614289011096489957150397207159050424785782964191398186464569806900388364679836798101237694632288\n  8360915854430104942614876035037990344177685999567599330502253234765254688995525806289317811721823163\n  7950877845934372878641514463873034437300982480492495540033223434378058884644265651671117254089024251\n  6568074345760295714812822409478460558543210753456382184804837562589157517060137146819642168971776054\n  9530199246953023901996148262601706284818796357991239697001594441468677531856458312725471743944500821\n  6298283049375695975213397439120310652126169622928117872149914975372547212930687038508756506150275226\n  4203373041216162349639788099435270804166933227218359322427911165736309254664967124992961439907500009\n  7635710205091352172102674878381800459683310699995590778255464891283674339451582478152805746103415113\n  4356381056637703548798094032652665484582486845829067556435863245918075346077580169583997580648813770\n  4343413010596884392991793174174742867125143313255177595667391206113546736483115197935420861547222832\n  7585604017733891732111418623652027644917630825994309391671301603555506639664006376991774482383984045\n  2727764172011229122906118559512750665064983546029610296574754375906955550751018593507588378946923408\n  0884424210404435178451018449469776602243257275763372138266732831848510419137225727990030230195198814\n  5702121716572276518919027375580323980856028541791086963303805028305825415520792215467550998816607126\n  3796669062669622288041052194375553599347863223933308807429440316363392974318457429479645304848126672\n  4296055477893724165925475425727294818303585240798970601383390192188164731155785052643281067107830425\n  3827862550735751441780943794515208769644180392945053371069580028806009592615542404295384939223669282\n  5186545787154155054376817216194941624398023669701764585168224184823494985612261220525940694686843355\n  8288000423604267164920519830030400639082160494841822317937800187897147326541391659694146628544607201\n  1663385275508319000328193491650079157574254157264221073192131424033453260766000540883242243039536428\n  5170101907195968996222168572420582700804488458661600852468547117664403374541716972573166435712993493\n  8871819929175946631813286486618479719449399756737688968894218741250518128652265436890284789523945318\n  9075978183784293738692711233245224027048550113680713014991275390637656776195040824729457795161472517\n  8334058293631438937472774496789651364811407002313274619898292467466885589843355545576042775737627609\n  1205804848027199984955395267234262697175122246216969012780081098444425535915175083609503915428095603\n  2294024501253444800135907132943742644076571567194141395791922713654100901617029910319986570525840925\n  7998434141590790940476127073830478178955109473090662575049936351422786265074676659604091872737225477\n  9472975212156735685726097885664645754101381930184782123365156997722636151699971162308147353868744559\n  5345401386655999956253624683462963168340979755045640501027726108378785182034937053327921389434083704\n  1728605351627431809719641851581334638617864058085289932616267479202822900779806148737877411733583027\n  6131207960256078488189046862289627843902049983703685368810277112776491648078939944439040925075904833\n  2890872832414244933523646308167981840710198476936630553895402873674490337398474907585950356060720035\n  8784504301688110214426498847297177449594105845200382301253166078708859906630371280412152890785515342\n  2131215471139478438631378025693727576221585767928915212630006697169938472634430828463068278319532124\n  7975797640301436814373461526469198950210342181762593659784532667602506674488467124609668661730097066\n  2524501769227885205690673590084316041245928474805668946978182767794755884701037881345716318817494428\n  9989298716727868572546655367737283112444617673040875235065054391728319619830505638090014071189077122\n  1329209083766220493049679457866788418100358637383427091353528093942551819807934978546448024964273686\n  6843355216708089658368204954333674108689934436229704144434396109886127019621236168294238935804471970\n  2097389199208230232314642350567106499113603577319563884719181976988071005806703870572501530190615358\n  5559014641266966919236290595038548687337612191372174427144615555267452282574000580347074835030814855\n  1071539938916838373110927502058170195123131177677851844877768726804213939286034213238995818513277666\n  9365598180645571558540380121592971267768643842853718880917909957308068010225411651642985479859780120\n  0530325322575249974103543108838019843220023575674082733060839664255593659517583051615349713443826367\n  9902877179428908266042597494911477071422970252511258606039005296024025458262483257557575612161312795\n  8128121568538408559162780570929372466124367205888681576790769303505178957563934003111259297972535777\n  5442005699664022021383473566037691695441318906191606144682518131601766098616772320663497456046509728\n  8265951275397273336869417550848721788938864061839846003716868968509185229834465775516415629814905434\n  6762684211445248399413123038525805184868019570889226188325223553643687364583479146903567872259825575\n  9755960216814522299491973792689788065727749960206183123619125984229997445917931919070044699554058436\n  0693267316708926126170133984267188893421249875569902430595059536766540275330755030949068933593376555\n  7321753833566489041072878037317426730961814074515620721259831472457483012110660947978796294904381332\n  4270611655269733179812220467342712122664138192914732789436609182787888276414614697642220502911444841\n  8441381849237635277149146906974336080814504292765761587542170524939409283863732947357784234240779548\n  8209531262353402755035057102890394313368148199515356610924477427046999116723789895516390463749839660\n  3242741993113944290390576059074155553325065548215179292254764254508718962213113516699330454312000074\n  7182980065063873898926256489054397396866794321270549392327444279957173363591063334844185146953429812\n  8089686874083237540802626059432986205629181754412222900184021005925843557050011626334138911164722410\n  3293543067992468631553900279513923299722276621299513099409795053020739055958119151243330404078852497\n  1092537241747430138830317970184410857045135768151291536244294925037526161101183732100465189614678269\n  7244426178043464984407081819464885701556647291249400183231574748921227215054856761733105517328675555\n  5513727525722807015844443069091168420794485271927516752388469452014058436541244190068829957459005435\n  7430805615594652422881931272032923409249033976547146518111314592519057258049351511243668916540226006\n  2755458017611743528143148949991614671893523814433684640427672953871675260813395098759620778572778924\n  9855982834823289177208117777338346633424188492279198052968309263756731847097048722337076247583698147\n  1774211480432136309414872547814926308746678478952455561005349890788889845921184102235978273731652128\n  0197485413419869770543953887497390145741221190480539008552547517769182706070979677126597248844196823\n  3810582599435298238267236317342426715578296460105068310046137927489065603076363259810279366112357062\n  2546093038459223095699447464899594352803595728122073590021484674876096284970187989807161708718601131\n  7039698435437109684351766492479554420274224706377160003575229427613743288102773742437633846548182324\n  2545858652299370190888474776740026800100967319726684955864544676707987877175135398088398320732770178\n  0462499327861888076713309254338928428954733998046782679145981967469019830683989226343929035718573309\n  5966285388450311226586325701495178443681391853583920429643375838949238481221756550210355406710582772\n  6887575137843597979044491452691790592703508814671877816814014900991554621690142569780350359587247391\n  4976161903348045649916980438948284871605733097080720504665480348755712333122224862473301639986713795\n  1278867986438102554256042535792751624131624549552973102364591993011349614295221853169829571040685148\n  0382213988837696390758142551957119935917111875508775962547737751359233870322994013917636580370678440\n  0859562468763995140147145722468543401280785856430439394706997121975940645921442901071293191405742653\n  3471341641286645107585645881239511401177955080732163678101603734337601573155634925565939373671656193\n  5500458810732233559302448256969965558388305341318667616899808566682827713235687068122625484629821031\n  3176077180123905872553472420474152001617666021805882461949664874606456387899631507124429153884042324\n  5075603214047762425803652609205191482910102715774592414262871044559729269995650112860668854627487571\n  8766506696977960282304138110846930878716848357909254627803494426425458612045997199608003166303479589\n  9289456325531254253443173998536945980583602867451850810533130476475285376287457097777675413077142430\n  0232534740409303069421829116816439039165574700321658811000624207185247579746980527651709727451530250\n  9461865993728504011681495778142596361240147809683786888511251471276223179153314870448712057937765503\n  0401664297015076738855047738328881787312124600745276123541766657688170101149428992573491012356466763\n  9625806511271339649842282450273056693708923735816460953561164343750565029963151679745340938235328999\n  7025627180216562436255117986972162498323095658719682960254668065000046716222402396653824185505730658\n  1446063590559554964198201139696528443930157393105206283089149218063428715535370059003504708646096354\n  1097884106096566034365354449061700707899583180561453390650477052743156641760972151791948928336481286\n  6046083530718819480534421773042360408411915761644613091367593152863992339638705407205479884795798861\n  6996218064420153535317900447652558227276706459363505728780427573485589876829668923357242880868062463\n  2489791895841694457900295928632288829382800916032460635320238223124737736787406179409010413815330576\n  1028300884886494159225575438094606302586267698917318461563936799577053825149341530483493122434806333\n  3168840269976702447327490618973633454332782808207744026670977817820783120857263445609470855485214265\n  8489101849573503186642174822985673406328525642088746642534053395045023102754493429019160008441503984\n  9520215325600163927669366477809584126560429064525680617095585204187128148134743445153937464754963442\n  2053892610995494428914636753895787605584248419025831181728850215885837880689893059452153928137465408\n  8777536100423510149310846076543290946086796910018840384162250090888837411244830646123775233176545420\n  1486843335315258075266734685821776462554798771580037807371524124840869256907049289006667811402797916\n  3653743339514516141110722645617628225991247884909928487298887052980830652459935517374082411336775797\n  2723356826803378116357549983476669908238378145543916215512856385576818804480343213210293942162408135\n  4802623088222419123119256612052550161349899775372113033318398096362166247186330045413600338330530579\n  3860790211293203288717499514527204506239580054268931734818354080848734709388738861901021362175650259\n  5911351442127021011648093093037494167291593624568786003466022400339535225142449151606042997647942423\n  4983779611349866591027178292993124652842563039824406078979869734206039517007531875786306161264714500\n  1003208115941696043578824718476564441351338509186208978574621805394727057491475888584634266518241468\n  3879858080482488208055020192887763490205355158562400189346433242686366341174030312234237172519433745\n  1401469092871472905890150615238956228461520314617026175667585862095154776828356254506431626437458076\n  0714178578002758760804833259675887885318095959658148160080652129817919584398592529518445846927246647\n  7076091516851746385647187622149193215623010127131052844507481070026502446417858724356779922130399652\n  1838279141848265281625104614721163047907822420234842176235064391415298230055436257014763699588784501\n  4405130574818011867308723759652465204643509343130396665585629392515681038169466662031363943991734489\n  6713982981562741198826272351095251221821704750686253399267537797846680999542042149911343540701022056\n  9268199940425166589339284985656673473325794934373118520489614803989074911035031394683340777866936873\n  5475491107761126947029878211256476568149156669190955293673205595772792951298209071515773009178847796\n  3374300214580360314477890620077155490476480542427051316776689353266943735909722400831594023758388314\n  7635421404408604212995770165367296599020483630577798545770670281905871864830613825275278600758790702\n  4358743812118409743929083622398912538931673184265955965954849588145573527311910746917982834574376785\n  8841443980936994532326065725996975882421929358791454369349104390422637817675573224987314756957013416\n  0414988729796068385741483909738944823408130109565830165946280719178447982633284555363597451218726033\n  2535781792406870010686165062027823681063429287414508137306095489089247445066227733083852681090209081\n  3243131511849533596968989039103170864371432842682490648126662406926704213367160470574265531382424342\n  2085609793500650141268388679333024186546223074720253207178938050317199178734911226776218997084782360\n  8111600798019560682135626640924595140594191988865960527804596189879889781246044507520439119510874257\n  6253503374285344359966802548772112938561910122074296511208884295468554439251909040934596997623225136\n  6844939593914310582200549776165119323633557844773870072751670887701833608973105333061674009407487608\n  4857287050254039652206249843878079142123292038061883104817232109300172019148512553721123091515719016\n  1271374065368354640345909017516919077376312212625722658664549644959123749618371939551519665045731490\n  3486981404538174573697589822751137745630786723562169766825239245298159046756218528584558914530148222\n  6584053595263909853937176619710158783873278238375584724428825363726210818665740744020130772139829403\n  4324598455034889846916089350460604602972075243052225050884840981344559999075868131547522204656145766\n  2331404526326965352792923797929373929190374869671964630718060724784747396550517097475096606260234290\n  3764684445058224722202132386388557145132347498203499660406621177777297860644341467366211106480533161\n  4307054651648294660337643562092912703240902104351027595403970654729979272108961839673150847030362204\n  9840208056686992252465953583737496013314179003537005246456058694776746889730944136910107442020272238\n  5751420522547081908963499142194431740411237485172889543080184574091031999461128055643344226228957934\n  0517365029531336028314329702493656220118807383796596866938563040365542449375719742102493740570193694\n  5138482569860019532151625689714018351165254960063601103120281995349670461609746208291773657299785645\n  7130696516500162277788527383407259835596739708240463152591767380422974317852831564944495450369564011\n  0936985581798511502721191591763800482965813078985947039731206537802032276034416297329698012059066824\n  6901430294939952501589890477105080253835157158428051781526426400657458402791703655628341155199917788\n  4995168857898088140509686764825608157587168921378526143482401986700859594918343799687274938039243990\n  0124089292676454523422192207578413785334248788335354749324685978019743073891678142961050444496628579\n  7198684931704497491550675521279111615838057069681965725948152986672133352580867678999596495159606109\n  8889306228869661326312175575758648326279685711415335026472140795023598595852764820313639865562813744\n  7612938148477402022504450859121825095624779073889654945265020370785100531156965622029849937475086136\n  1904397629959903131190080431975245809400009145582174545266258052740399813169325700182768421722318051\n  4068200502309296617727018544600370433014323452516468664561052172069290603672027333539615770828488823\n  7288135889404534490226994538768784657248578192875582017026334879541782535545557549068250069979739505\n  9504613420534309269819057255312303387133029128503192281356963960128385345521159435691409774601581987\n  7741238198895866727111427295831082708986392046218034537945562433971856249712714095792596192307818840\n  4535552979777422106889367338855485881072236768784859382251540354409948225290592834847801360135009151\n  5811453292144235396298755483068015588531659665633944781862223936580697312612851200242204741143375961\n  7769910633391463758052035815470306229527721703514821238530493265705844611319656225452385286064449330\n  9181674712723697272029500262669493867606739072357441326860714781306327962522521358345146175319707352\n  8090113543146777394534710240060895178155583075721182150799500558837744547319261292538304998174304023\n  0702238909816076153110992888652872560217949886633964206182092131604317680117781542966367350787241918\n  3405805978019413641380162857929818320868424446974760959467546593513927192027086066670096446912642578\n  9697600503752819096615375661855458062643522949216579083498437925743197158770646868200181823204868998\n  2564563340501384966557640297083448061878669689312163513396687831362351177497941993054822898661904006\n  4715435959579227544277779439667263372974662779775357319608434724918119021011929439259038026026484174\n  8444782005168568430346614412500612254411855360366968299480657213953513340788692453270591291498280174\n  1121071884134268787888298002107119318415476906323213303566470428019983416257261051670413116849386770\n  0277509498844108513693169564448607593170835467673690177738942973154551145922770111036084305577182412\n  1223403292822987443986446401919560923000143949934530604425799693849177239781614945113120420486863791\n  6752530634900665239580440289843539255578484580722003320292503465974481326140173373348415220872649858\n  3672364880564331283046930530487353905968489776941066248996816465510182556276908923306543747477325157\n  4823464207618269372020011128849083740841566637879049177157916261744725335692110279631363639619333830\n  3169096058563478651583641040952185421892539384536519000945682188235121967853491290747273345761908795\n  2770071453429642885777891979700517737331894256474677870595141670950151254363254585850590927777223574\n  4136906107059254179657940736448940133684621259740377694362926710786480691656941449476496275547975269\n  9750611239290659055560299806182775792321198690451590594249076760144944330214475381107886168394173626\n  8247379536204857866736619434018375399507887357076956973633489060966234152033032736644168409155972675\n  0606818691954289729554967800742088808731999842293318016422639183011407959704912671956726619387623534\n  2306778374503739921556049731619654537918413623760136660987343740561564616345985238478285233197307913\n  7019825090585326929428640128896615562366533668086796762690219338587009470620408502701789450516817868\n  2770319342784307016451931313911485790961696844160662092837320833387867641488391352989258481845308669\n  9758841288965867024287556877312359003496164995760829237752268936555707635413408265577248890243575485\n  3975257909113420179830261153474517489394228238827710449742344359228203662147297399136740367101215970\n  9430824875344769801066976990314194078502080100063845162203542748953285695525801669871401279094554658\n  4468531729766388592232722802392295725516217043953779868091887085119555014834500653542058958817281907\n  1594632777061363476090473165184177320017762749668619298300484784222251662526812410603171436519456728\n  3488928109589044695107654103618988534832669434021847931347638061335551520236021763656182711315453253\n  1524831850160025503530023509981187456840139784132450412924899510635618839886059399851860662669837430\n  6821560893536408037221056922170621065402903346895715239006679969843981971994494884736379926562713791\n  4408554512627737680336924879096474511063094304810474408259752902764930190996182867206680083812477082\n  8042534854515494482673351770991586513972074445355962906202978965148227996438228462410049492538096631\n  7158494746496877324294171486011775792546480922293925634847344849734476876789725518676844578041930104\n  3588384787449847191575466125277421065198340368876821770985647989749664179637585327608894833993789803\n  8693590500388591500418224769262139163222115117073297407572999505921614195341795453956482580695755819\n  1410105474085836697638897485443567038088777622534237252366858625286860701112073766444177034759239022\n  0540292118336359207682874681916357344362122584685518491173782814989331732943286878667341277094195061\n  4067843095596346611830093772355931550084081882042990111253625495158658798777933201606023025399639582\n  0888578524640683893060314881551188185106339280138068829477553386857687006287381871755096202301678908\n  2957729937039481235532251177306514137747970534389379645194776233680444566103772824237746406531747191\n  2285508752570124855530349584254775511192310417412608960417645304738448618495987688244554949742237079\n  6274252261378595615081527071735522514060924714662877076575923280000636236617818518201466129968973204\n  5067019387912233902801967928485764215175360503242804953741260170275740303053422716418639495786000064\n  5995239276691728895103478325073178136744237372764385742521775361860499615778451640562125120075711268\n  6925439127054804174130629085265480196487981111437341575547549991708223661965071527972205089698520513\n  6490535547278448297207107814574514568460861115729565963175793886474842463316376564944811616192160462\n  8737029040409753672886130662513809093509849143091520136859403499036297931364403312590118696488012087\n  8666141208928978105070175592631593289475933353555853961535737486473277884692900514837562696456927138\n  3010871929842282561144132628796930855435148219592948067080592226824590669598704980565202263218860004\n  5813384821338380107140119370503199986558912494606613140897994650450291669772328830601951849785565324\n  3552234794761767925765445820526605167994476072270550260402538069305498861065092174655658888730178883\n  8412895999596591593227930457380841437898235779781221663915400107412133609571689636670057484589520547\n  9261619617366617966892473003181633077684291239817740029380690464820050593056721097047072358576276559\n  7152866857405809911535605869057244722420834985942707651457804339879341679576813796362083390395083293\n  4495580595363760485462231136251679236438135424774841948043589332145988194213605792941674122615999836\n  1085501672440264935290269294762413425825638723031974350786160646176951012185410632203081716611241488\n  6764403388729757658443952202219610073743454148508916871337442678359527056131521252620738693321830593\n  5658930621030492920953553814549511601214641984397939037189643986934878415890922090939070427578219059\n  3570943076723702438900534531209670035089619222429881608768643298293971488249604124465132808211248922\n  4188331444749268803634239182966671662822415678183967524379665967458116991492813690145022797801359769\n  3138653945547206845777717459138536178479266953710369508963772279061281236547915708886907667689081937\n  4934061036841067386005411002627870087470594710658645143919698055970695055650501512339366658905717331\n  3364476421307065675731991903938811893825307521088285951614750680946883924574001113547027478698216862\n  1274321497665188300319603334562235534421417368117005957663493676223290691848803237345192434912465665\n  3297182384173969198658713331341207105170736834172412344723718672494151084270496155495037955015287382\n  2486053846067672039287586862626169843822805601587578668309251223040159989753848922836009598075215949\n  0258074717157735374806690050015349853590369767229710437159210984693912049054262463396085508249182328\n  6584393402629382685637152596238947447178336999661802011547882499133236522159566534048570112325827708\n  1886215013071577934600274395168927524355182396240839150123473924668651002227673515415339817443806293\n  6818843187021953946745788068387330450266993482047409308509529400887069518186325483548249662607066502\n  4995646819410647040712273110042154418554912316340734019618090749872367033899749934392439916588065128\n  3667905641695736521605028224488521757361133174294735635774830847833098492957430573060450412840297114\n  8973655233370252933328593415448831374005810726242464775155356118977342742942596840194068133338141610\n  7490916404430780527772977009382768736682692808362834677259100328412812893578761188653303799439157109\n  9173130876841482981473167438924150708123330466386665268851715228773495808650709021102713080114880705\n  2510861641816152556748171047862194001056128001346471000489600816181363398613143759537835734463470097\n  3802239706673331788471217421662379783395050849458405648043005911201841730050224196298113764325550862\n  5993667297921212396833626254330792019745755537985778603339936113973147973585880467482663190555031714\n  7510740826575455384526005243911716394798545438546404774452744423208201158058940110410945383309204755\n  9831301278034058767338113451784704239620884935829339947629489274926307615195947580863523050039063526\n  9755089737196321432027975808869585297731621983594425668946663498655664182852784053071039460383705531\n  9530705781433206165483720876373054215104981963982316223946155540162448192274889889915481816161014129\n  1114223327424807105120278497238490440264296807698034403160101365988085642296075406956955713350800535\n  6595188841456265319836545998149354703533396578804947612732090048553113590869747145353689015718969841\n  5775481177794107604190191456527288840405188279508490082645360132429152288889379751999559985968288936\n  0891127109103099730675706218659729673463984306192842955042921054669160915418280351783236841552181865\n  5679634071112430643855154156248975176397718812620984087360982992383637303027505941877062626357378481\n  3688683682933396988927744468696966294996896602769160036986059689047184171600019718412362651997930127\n  8741913927227986980227245952294015243220840481753981240082576371360670303344776541140427436996205412\n  5145048270021051517411890882549260977472146205536677900755200879989232346535925261273772769545671215\n  4449995014845268543259740875744450235595031758880946786706242795049681223173819531934699556151004209\n  2153608326032153069185727225992986003953925473431806464770644415440963085983320989428117389795068274\n  9552487066282732805364792474107235461194594426537978749869795964322144950143520616632736083387789574\n  6269008896094162137344263820026765753391034189247610563598881700835396449558521922407698130525217319\n  5013237419645342897616581354073313026303028547802248519255207832323745483267963289071256274752461229\n  2929641409424850290594741557599275124250850699663473537642940738391820741909162541609728445916256144\n  7272170590829385767671304543843359908261608628467196328751602860804035347208536219374949413665519915\n  0853689237351274850742948144519654169382291793153091803782047287223894558772648584565835836888354176\n  1056472125564386401518568769577988275174222434711115526234369721170763345046653272476633423782119587\n  9117615783397228747084512798865992451832791641445982802144372701894626680357923333751748064104993185\n  2188455068211836085689756325118138750460942419557443263971984310789277524723566722883955273552360662\n  2598788598539632877284454683694923676064844122735368292191324554704074421666820674612656707964301200\n  5535159904741708546163733620270386595227380642312621874062689090399816710861502195826500644977817357\n  3185052157715160847631314297100682482491391624928925561263847673862182333452283028570138155437476505\n  7846569058839482531341998139629573625019198571058084667923649110592908805506833821771837094406269993\n  8269197068244705320057945408351861003661161560945082423986504199873162383835746664545218873590261219\n  3453160485833921266637725062085190546236237337328114258166438424988979859667954175920036913004537037\n  1962753606871830137648121274105614824487959863510850054873490298447752975753493966553071505515441039\n  0938653741666521591833549973825668932645268620823596214023963409712242682687002533955826932243805998\n  3242690845304781419914989311071015716947495557635219458745768629630183899058242012787867557969347231\n  8503074461060348391459879497794871139135462902548628222497438944743868266164360683181248859872326879\n  1076616230538008602921583381443284532240746235541879988817472381285359683828950062022524646357316108\n  2663603643148563553160504991541441308872154144331745253732106513961197330694878139130968733186136669\n  6193940257200499308099995348219427655878113235218778124571834239764680697306979340608138301890778537\n  9227621548466408823126429816421239417456971356661539825555435294981722390145222359192574194314642182\n  6647768886677250217123294152289784461629105662854200714538834167814891345667445069291290631913561846\n  9153315855813507648754132185945574577015648665261674662085801070023556816875810595967699890198547270\n  6417531288487494139070866420808062769445013196701970335518100417192425136442744852197815370357770961\n  7978036554715010064181805027540735836312100758486904203604530637430343887615238289835573728526027901\n  0965811358399008202510641500684886037785145170399362693832261888230189959127100087907541662874832239\n  4452285023918486791381569205686354321704163358637035324353038603138245178894425200804853014804232640\n  0652099629600966417769376130820806870201308834720999916645580574702972650642485903100718469895310690\n  1743228378475715367509849704348348205993122322475198548535455451980842281450746416932517417116603293\n  2667762278190834897227510030808975252050302466493512646127848908741183038587799856966390634505200221\n  2393452668657992044238614847572428901051143288838145837001486782283330164072761140369413621157371699\n  8560584173544560803368889069252435338105397159315045259209401288682676195785113132383976361566212857\n  6482640972356689220650459488317985864101056438186988942899276314816131141197839485143896402016161447\n  0282221756482734200646153016170156730451861843770521270625734225871506289598548861762052296168865652\n  1583778424714947986648770706732481799084249744141303077278122172757039389853107662656948276197633287\n  4465960455935018021232313616829469105165367996131496561881423079790028197020753072041377449667453062\n  5110784565792463800382738568602245895406143936149940484842869698064832621084643807433365583986880899\n  8847151429570101451205496684289667486610186687651297313962832144102683416586035991143893180762564434\n  4609274750282537324722439635823144186618983533732369168086950292204814362372048123472392174822684291\n  0666117849435316725923850410537793110490815729580082189041099653740522940462019848205947195654684300\n  7682203732839906146792078803130621080742887826745652227951039753018549245010806671435652203409852097\n  1712751588390486131129466673396409924349264716231223460568160044054572146286566256168928699746838216\n  3390433176286370809582850819096974176212074055085110018153302081718136717685434872720891726067431810\n  3868754990964287428041065285744478313994874978924434353732018837509779534604400528119785269275442489\n  6325741629879428825506076395165108387117664673766387526975088379398903288357402112295635432087437414\n  1624949105157682271174177119322329453919740921365908600004762024328188811611636449287155599082998145\n  4358403717095653052756790061038582200502577422429256977373229660938546733692944968154326056858234085\n  0739091504592315081322676781063632505958627455148922828565406945222105635580286224167640557695260322\n  1833562396373988080142461187550546095550941227200200166732907897800070963848283124462955965450221207\n  4332643657186971345144689688892295108020016256807995121841316098330970217827686024487144336131445923\n  2060147349748148691320774245973643394920073088574820672241184792682405330459869275458970721315458415\n  4047723222208392080363241272176311628918816433940368693171355826800063517320974505243783052633429820\n  5158572929372906514408225209314003833442860094371776965082929411189712087370784093552754759466760770\n  0739582996325838861067374507926180433067251405352116133767896036538579850322184508372345725893974482\n  4492032873386027992042012799506284586176929349347486450464919686353383914495693293534991399224536641\n  8810063103071095056877344542309645895436141863087624149444741986669834771340530095779787207929146238\n  9626390884639299690639310163833638321319539379304280498487596279495977933648358480037841610186331741\n  4981336434273879803025779702183088650364181062215710292820215871814456266435519128923907464494910427\n  3596927665231146956658445818114476377375235012859312659257607505565019843356775432091750690113587867\n  1619549365520291390943771733201558080722733319100177931651968154228088370576507598837597021754117738\n  0871379853389628968302629816280553011075577589785348238548129828105014962885887182322180488826018274\n  6164487902917284184000293674697066526008628284388308813356335802435105776352859335154443801010244994\n  2174781896553188470873781552236440714542829548321311895375408182160748659797776227910230823364843617\n  2336602917193399261678828689800578911911569612861137304042229962444456452288117974715366357914615049\n  4381217969991171955339291546798588856908281911031471838112996786565145305967981319080042218270900569\n  3044807483008345642515023609363752556383193517427034362926840234776413899039043362351851350263930095\n  9664448987760417437860381723420607907143711944475395228435516778885709093405909842628007555002487258\n  3065055751125935389631517182606584600128932682974216179130811687821272103921757969833700705560047926\n  5997432364952544755986234844740409617147566288275325091737591546032508096011443270411987315969680079\n  6893604075977501803740941714699818850466289826305034062817302823197991255309183628077992511330655577\n  7258958054972193754768545034660721841155705309674742472328699207294954176864890518966875077362184297\n  9151157585159066981543346997356951876553230061572819957408798433268786548387703704838867969634471044\n  8810366625529586283434384804626781221476425166019764227020362945087987909230689977626220233634117711\n  8201539905017307149399611554840371522826857799838510938400452826367576126056398439135294087394557427\n  7648499241414685824291385791775623295402016824786676002102151382666411013004217800623443217919523686\n  1776961388050065925090702529001557499487526013723194269628376917390123280026029927806831063027349010\n  1100314067077900457927698279313684945163089509182904830296500190892833649883721439618079320874232876\n  8068649099204449507359860528957211699519040408338984083563306643854128890071475438665670708501846953\n  7900325716436271571357347225105929586511098406845689715658254557256333555945765777476180201568378523\n  6403149785380983156625318580942578510581390461546524807271983290957729580553008835764393546571457913\n  5927674664325448384545582730913986167177799594349945503174771436597966834564542345782349530220337939\n  2308962273442866717466798655682537325145377430092237212027531693856659776107823598018863075075604083\n  6771274187145896698345702753848703603042584280212778831071351132772777499204648303734048642790225836\n  7600773900836561591221966284269036366602985432353631799451470339639496138687167177630565460918856551\n  8443445168903346245846829124143175358657498912475955608960402921553939774464288772795162230612464779\n  3088265423574801071780915277401654871046826553570309898131083104309486675394151163167665828140370086\n  6865547643833977042757125044749221422969080622787608544404858813995712747561301902637515073878311885\n  1441005371031418316347433675117492320531768258391503423545058602263058687027792432296916175459534404\n  5744739971171211920778991581218062470944155069472735140123455020462906778337817621419189014690880707\n  9818100673485939679726693487696523832201910820873136965799813776062143345608391307991994916188426151\n  7662011516330133652402686506039217254034345528675180825801046290582083646811073518337297519614561225\n  2537135677118878425199402354396224247751737334535338915072628823213219610084406315154799859952158888\n  4711599783751001062597243954442905647837242827112768861308729717667450387784470605049817926326301121\n  7932857796302134172905845069384231278574470982819903689333323225245658784864990971750320221672852149\n  9882775465830655901595843516185552054897826736135796279574933052201119161084208023699613890043993283\n  5066345181640768389987922413230641588672500479862191487276091383655534567175784547455676041291332244\n  6095514831253536112871452107430436355478982136977200927930137261704890828039390999835574082898005613\n  0326328048784070258801908538773031881871273074613664205091087496124190176913449970774575283633978323\n  1561103564821247090359536816103938413756883377157827938294135462391627057605602271779835321108182513\n  4419902677286104968703506073372089355308640081426599165087223597269462486048366658911303958507510474\n  4947269939264526460552266518924976453080721310935209623157608488311382603647916682468008414223588777\n  4104611556932270788793268743612837957576853818407467782098467762736724469111891654655430484797104215\n  2397792892067638966358963835664180589442147453962262317532655797252681466311769780129937110982453405\n  2292709330039962951371443831951350573178805666396104212257787252801325283848330829972881825074988518\n  3147176842056425852484751295545343386763129354644077734050007219968380140522695947091991189551884053\n  7007723165819521053047311491449137585879146562388719464798452652848026896471317271515010401260230712\n  1222879224688811363287433466723782055811179420272164792256537042244877632969701292769131500425202259\n  8108009997988559023568904329023147853873872402094744838539417783679432332561309381772050173430979624\n  5324951033905554193731155678109600573604690408793506212987488240528497439396469465846777436237028014\n  1430030440166179011657976026979051136930909194130040439925056649562424683802034050894802900026376220\n  0578640552156227401553880280034689559175431276218613147605255689989509498932383472879082539984234639\n  7579120047011707656479780085662647461192149320181526856763348584378214733117677538206424894580965820\n  0413472695716237038372077935659762005227802251822529632003253692765319844596583810375507928342527858\n  2591745643500626084344163112970195537547485185666661090821301768897917608118674529452988157107661286\n  0214031901965386239562915131391540587849663072019421858020705480546447754769556787208960159717907361\n  7241406114197727650252901385992813531379709256036120684983888215192251813217998093335978213175107048\n  3806021942235771089945917470518247086038195757880028161556161166585331628472637285890244233722087246\n  2933270283531749284100443472630417990086941692873722278380802882663780139205329286772928042365659125\n  6451489454928932008400609684183178390593490237620500022433912426191828329180108477069574155867364119\n  2801283496458206833115754626233916641813906198852245734368306773983610104642316464133135532352273752\n  6644533820300409551032192889761040287882571654340181783887410155412948949210975077746095597715247869\n  1288112448292842571974688204885654909561576851286105935267802656143938335859217886735660059653009853\n  6546206425434637910629888573898318354369679219264775780379760991519977631569730191138816967770383136\n  1743164453785457007319360521970015173541007668696013054372758816070499877893650174222466174381932691\n  9286242930106198425416346048533061312244441005381190421705295021020394928499328022918752088000318240\n  8337953638642237831826693545467637857036064039922133069977838159195259555588878191552733115500131708\n  7949016677272842630344949747135658767281439426549205263006190800059109449562185452175790848418298466\n  9384194955881207470010603768356344103320545001615165724072012529860495889470797218342597016438475984\n  8658280980869054903677261462021539863629416377179304762721831365968096850029180311410797043113811864\n  1849141586975849866022454649276513102872758629386704002130005951781635864407787481178065225685065307\n  1350734245894460268346208345803133921453542233875444863038607087278502777777508677629920222402710743\n  2459134004028928720902658654473562108425271922286631314180112202868765811959272712835132421508816450\n  1912089966902197373677201815546709893992735421991162731652624506949920028485236634716192101353179446\n  0181932739607212488739815750393461817020822302795639335431676555278850293516327345947265795104011499\n  7344823774206587573034636025051615613927268982066048321085542322084072024003091375158254174604210574\n  5596153391984589002739715743753802242641556777875930793480424536014455008046344124054408972659399663\n  3007997972592129223109419470783842041830759662553943244560963589541422566136737969285423713764749526\n  3375569771626021992267349139427236091784676196587205759703367639965915756363993425058788943766830142\n  8916417573850338881007860021862503880088175428204767842725956719604840605712100796561649269169969392\n  0855774499424977562114141333324323795150936409664134080844752861415797124250850592580508106462051245\n  7221688482019793441153229915524820485989751301007559884796958676495248802794232312419807388735906666\n  4964915113962924488710570456434199781743710931692166476206909405665634791222087667353162014395794445\n  7621663868466016550053394793158087747107647644547839610999272348900285145797974434466044051117604558\n  6177008433876053148008853673570211565036104548799284037532175914820188299399708652690645538159173954\n  1840830826296942142296036192656880385459991453155319530519391834550185884549349557882374650985608212\n  9842400795180417637267312953711599532987137948096818664554688514436258350366624408525585930624414700\n  2018821220464219259172345933989619257901631775292386555197656249237162846568538934472706908824411028\n  1325841910775755054815966754311956994397841516332406889407043926608112156186190253032207139064676977\n  3268368150661123769280024896835575713723112884258276892878231095678118996696977409489348724146614973\n  9727949412661076369402958236283034824223717633199718432399903981284939398586827244646054071699259408\n  4518183571889109435126417684691477909225283783753239560194745349090551016423380781159966344826207141\n  5872381354203240493175757533707935096946134828527465137714683420562623632197172961999170866638304381\n  5049988726067172676572483899667394934781864059973119900529660035329941393264852632809300822108367705\n  0197128707669900247813008513052729668440606101643782307191363070494220493834196009535099939871351587\n  9252197394280615135656431340816156888490174782485783660680040392675996290863093790311150672767194187\n  6882462830751887950689739054897988939998836266317622380542165500973438436075892142420468068102248730\n  7387780947877235273901645574306789841755860978059801159655866608180878353193002712597379133589578973\n  3400876344311886148697683788112151087712667757231018332511139198516665079680964485325566384175831166\n  9493885921614166745675555382378604424455712633396677214622446741586901295620545652768104736368260978\n  9864963005682790737691986315601291614256930647810069891970202265386741626030496339971273667679574289\n  5556631401488118461544582007593167883566826708991945569858024090677654274445079856845354905475878108\n  2742772021979660038202099786595196994492933543169491649170554412944820929676092514799032258890049539\n  5499572299301806217926211240711016220957855270488860538192842360852957014065767422134831332602634217\n  7054373095357010890780730221354982636285288782655869156856346625947313258519565913846892446244583440\n  2277049670665349938723547520909770648817090001106391255718740682470471367225709217122286721119172532\n  2046914596922156122975243745550688205617369549406662733252604137044629086544615104425600763291794861\n  4510692258879443748157789125088591113417223303156749738192086397220651352015828008698246876537375323\n  3446669783773281011145261959958866650108216881597594956660290352758332149372864358745996764765258208\n  6055524473391211712979767298140379890972865069764920322099279240402066292979560833334837097343711038\n  3136407411648476005069852015674472277835899960842557884272473530611705160202186456818014842377128587\n  6616591199011868814095160940245806826199051129611212754574119275346382293994753499107485956141079594\n  0104716129658891591656799255444422507796929870576970584791430401182545453561117242733713999994326721\n  2771932319339130006890262678523004204477598136728474379012867170965176478255946009076012677038666595\n  5450974046848589127133239909729337983586535080972670948531616454530790871573529955075169242502752012\n  5482063398833903447828489486253263843703940445054343631202404956819485038629028569337191554779296289\n  8845325057659768207643446294689814524433420558044994658582375053659570536224403818429935935441506813\n  5070920577444979990516676905380209621766365606835781587320379231026760528625950776545290579527210420\n  4138524615686057656282187475538902520578508007406933729429877374630579256993775040268566158661680407\n  6154221619388979463853633831125958244187970971954952240747959539519422976858251390076954836547899338\n  6356880618290567934076519758024674217910250332216964377600441282077990490323308123176112379972572146\n  9283312184717521295801191664227393514437669837519984530645787366407773806996529187031231945950041645\n  1412022582697246981461488184628904987272836192381272041977916155713134479968757570339354019325461289\n  3602565440312289217822034095434438836935460408954458024790180847629703419796230216029451611247691650\n  1860059811641727438266730728952978409244016569577657255557295761302425335479095067619819197014241516\n  6593574460395967361853255106100792443466532944181807012147646030124862963997533347247459834339008685\n  1604672402252161362633437520040663234254993084214185882609820943615743240845647108254431018830907726\n  2585702511210465516446200720391537464739321529206337979709851707477303806053628389815119695460644201\n  7113929566885311883280626433431701717020517026485281318412516343924730717133554950605158671361101058\n  0504697835880611507229261275769395214080302982839704314172657091329508291125343176943080754686551329\n  2224276499041740474813410763681949573977464379686518304446566839831848419482441760598638213837823531\n  3730452285949831010176224943940539018649427132324272489432022720850526670401611065492980272688629950\n  3201407835500681783266124429473379347087040369339474448836401463014307665488869199951906540631166476\n  7819404973010037519857054167252764702308591992273998423414933499839097864034390769224272933766892660\n  4934944169471569715547059904217421925882575342592999565986426768451410612384687880654457917717504027\n  7628236063300794375840743669481319018301570912676662079893317001720205395490686409451497740977410943\n  7345210942859684717270234064506710071428745863558686782369963390799448807437608835336820312113732445\n  1571040418642925879449637775145772351175866088174938782675387764130377951906050406476302680647426906\n  8794144744826935195393809701784967319464528914389222386328010121834314118098075047970243899193572725\n  7052706054704728147464744620822245407471416940652069695167600105591770136489713227842017003356643205\n  5511462217933132322217119327373477715778865837696990791171131728353740193571986318244470476154481845\n  7702523441248455096812811666497090604322747183366809811678365157004680187681709568893241844073623106\n  0256627475747969763747209063548402949173472748730812019505270963758360746254547935295423417127268198\n  1339902641902576337361165697385508744130241104699836432221001267728682180949890762368689263384417518\n  8562628321296599412137517969890520924751998789466845120578373584504314890844568816138401588039698729\n  2009854086296947132259863231317127321942891413549432335912293724230966015461649969855796276327555457\n  7984454403223040904934659346663308857369596023285750180268502120007127142076555657726407983020729194\n  8065129360217761136093911359393530812177362843189441739621355453605002461387879606760408053169300250\n  9344182571342161361444011915228953065300777905397200339662894179465964177798355925342228777465640003\n  4393526477351783515933055719947159812125038017559547577745951520713908433610011537904901507890705670\n  8818445741145088305122997002099696113097121893728533083594288099049270074679601280969718292839412819\n  8960521323361070521443176014995019958953589718336907828313863423685795679656341929304976981520997452\n  8878312145973684607567476636060039687917435421385034895326295820544748769241330366118328689112778317\n  5460291279129556760074187332255429082447596730430080458966345337819875369948633505377224451590105416\n  5665887069898901375388802432758515141185845435365298749157271886535640826832722511014700909898627167\n  7224152877689862267703698396995978281655794088825371837645374022181884118744813382879471964454937570\n  0207234696253360159221820280817972604912829242072671298002423760022464850087988988572315884221469461\n  4749102789155465212305942486102726047126981324149381499017673574896094118268050477173013164589468234\n  5409075051861661015410701795541759759828042293862715551077779967459122466163847477146011178964858677\n  2191861044175307319060399730981271821910672442441948147115278343039206536812214246550226930206567588\n  1276475434385573474263281549277056266006654671184876520726733565473166966217706983364583582683020776\n  6337778647489587312552194785990526293246984363824685738723284277789839925737597904038285297787397684\n  6638096241754775914830964299155281451658037282442319575209277265826932305975246124505643557559140534\n  0142976750824433474662439858343761487938996414440251411300246886937195215783044869344384073455908669\n  0946448138235353204219253479168899801439178623237601755214594654274459179747606361665240186206188847\n  5586487380583089379600294714755490167949590428156184287251585293982983632066919799567389478800199587\n  9803482831259925329759910502073507362660254243105132862940349554176399109476329448542904448102689152\n  5958952145732012266399103321680006863504862007357034858961061790277660718167706817936631804538237919\n  1259561984388576095180289432157965212056576110939899154968840313775493935408569534499080090127038401\n  7262618018204667379599468295436971942325792206474709758952510700203774171942638934649675715427250404\n  6938718835727756344487694459508498638877616835505884970028685726928054212917958581319142283803871372\n  8275528683064543331486880921516972378760137552798110459669882917779624109707091370378839304506450124\n  5988678589578863709104821652981152058332278081779915608263843346554197603150488841919860848406264900\n  3995878169329427061962297453127136532694441514636256973427524160873440269797879002146362696262012037\n  7533883677549691572082415463924241350575749432317953795546323852419930894060511341098518780558840927\n  3559116716167018711815535058236609856919392270006468228835899448657522671480046316567521942019661830\n  7034521639282318251127783428328954142472172600810147875803021229475153440371272332167086572434181080\n  4779578414426518997788601140202712329482376233826892096411116301103221754850809433535043407762834159\n  3003000533913418044642352624003807395109513701115850953473248223743803508935289352165877809760032571\n  2128354195312255082041269876035418900771365110860471819410808843111074253639171389881359753193233465\n  1579864775046845758698939196311882411441543035704000826401267779538411066650964079049875221717226415\n  6490434959626706563289904578376011368513262468346021348455756462607773521883602166221683273267524660\n  0907786809348433879198156466120824848678050644296958460210293045372463348760259962242700993707358710\n  7459968463323761050293787408079067362688314322240026342541834946497494337876425107862940494355970889\n  5096801337624024819095581134913297913613799767020614698043501490706733150637876240206623907027183279\n  0480285148295606115474069599725619492966830210211930502506226826388089654062984556197933891284197588\n  1135820072574356168576772366593657751853637407687010082486727325827055947358759499152718354765991563\n  0391378571672985440402751717388265873849917746309881277693341113336407022766678610507168850450924177\n  6817981250769109509091441158337030312240850672305458124543727125939201379371298950497688964104658348\n  5074819454011857702359172469012966511482150074342299282812227997873756699200712962845547283485924965\n  7682030788467950647021947309801494977443099497791041466285009066700904219602986633110301100111327823\n  0180588984555896639346087537285190743600228423038962151716195641806562700099995601348969285573932626\n  5725163640020407998471412336038886746834087295761469762659715075739705145216740388083854201531984940\n  9356208349418084482165184390718645485793541198865262240327191774938527578225038226935970540054945456\n  3248668816693702136705498488652755267963759254295311527394338996216801552906883513703290248458258150\n  7127636005483568596542941065170419630389669909871302275853459041651175097486133027113604353170371718\n  4168098731418195850315648707721494788546280039262775184566504309126034142218423042101331402856915028\n  9035417750909654228140833298247325956328247018868131890697734122400982457204778102124425786794196217\n  9708245494715165738807912130559425579829365910185929521458891989736410574890894887746130638684259775\n  6423252686346343967798383912119284815590463257268442980690380184893738786626776014667556930214317529\n  0992680576999578973176289166009235193383288594182243444483733745857062267504976827361392921256590388\n  5590939178962936286792195698567220771145167687115170363840099018030189287795668529739177054160961453\n  0699375915962278339171127981012984300277489093587489453981173533815768461395084185638045832986728493\n  6286928780127547239866389241352820450578035388536484709732754492568009427559651602910345775124513594\n  1932152689509014544595241696113698064708110231533338827666229870284100724886605287603754043021857842\n  9642231635313350340680402784441475200826890037863547841565363689567311688395043354563178010166155103\n  6438448861498271395607957291390579008646612982441522813477864422645334901586371744886261087774283733\n  7586277208196830696383180588110789389572837677830118699970089433656062457189838150176746551248089349\n  4477000837345306194820022438725236049547571173946629136182524460576260094886690256581329311350674437\n  7932320250380205435018529949807781052599853044887550724931255065100388571908248547838993266028603373\n  9356873644557467569660119191601438807752987664394513579476071447098889327766053074116311530139110492\n  3282193110588097367047432344058908828564002679759435346427421078414906154092962408338791081565789909\n  4988157126902366200432802152895896157752220606214579882840491823383657351254312693680379872686847552\n  3692007777213811796492400361590234577003494115340683355738248739131353919147581585276254133758998420\n  3618879551380731734622447712358536727905300835514369174708516100914754482240609224557576103986096635\n  6788289455003336043337208465567251648946232727869309895094558630983011437878258832122990671329181939\n  7652202572455840081402413093213342095068969419077870202615357580218210512329081352831950915725992555\n  0067198796875146302345713152953633128866961298875104615085935633839150702622404505679511688694605110\n  9466276723760723750528845553323504747748998015828804575300504609169021596452383038262921063032258517\n  3215675280891358488354854871241265327424716575220157935604338198464883776605527026552678470835601024\n  3568608832661178809770313606137790936091130872340772096181023901578532920354712719691056747947044146\n  4331213143956096751662611289444050366388193402864204850380728609879198298048731334990048455219406573\n  4654155537801466230578392118511432796651242618604478370665694246510969746211106625572671764171963200\n  0060679461544447383009587849363123252352851899857198091600068141919186168389015181248046434719012840\n  0070704117380054024841599367102849240755930396348724030137535199115751180444162615222008808978968333\n  3245220004404297312612251617655694246030207535958932402085289249243527073965651388572918316494763448\n  8104460321439087648326551672987621999736837094585493934338332588462059401572984464297862778628233290\n  6904492327659329244991240461338339690152475856010196827612372034305510897923175286777387820132668450\n  9880718026820392202804849215743424256804673069717712187345608571520356706217008389369827536191719737\n  1079407399906036839520612792285497138600225654467398562769675644776992563009495709270131191929824955\n  7757637508594236914490683476345460439443713186795630258838268179289757907386757743819735208131268068\n  5284194436531551097133568125748283469790178901431827752618088331363997360282959901000051972437701525\n  5864819106123617676411458323693479550647375250340609927897230719508277849700119603131624755510087288\n  5217381291856087677478561960638935124092507858062866821553712362464896932592034892191306713471710997\n  7033736289595978350953252359827128964919871104481561301082918581273929221101792694864281968328624692\n  9210846438959969288165507695822898733723861578329428488075621932309574063083808914628364138116929229\n  0832336756904067876535761639617542666459380243601974719954034836508568871288552924293518679946556844\n  5132086630207489953169878887983908989545654675923206058192261778837661222533547338637096772959302399\n  1180556622809264950044987752773346252173326389389494914654038212432180736158453611404602155525975366\n  7202239198810502846810737704377232931215975362275051572387645294363483879135289887879058215501111042\n  3358451831022761133433580478971414977152515778984829893616449182897931779032646722874941867545326918\n  3640879828266619105953142528663092670701732405950706227386670579287338827184951879760685322806148088\n  1864659328799427797461245295409526712496904410461310739091921123969406835184469699304716866174240505\n  1922297675298529668486734836811625766352554575224403184392246233255616522514104235923273201888336360\n  8901360504726337496205823706184846895299865267466363021958716136936786724835356109940373813996989004\n  4051538895903910328279457281511397587762747445318429305366136379516981727460520885464692320417591143\n  5001350395075348489615692495090020755605575438417029014607818186992492393911943824110025705182138823\n  0098035458587811640045530311277179266614743774837366237460202073538403482309687677893623056167893806\n  7317856631371635387047158740172890527249125208271689304373982296588377632265870582768134735329947863\n  8582774381654779360985613156779341800020147580424559377378303603956313491357634013503034840739927578\n  6595343912755160207530865236538527450378885971248667165003987741926537414501116049507100186493015358\n  2757306955302684228758483403210477930534852209549079257356397702757373204550799101581843679809773130\n  3516449897806847700924124658901717949986390152345242314464073314623970454745260504301874212994382125\n  7064491507354692970932063802903775911881873901579103827946849262860649355770579275356999844748784544\n  8455800506346031019432771827220312508097750299519197688024658963981141533713506843610011310996298251\n  0923400768862681738142858204141106078957011495068943086279652602887953539761168458073043529965627122\n  0921968552522884916973449075278234090379343664317568824083192949783543147314493991484494446342896571\n  7965533285040094675939963594990733864266562187481072632478724304062904946792025384859153980266086302\n  8206837106819258636756161674883003149343012810529959988806188629972368964165204568060779510100917746\n  5730814546919258132731296730255920587165658804203391315397441591728719487570142622214719278911066027\n  5076128944273224291366994665927065725104193631023859817549079869943892438890089393463412138281362194\n  7180798111450300020433901579204393125539951922260908899971256309233027142912501440398187050042025960\n  8780870813586866490177244473695219446703490650223840969305182593996803942103858321601640076947789192\n  4212148954359374400999379643728561303628943116743708946744737971676182086415931683561842400484542707\n  6218560664395978802142164316651900960728174606413768465552889186181960348825852074845556619089693189\n  0551159916269087256988217638846374595506473777391415806674076650097783414934842161844038388310937601\n  5393889363106315487134597252904837036883415016860751585799025411531953560707703814971227446960968940\n  9530526009808174927009219332674213887448974859582609816278112393479338277056197406663789713662110111\n  5062064178327309094386421044341001568487946244696759993524704930849927057311124823975923359898645282\n  7704154827762908516503796081505783509823027587421577959779004592060888004354874347352982814703676657\n  8453926047834167045941769174894680825377283621606685686911351945238338908918911109127985145874140765\n  0285259067209111152799259142128435543975758998522071759099462414469284632686263402158266024982921158\n  6948010765766605491619087786452758667194236834434314341938123350021289777131425000529224971673107771\n  0017168511888229988920847294675210622424553471607991208322047262682159688664508167350961643933992447\n  7511462369670308230209426462536749134703407424587665240882619103362519804641137116122739349796447567\n  0145458128842701067719626329369178482286279120561849828090900732388615464457885782858409709604774411\n  2659161889517766291662527168721718762516513631708979617646484309698655020383274990369013956616772453\n  3477735942841050791076893352387935549818784678123081259581976513263542563940234617028903607081664241\n  7750144015178987133940719540680368401437775382302327416865127331446717927706754152593737093421319759\n  7040931481491994889872286782267469651931566305291459571361839749552474801943392794936563511497990843\n  5426571310201971443459520117787594580375078746251804995052213989814784595033178625784899977510091836\n  7587992192282605503802850781001785441580731247007138124481319901891828791517297480631535418402724973\n  1986676050304698921400122077849186541670628894614373987362169714665740339540354657042071325868663336\n  2792832121561488105450732644643989838002417068492199129748009428508166943564929578343441236526169848\n  2303194094863341021660698828462310983387014189280782073748320543074954164289632481395094558993370449\n  1826186642654150819005827072358841898280998019151035177063881643966427934704377364802695785368103679\n  8665319390376877658266085036871810357283666433650577172278666728793090809972219221888136713093480501\n  0525726415738134064117816210480678714302389166811566310728760536945753778478065058502995269117032333\n  0371671960112352344407475268128928355868286840263257160569745001944449517018066181081906441054552466\n  2199746055108376658288581298144515267490380226956781150070305237616097616075164743583933410407798055\n  7722934775991343313672159786610550734227837116776183199485930275857261397058658470986866795339609462\n  9188678055717113687861007855007438818571064126920509669914928942274974254510850292688489395447482286\n  3067499394273403248683744914556473583037878860598475691837004542330128662758579270951067896905333597\n  3429361420032882467148804583531441386307976265974048930871107688512323078607934245122017154558018416\n  9216407608957713287564519943138023272075005128755637620339753300605391520811588010542944317855589339\n  8246356458310469241582866117884901004634140760949982144654146039283751024735058944073491964954037027\n  2245345722012446368700313848339842309183240249015795186593378599282947015985795919685983868598194490\n  5441298097484199553689636996354717206181813585525926232995399169375917092428613664218558467667720623\n  0544414885826253705320824543744822903027802706575103800171088178328186514598655832587195546458525341\n  9757769782177292361207133364124028163497001437315008855271291758919608289738898020217608210487754500\n  1333613191713197620856414914813796406630406540354290848751446093045428797888157247969800565660799594\n  3883648202831603389466790445113655307314233276057871082079267604395353546642253678185026829228847438\n  6393039583740097385870142651086344620470517584760549904572725750315085058585681974684292904170671661\n  4133188504384698079735601777104811768366410779396794362026848191177314824089976925551288263145278012\n  6438139137569639489110846479984997677906299545449515731787008040712480283337111702642723015442391360\n  2066185340630711308281520749753719314684009710622503719592163865824282289408364927262824559605155252\n  3505912078414670760567587367336189411174276167915553017199436756847928532673226578045593297864425666\n  9444338925456899171225377298404289632547282555336798903507722310316422225593686622402932897079007749\n  6213095713496292896492938787597564476663310010012085380491365778048694771004653842197087555332495654\n  3022798404918623196790625317699314735845280277782058867692232477965323935598599179926338256860793129\n  7153065955394878327773888071369814974640506625175143141064669754807888250621080369303014952360247668\n  7170177830459449398213546668120189155589510932377910663974321717152861012900733351801133111413566846\n  8007910399622453150596207162070402855157026143358103007802778165023775172009678562401690788151274926\n  7410160630231957867333096674195332631791548690087721251730723578980925225302256322654190233991410380\n  3099343538458027068033444271651927725823425369059249275644499599318933730202415613392172868821116886\n  2565852709987290601656571088073894875836169521706209563268246090399618378897872018226870237853568344\n  1810012149346172306767528635990112808891008964737792459795688250073985023807750959129815553066924895\n  3573727641323856684678177814057638772348760403251294676471359436659413455310631406958562634633689731\n  0651638074355343126100690967453765014405198118349235318871940799399909553892895779875047727780327084\n  6609361548855965799697025956232802846174744164826320487241282989494781029882283774618561858232334667\n  1858688349581842191943883222041292566218213616277944900410223801402421658236604363913231229544346569\n  4982722206790823288070241513735241623122747757303256124704268544338532247012797778599783518199543021\n  4875947781607618852708382020848349974712755282025796946996655381939593798289613778443007953018540036\n  9661661157628681207957971615356066202735762672471209934826291145872585661003020261654600684814387146\n  0837279792596145993239211017039733769873495439047451665419547377441161880916700728524973472353480092\n  4594736914410232283436343841037207710013462057946640670753098240855503576886997007848143675510401545\n  3365221491888383202132791737495225085910409412646261587266461619176963173314166337444938488514859513\n  5867901870079581736475850407096563444530063108651340154568645460985779376822846423033101732799271214\n  4695553139665054817276401972657906219538813253509632509474459898910878590169692258198604873251616314\n  8722533208681152503877839030921096397314087014632627748736199925160369035164018132286384101577891383\n  4548208695394911416541921224410372588235373528329662254040539599551254188046955347016927965818084221\n  6911467794957709031814719952242004890588559374644161534909346821095273819069249340125854016212983888\n  2360671129904727853825109322126760086356788729911106064744385406313070269157932911471683574893086073\n  4176203484242255797432510010038643688160552466827732801481669787349633209963417237792378830351660548\n  7167179287400111914472624567124700249762245822402739770702702350323771241691314913084480272640099449\n  7259572092359302306992730005224907365141977781182720305259060505366479310184870828397624359765410245\n  4719021296462440721878685429130719911560221343598109261278099244929883532142115168804430524223133517\n  2036687591092061218171572150132304915038524312760160267807102779059878363028490995133233325655424283\n  2331269708260482841091164629355307970134715999285642688988970076744233464896500451148248944884381190\n  5203162023956125155080114293455938402258904452354916067705752641775197360904402044833678818915689702\n  7789366044998316755033346099743453906679681237983313639844586220491826985980185062808365058175856328\n  2867239702164703792611575436878345664046590607888585936157260733764794736283941894928357605048336449\n  4011349865491208210048132550683756281970256869699549187621976397204502790044667563951193761315600645\n  4486485525074979942085002895444499533574504683662276687208248316413599480307060161182230915617525952\n  8490028995293428737617351026742418815937159948909697922257721440139091272246178883874360805196751530\n  3147911414335732073658590493042773379844712919544464543044009597518309741823376186337811529128015178\n  6636009016476974544958957323146795549938933751394956436260145495926467373472160218853132654468600885\n  3720772213452751031059526253071110235537885691649959116922083888770780517354383985678670150963780886\n  8647575766982532354044245428400882687477770328538261997625425819929342059121797780827787051185845230\n  8972985638768651127507276341003599414660122279489574955920360994603780484838552595991081712362827442\n  0401784980211031762787788750303630226361609766675801060395554799787456998157973342339974244475884531\n  3933453664591755258134755046344267161094890817996895922670464402169176805100590718447352631235416442\n  4864777438787765173853478975014025204069329911353255614813604353296831292899129535615290402759131767\n  7341277704636530852213257548630793354788299638340699937151542249438088240647332631233504613882159479\n  5169175925450984809791108923311377895396640746083457300976511706075241436288346609180038490635692685\n  3296400551653599785791306066404745571908486625041462763357204425087660332076412002768371472025839577\n  5725483081763522817065775941532708326625539109689730585045622593689849897562270215826526528062002518\n  4416489819196909558212078989726717646133800839566487722019320463671881723954704930209279866104118469\n  5704868470049638641259530673766660389421761893875423752240187458159722844252290797737229255101808867\n  3990839885492144913863562538863789161591888424051299819365171369259169577919988494941497711519431575\n  5826307059948575863534749639756855970386267805400720089745025270519397969812529688311916459045209756\n  3052833730948602383296272132256900737675339111682947198127705742624375221375825032008736375320464500\n  0573891793465923557708362204145285013907946406724667360182753798544781407692125608569448105416619567\n  5264750745239025451705310940662636682474575734607040652757535777432010239133411381357750332256114390\n  0976099469521398177028414610884136085659183932993931358081952707069270927607721717779098763854634460\n  2405169049949774757748287300933978940641473694571985048299051348428670709915093304457966391953558914\n  7801094434509827017367724097904948059288384657526908214068409367522488842466125605269509780101260577\n  2822873599379849977045731761175869419846747429048640123199674462226863633260076411070293488972360126\n  2149845968416031874245315843520548918590453569419644606333798849315311695475836111574976677407031544\n  8057897817050457319225881549431143902579345049989550037270423618264568041589970013697709364618431829\n  6660690731354763645120346808804485446394798810546809849670131795494286681388276584446505851797712368\n  1426745854755713822907266346031643813750146542919453599343608206282790725318865751797342457466122502\n  7443019092242962776936653158716809444242786249840749466556352680450276843578211362734069435616425153\n  7923224666458237107932145904446111092210703976045651010128697605935565797997230393938683961799189869\n  1799159386947086324241601016103098873785439567731482972348965947671427213412840043762106602005505662\n  0233395195755864512830241771428237157769328767978452275710423728172468445461622447270366618640546724\n  9250144671204565478357269214470538798054274436506654919003697852300703720061418372571130911168102172\n  2867212589594857460043532950331146957965649006244622695391251125286803782637520834620109193920529940\n  6735316501758378263276410048994464890719508214784102083666996441555489973118544459531232788198843519\n  3646690756191744363874898626362765030272068609251880972360884793801625295039225521028318591195209521\n  6030879709223063182430490513612517852667830989648407626187112119385645233258801563584566325681536597\n  4140063516653852783302799332761818731642928434366351615663255280877405476696700018814831299264949756\n  0617449945560484056516920660629441907471164740575561955183453874064046466344652333203510377844767588\n  5666660901728752098224471156450455672431109195734666267791950351111912484914064555435257725496566392\n  6785221917623854753819710831983228483946922294953737493172577554258096479498589102686359453576135514\n  6603751391496845122967455478424717793060749999248715039173711331059841824004577425759178667121950517\n  4289611967389888904579312607783631612978256941136845078884344497866404495895781779775376331750386865\n  6921432845659076387703508545492288177459213464479036409671937884800156599085262761750977394016437406\n  4232153788341300502620171319759124864587923006850025338135489151319984710933979884365446048272891549\n  7107603731744512609717170621549152309355807845628392179950936649904409609156994214938711242914663120\n  5469132238606335268740464186976497513460031842898257475120258445983103982014060948468707691618383086\n  2387891061468241972832005261503851106819905835176956323656969414236261015215538172503693919882029271\n  3685444010629436726451203334424480829528507786502235886684798729233633452675826546136476448809927763\n  3165502130074494529895433961752661174901691213005810955424491226738528512234383695983978048397524645\n  1012058826742830639996089076557344363448014904882983571898164096451011928985398760882296922643542082\n  4456841236875233258977838524384542275920567609260795846727938663976401333752981741038008397136698750\n  1792518889005096162725302906385122448156294734866718079216757439502335418797146370341359507068879603\n  1015016464474223923286729237172565384290147065906886729406948425427159052053409339014321081313854582\n  5970434858093148550633941870543754820191702268823175109013294136171877005809113345796164220301259802\n  2043107382966864907037504453868442844087909458071383896209544920759961553665571306844046952712994878\n  3097134507882757248448998973497039622465110498777004179371263198665504248264504271322916123093246164\n  1353303916768945148358569270216603190656899930352729669425409329858504714285408386710889273443108736\n  3457002691119243249637729822940094402075202466206644738391720442575483401453940803546273409990964069\n  0720756229073746841311985865787988559142521470803517849673589369335350075446723246131252582687046375\n  6343964639059479070392896125976486670569071815846029936042856641652378271137607745621090317980865717\n  3199934312817969129429620455695201243315446083595765650783244672112585007760996890714299062146372250\n  1837031998516922005081391020537898391562299250064687356797954066278295022474592665617686886293211625\n  6560500845429455903291737200982085881735374687831820644702268612764976090634339415664902642621944959\n  9972627879887420686537748400124027120252747334436166813022720475458702704640986434675736414944556040\n  1804690256490853251672716709512790052393421702743032886141323309616964755602018386215997872360962122\n  7570421099687370007122579942951869630041295418877962872409327846179804864790769989057773388605583824\n  9114228316374869287853814814314622428398496233785577350860511010509261293230994924741892675131618818\n  6207532574038684806964904698279991221611386656638203260191359684025156492479064439833300318078952369\n  6165184056141033843479937617818210047435190907065480640320569117166432209921547124046169424710431522\n  2205104885366382704720835222072281792307724378621462986066830039443184031897119593875880719811504839\n  7750862492845205376609935703511384695978429595440648575150506208497122812336063954148045231830375903\n  9230419312935804702532239639115127937593601514087053514606298995194074575535488686198226932469553821\n  0219472021248849044263655395305394353300405061335996832016669879477207952586691433189909211865226058\n  4960881496268365467234984048143810943198574036837746637093658063733929458794664451682611483334598089\n  4813230142344973630008177003029015416740179574436162018422076053577654231628456427644093755689715537\n  8728695987224574072558628891627542274001393924890937205554561607842415395618839990558247974029707414\n  7881435727079149221043557745460934900573768159682819680197715906457966057549425418144532992479819966\n  5711964551885655656812151334909804658037684761826601373717568372741306170464438082924391653713296382\n  6165307231060682333889999510255307327441209426994137920110104663208749715410587445826115995906877240\n  9428697875946269429880547786077645800522940757030840638516043605931255565855331231165546386554103007\n  2699344773118169078662801195532248099561712788155639351901256077112884694732263635778302596564232697\n  3847446967479381719183498441201028423519219594794118886452077960231343063217174354069248862375881350\n  7950130195421256853896066931254279329444504604143997511059306830758986663120897091786738144310626732\n  8572913524733573733413996498162256056419741787984415602133012302960042148911478485752643862518142961\n  9136898382227494155863957874082378090383414087929764451188880233720098864012236174176430506370381076\n  9278341189017294013294623856393085315322442227688185717288938851686500759048441570973663653939411381\n  4143300708417983117234397432128982693088281790845460835227616883923670670181937790638751868898267898\n  5926122487707255370774680909173812195568154246781758249863590845775282210873370947100534470431626453\n  2650987541870482604085049432894496711511556404503759922183153150621894176807974004026780591637359492\n  3058021891056162459013019130734230922011877489054176347523478720509575083012458009760894490201422832\n  1517081786382971517875410232779377854072683639518037227273990724613281166726202385362958044768744894\n  5589355612941667877115144459521507280112452897838988924398057926113395117163372724763220356134137665\n  5493609107607754288639415375091128355095389101756992734810580205244749886065694140688059815714553496\n  1021164041299207119157382239649687900615771795957511675590848192969043559344490289369648619008661184\n  8364084454709229880820186964350102416589280672893461892128839980588675472338226628746748982760072139\n  6917908199418072364514382989430173553032251147891184679935694376925654535114088246264417878175405852\n  0462752091194551715071532232290031783786392997264579504136224307388747429588420386537963008878284974\n  9101536714044872706052239832746544345293565280769604772215030240603299608201442874066463090243695582\n  2017514819021276959194854806500251596627667211562658270387072145811474469794369850676576882350350632\n  7908552602752457845213931189712195956022277801052170563123963444611270021258672357370900902467406949\n  2576669653047973714276265705359574487908761992997975491547095674568662666933178160269499245637861334\n  5040128648268256454678144257343138486006682679767270827808689640327625941678840571459411480462916488\n  1285200102610561984527854316767343019418002873928094615194818546866310990795150448813365012546122141\n  3542791228391303694726258978002733168003031221980792227233930233396990249323813630178121360113136831\n  0388677339001225252410376288392001146874739783019681516234484584417084711540563067122150252400600956\n  6845020996544235778554788006584453063354586519748517271104686923708210374238344516214463591642683264\n  6976748511916117839341951421626343457280693936967164403452311179813313674725581030233003356470919313\n  1184154932715418721453955008962151995577648095322472817056846283525646275430576200001721499028964513\n  8438331171165858417764510618582508210472454698908552605715433473640776605980218446223023035764928698\n  3535477228669116725509292642349535911297780867067640091417604725110184229542894697242719313957825111\n  7713736466128861099385961544636685556640632424096551152712448740813863395840329068301663750515937889\n  4470032446794442050062323805678075861405161794915675878485475379803613320458867201313746842227773933\n  8301015927873826640352079385737273318787221160069788684910568876737354682071793442051691869120733906\n  0230403595314402484827552498849668639056151812913549133306891980509583195474524347688558773831041434\n  4539933978264379056007932577903268772389335970408929063798623591326882769120482353226853311130949276\n  6145457891114707181678298795487397796649393340499958044511144263787805500618120194285658011511604965\n  9751470936084824478407151016568819151547630853708991777495003154677919940554302384555684329587122807\n  0339303655080520359026902225743269417733783302077850881645997749984355147030418993109278863628555954\n  9866645215146083224327029398653547117146112097864464644325618002352000486416928090125195558796777707\n  1201415854032429272796513998214262542785238361824897440083764657199183395660336509497078523288974588\n  1493347730994863973831820193244687919192275981928705919005907540673571852348118683464347785054157828\n  2244907985840870058612052844716335877723304380827091373968895056845553523261822111023731271368814205\n  8398385474704900053609386576177773048783078559721753881861727200525683687300867217691544126287754950\n  3239222116487221786152262091124259237746705501612558235461544208744584214964776025595727402918471645\n  3158885258827884286855889496508427039429899354427475578488409253424367596461265438109202556299820515\n  4148019374700480357966774587410088413181187258238578544848881668277133032050914804990270633866946909\n  9351248792271005092774614149529146261051764859906929923817599024416187949702356571809514425854995765\n  1792962105674460022141336737548079860359695946856983379772672852875925060444184643577824036237766702\n  9872832370604527442555068151809555888683589147533045701169217308190413682196197924446042649934384845\n  2732374619113711082446433501694801550253284184628733492266134568944139002470663355470788141605485679\n  6686564326698130317836216464658820830050364454812922884964461641012502375768282189455118458059573209\n  0939462064867750938024379128960180082794047481742206332791471284209513701056194327176292868579090949\n  3218055568979066286289154737548673198693738466419585618899770827990016924649425190347377703988630149\n  2011183528372327919965077715581634061761969840722231867827012354034994384291685565051517438377353920\n  3225611599297568796557485637139984984188981872386344774773551501353507919108180826989536012524782547\n  0432140977846932329438014725512584376086099814602199698631548473576292080996702231230779999766892614\n  9370948131311761267250290202511250176953858317579332482374758716019598930968995429457152380277892235\n  6850487641824139102326914916557444484512460830514578741750738717674417355110130764553789788752222185\n  2058613301075912720128415816099012918291185666715739299809291799149161000466033329225776086756566635\n  9653418185422560598843184427218109423181090631060596773327840395059606697721027773614118272064342985\n  3844246587728471851788363375281932542583005499614614837350414191861619862910670638791195176205055641\n  0548148530782364372016539996520950423890411674976436029024341956762244685142089456568032327777818280\n  4023531717271616138474526434256170300403880716888884214757957281324163069397719048693210177484934395\n  2208897797746064132160659123542873066349856495138429915119375415682688046403440740031916487524228128\n  9908496049108875248189766295443946375362198306085302662976776229728237088410640306798395704550798642\n  5562413295697069031260693727227049738584906354811946653533660264315355456127620022454365014092870701\n  0384502494229968246989481931106380584896383496684231546895857394178100478027431024343617063937322667\n  1414047645055320685254527772713379959897191293351095335218376237814482821238983318392269540362944194\n  4477939338629478208565391602768654742216021974541625034794865733087486963621460507966572115585682647\n  1256401983236872218016273702740854612331531487465319393626134387278498409826789986196912202669754590\n  1203347487171527203423784853201997739410893991832399353436083831944835040717016050019719407955692916\n  9441248268460290554602480556637492567690235856549630563054990947383386820022532727510147653820157189\n  6891764386176038466914712705020901016679314353889817992613894958205684315254271733398458496778421955\n  4228496937753821419875398362804151385327095150706778317618492686749245187887825652388078755933987418\n  9923941064660842841595176800291899674460456234768417462843614905240996146091329907825077671729948737\n  9930049706095219029159187881565502948692499482638863968238495608685005799920812591698095762500632522\n  7429775722353244646312991916029527828387808637437948487816007986691844944952033890911819968400143601\n  9370933054722190471786161995211092911279170019766720202163966918422241349535264054150343478493730094\n  8107500099230370915388201550820033012007604036740047502823812172353310546983710100965755488116614281\n  7419714224111146539649408810687135316799674897427937226351358103899882545160553672510213641692900321\n  0731223430072399556914225246430126273566681782285901690339952558864708517542843979342327492533998925\n  8403923207983599325215743584252303743666138993863200080064574750880709379984627470966570809436929936\n  1070027345381568480143981800226497961654983924247214953855166490613388699479448764070625660160551717\n  8911310515789812484067441540438634321808049603577636933696507502496754659653517150085997507640004559\n  5426370119626833504239694093247325407321746536577121897863354556824170391037818242656724415781843849\n  4538256203497811749471046589508232140820478205399922170830963792471914357052689273788296301720459841\n  6396765979399246845120216731557594061085011084015014939584813243143264831706383522933898357328629625\n  0064539653232340901663455349761453977754354551018002272987816661057242312430623503991266927255939838\n  7044682244056902175272089059731403171949939375760651704430817843584689023226409067025582563156527103\n  9919878744996005669653116942017890333193079128764045002452926077757355448308514991216046260407966357\n  0042929414152107851793951248929311310872340368754933321199716941558224225323452699165148427080749649\n  8243209108709130271922073605282398890333776482440248216436744892838932717872463012952137775840656766\n  5034225484479527343892962635217069248295722337237260521214867559012437510688636168620684810753252551\n  9080870082393756679930005256400410568687321345774201100430212747964046267720796028868075453328446116\n  3963670296167636106120956409159039226759772561277082336910179793240276009477905049390594990355097623\n  2855245692014923380389555114536945379896424390775315438661079617254935797164480344612666235380414555\n  7367642625144590571925802222930640330494317739911077459948051848434169030124710528400114530117015926\n  4176031004668798434006763661357541593810739490233845959978566490063310019258076179659274890217308818\n  6545124915610084564921917339841849364007892425340052885127409782607281844993623344396777834164303286\n  1707465557447095887106612285979843832898882778608994982593444570625520846669336207364561329951753464\n  9909660709934312563597490296567184680351887876443719273432284967575348743806058683938732087107123411\n  9603308930602352193502379647530151415937286211822952590670185758559048698103361310619537044107720860\n  2330006694355982298997200389420507124130963301247398988986501613446041636976412991855139856413348024\n  4010903820420980509818816370765602535422885206425047489586808991794668611719325033248230241059805584\n  7663804552137893230572350200971557476025937720767760874681482134522531630208788823985355668408462018\n  8776333889382394005969382347555811966044053660170851554314092863357092159448116017532965834133347177\n  3027110597090517811589017086602990160512479450702430123230670262179701141510682002268139997507258321\n  3035616679491261005420128645322980067268900094820970758541021988488529545960197473063613284296985538\n  5226523816130889665914509124886813125953536296057660319750429504118843939724705360578947986283171400\n  3968480764211909414275681202732454233195931119523950562906226110099643989483816464487458668307548577\n  8532874081993757274852197413718094296777741172223936413560332119093344075567878381130451998451486289\n  8000608483869420621852719280187780424866808029951289703473294463170946003859512545338683557968905846\n  5172300670448889684061086304061213515520387421392844962022257546585820866986406049865542588590814553\n  0994843493842733842178645051398542739742909585700856146256183495270022814173253676539794691275297470\n  1317006383541596544634244968352635059485344744721078056107810829649426478810025979318775639239043291\n  7853276342037522975657527434082950845479470152452608993138857831239117512692255667572885133404397696\n  2540393117493371399449529356801060379694459568597524987726734807907326761824523355212162149680234492\n  9254288655145733756557659455570923953342814246290317278154039983415564198377180189821124760855955518\n  9995062073007140345208155033298149750702442677264360338737539731484313740709266544922952042319900734\n  5946393119965350568073329814865841109199443946272328453677112848473622460633136028591059635237193871\n  6345986963644390685405322319315241354693248757673046338170302944798352260205181494445850496120326909\n  2337527162355133526234320721943009358815033935989744933526957874572783140396703969100170734149325310\n  2206326301692523701801202442268849290981955511719561208381550144858365716651026908664871732381901486\n  0992469913154608200199270504730568876141893298108310235264828108102485450220875722128344134379484999\n  7279202583543417204425984693274091417821439492801799745659873698287428268267484421213715468232751128\n  5341652370316530704325828337211237137609695939937549536223222219746596193325290740424876025138195242\n  6973910175637197534300447961782504311533150675825627353434762525391425152757047878437678852418719663\n  4624199270080257610839274976226365490018653206454995155802908398513272627321967284783025385221904792\n  7868938953878036869931884660310436335243732715469989881118644367011402842620261504738823589974728149\n  3343257065474637022451887289061255030273791902640396577417606898976983456646470520471635921448307099\n  5843064717275076337180207145974456525141885050371637738189029696852844092581931744100555760898502923\n  2710160089825722381739454369852965476949018738404646564373071319590114076131742822038833136029708526\n  1451234907307147624534050245423763666685575740120604059886955630114415443141696986074032207886003132\n  7905539178696741635552402507676530856322427378471497460377840646093468129918719028927597630701598408\n  8778174519269014769103003023497945851100018088660621628680111091511610409832730880899543375511871831\n  7378655877648735885449036687907416918253831330636233820582015488544982788382174243758054923815972964\n  0619631058215167091903263187309338138501130913327709303425112210972155056104913870504262198052602476\n  1160750597103794366477152935349171861250661163673833049956487877936569791129319587827777406010753337\n  2432790009732407256070388800871137309659634457096041175089444791191621745516970964844762046174128154\n  5361284226015513015895258628069570639244435478023905168613385498619266567622760358234985569192248906\n  9011645986609615679554154921575812835409202539317080737814650788320352665134570706553685699281124265\n  6708448017786461497404549211843122762184522441088471507570190883495022437569885049454241057266246094\n  5832095962572872030994776540107398558069966198019534500506514501054924018861089134173060759238439461\n  2465698616056090945417729073640093913219567683643332996199979654243480265694068369867061758741316765\n  0506027135882574433707216458819522613397054520523441280923173065051989954502858538352287378728698291\n  7275807824209826106060901509252110908989964389297862943014111400676287749920781723794746209168998389\n  6189486307730602749102670388394335247424342123671217702461011602406111857168705082440491623894343504\n  7025081364915515510432725074794102473747819226520593355136255301812196424992488212992601774080103719\n  8842125474472160296950027742685077521758669179938013625842241739856076699165432757061230452867280707\n  6318947058954406188421315713800339848740868094144618458542303449514485210539912489324554866593053355\n  8457827714423774338533920824127763216596753832665064306388069556915620262225946941429007998769834420\n  9146999897956832667090414139806863332515652569687878992257432796139643702654314463933379900081985753\n  0797881761337436094839283022338032797320386536462424980551140224692264789315929449180403829836490348\n  8863869756441485560856053717722873714822823686427811365720394749690693723991561003682807514117847378\n  2562212775995916775814038532986888513655232313938431742258535628070191544007763016347647781261324380\n  2484218656698552740076410511901095452898382563484070455808090522147697220428738220206445111655802021\n  5813722046634766333517561799050089778088560093208145417644390323524193973154721892092020247427040585\n  7913543792600976807636298756614782644338926121213456594456801042227616524183764018673453391488079001\n  3636035284321747804016831467261880679364930468658736463114832826980492022787625545401785091774977282\n  9467569293545166609864194814583644478909603830458285369895608066566619036031004530472002422639388157\n  2068674690061929873082248490016816348921255433754447580388736158658859248597558742783859992954170991\n  7225115340254222296922343661777819296533134967477572209784301938184450598507508056494831896792205834\n  3414789051025761749099758200123472441028507941231843760147142137829511021873589939170816868055988133\n  5469913794537831377114135491971243465810931127833266217592227589369934770498435251921073517573702005\n  4573451305873132214384620876027751840534893713237662907112055269490530038882280420480821085192876107\n  6772814548927944032272362841247943192644192430796813703829482005869742015013235319872051992035387731\n  4215882211485974318238790989199325393415037876899596958043272517776898661258893954420139171306418862\n  9510665268960624145208448034034741133148800431386473171584468157548365316705126017466407607280959672\n  1327294224536104266792809469773583638349822811476691695969557327702827912099792608638170176542101511\n  1581109268328748595064626236299259249694378182229169234325485361604152514206369252147745980941988926\n  8147764439053761119174630260741704144922419498001706238668169466079892475169718500094287444466241005\n  8638035586306506360957270979734930709648890760630190792334617019745665624871288498673826785462689451\n  2094622905482754233025173213282785316517586934054111845715104834632832008101152525413119367954561261\n  2161031974278321038795482539174314098770652570060376719683830478692910032674834420668406673515088586\n  0916629765722779969260038682733496418758332118080916861851713459115685089314940448199610725023378967\n  7989918872582686705377574351246508137986281348350664313246627092452365469835174070426513698824143308\n  8355263194547542532484588409399378463186733813366103100581146455151877305014130815666018061132268352\n  9639711462401049831484646043952006163735425846982605212545385915053646201416593061524137743303724644\n  1039759850015689210279093786786031851767240469599157234052900381676072424770169781521486151947462705\n  4614221125691272253815905020395830514685850036024200549094550268261850958754262109739913220950295489\n  5828917423298134315406925757058801573654535178927415271289413143182694769025888547865991968988359990\n  4388542274846947311875197488771215019159190888581326376998121590808969182335059079714874613336803970\n  6350036955539422590734536933263896961623842541047946294837937463813246124082530690269146502151719655\n  2425678847127229752667920280384129661575021846811088693939925268794395032672870087581886104930085975\n  0196928095204823757138945438844241621756626373518033643277401734125942745582026754402788121409286880\n  4120300022706318082593186766481490447257994467045942382811148786117712471299402343531934763897789484\n  4625604174547802052955308150254298015709039238214721457480550269684443809603801644372619530044039908\n  1842658748795326360174773439634741333029275581820008464886098183291707862124370345940428150160414770\n  5818564413222318877939216398896127369924002251605351282937236557373193193898341753843970830903585333\n  0857183693113650370081905654504329842209938149004544540044861822140550605287168313414262789644169533\n  3980296879517536667847550967256739077347181693399759001189891113962465206160718856491192664269401606\n  9590616104437801498666998284332465257608825710108991959111180835030365079742812307093951984025480169\n  4462620592363635107199014815677440001231307254102560560159316840532816997339070715372088090132654154\n  0840848694648513376227482849916127474705322255057918337197829980217375914243447148663438084599101392\n  5549446596674237301191215691048473306980508171297273138066292296784931657070031083055678897912329813\n  0375103174678340112081353091466073367511876218722324789683703827950123954449539675885373844664134720\n  2470015885201761312154814372133479265672244691795625863300306994583628910381264895233888076384381880\n  9211807397927683141230868809469171765526719713411290271581467529442762521329501543011533690389221384\n  1013378832753935920209051942093938979412893807659530870273550773042219114300432566846240722890340217\n  1151273168905339467851873822784851582247048412773926828056517260376445844006828466737354482592496916\n  2142390338893181170113891315019222854107381814522925921851485752524761838480775838298666675567628883\n  1008601526358935863571274217772895154458312934709800847178289672734129037076071597089783899342792625\n  5738188956319405072752087325999456545608586855358263133708493406413934913749179077218228531160094982\n  7036679278923587884316084918389533623615765768334222895927023939153868119581529960664520818861843896\n  9720018935678548949422165123610171847376046060382961644273311730402586998521537216477536320660720612\n  3292932396240780047428067808124542992795093505143976021192911303780217039508295099069944393911955003\n  4072157414801775922997193282716303971339380034926791334165089113946424796613209472508981957237504911\n  3312916698427371148958662864933613397030362471630128321007084152026276899630681896952666694405167511\n  3293786905003412004284173942954144584447541246771850871030194976373064645661863494065661595559022203\n  8813571361768234778463109885474803141607518313054403428112703507195990142030588149232148841293569445\n  2964317031319035779377391901656912577178069851218011520363784718232894953444655146267846820263039666\n  3019906922610623240862574936674402658139719248013316060412804309403011781839533845697347778755496505\n  2267198920398064650880987659599040268354582908404887435901210248570719056955851822996481632457015703\n  7483350716256177878402602480795436431427740975204629600770595232159378392656058476318316453946086912\n  9139029707529324575283112206316530779455997093588019101795478468222029813794967339008709934835236592\n  5215317478091492963595768036416453157419840829497042403902353402659221352598530803324317858577406056\n  9003951749662478311461547074710152410927099019069460555923968305614807726537399849961888020452613695\n  7223089073682258369725346732930434907962315838626126344424086314103499740365508692160500462809793942\n  5957370775224212775596279285841773136930903645943638449398233929185489553676473560878989971977807038\n  6620927463185198508519268526245382587024957380501099381632387082022856447402189035037020515868245711\n  2552023153087809016194370538717681644829394491186589768122858228286305889861029605283254438604524159\n  8879043704773773713685021353938226539490234217108897837100517498175970206868257027259712399904777313\n  3208906742112120082183986777870565629424693820042378134913066630287587520925647732731674636966474625\n  7061200346715640903478963148186821345980612729682565455767498591972867379753810674217385801948693932\n  9232978545561007900054725330516708185495508295733164530389667280573878280582588338674395672132016122\n  3642719023999031850697809484729803770517200091305626967205284316649649046311031340090378152174924340\n  6714466245262478844479703267080920479660215253622977798413035291824916677547333861097577175208925700\n  6270953984192767246810212714644651636182903867855736355070011836724154289540477483432843483747564304\n  5274450680844294328800326353481326604760172142269400349628563970257256283718828008954760238666306549\n  7470453498437664038598946458144805319509199259451498233613653904412316740712966326187042419884078656\n  0346889440980735651117190884162131337038328475271580140233374087460550901973370836047200902016509576\n  6376037863721883200386390086318700252115943278393284792647056206906139403648830945520239437276001155\n  6448767844754083561603998488513772923034323530097939678336983009127779979497170462853141004353493338\n  2267484965817752353127196015906172828462137140103053343920270345130194910703446174565771792191324143\n  7364969396904896573282575669132764531083445687159449900509202240475799421485141392454572532607827164\n  7130569958137234896227241015135814633935985739176240573446271578414318958068767448800803490104731595\n  8190724146417291159828969702593777767500673203833675999208981411198985757705456900880667351053470372\n  1329348905545549720535301055732469661053806609950070275475226267638316527252791548331453619391671955\n  1030251519417178123912448276111453221886677717673417406452378993015037104211023223884776937314255347\n  9838888837413246016948494522990510710895587932162056322085156530074079505592494459743510349190441133\n  7915663666177246177234250577135160442663034312685087965410397347392745290514055124103029836258933623\n  5834267865532047780753909090946014043806764382911478302964651821538618920140071149455186269299132473\n  7572992206115252478291665457569566383251147867252560975782740644380460707154246177387337680719306797\n  1913031072597471709514887374746950349152024257187438661942079828728831057102815793640271463453279847\n  3494139024208229738660143735485609080295713469226533118264067965254434989996978086293470385536157001\n  0379699864618068028932857297252901428290197040501117093960401799400772790730059574064535923916663881\n  1445976418742692009378297052256405569829948514511625396658674223630839350814877821146971451562642183\n  9723245197256393926186481618297743853241064349252541686264352270431372380466259855686036939297507794\n  0069921092726870253264588061666922557296352244204858671812045093427166631890519262450149084600688052\n  2350944434658274022582905129503049799614016607725564487461462709786889732567210192923009824547654380\n  0864374001097572366609241372318680077447626862945263917248970267674567927348695426329629330779938306\n  0695174258956537533033198251374669746258716171967671157859591293894641900519594231162554265589036040\n  4261172499890930640509531999646107199705169382815884249161492363960011138453259171654027649547661729\n  5659031279164951736029421362818726459267767827689602966497224763374234588532554323573191763216539724\n  3501468576239165650433876800210156944358236086348457350102531746380709120581568187968385839451042367\n  9587670566860802659482952325594202921026887529115436922289471789836330628408977303931369921911471481\n  6289438323424291014432554651237764299212082763929737715940641397405209230530964078416316554355424023\n  7060821781822992158282156540176766976612089914480600595299065437623636120263059889510077235755651659\n  2197145167836743551290845111362955595308758670837780019199618165568310045570228278919161302403618351\n  6412231627090454293979674128235084330945220216062668426891971808149654830769221468092724377218327397\n  0929550675247929813115669882315933109698993912254344793577456066112690464296564074054192882264785479\n  7979744559229982135300293155312717617221863197089822353116106940684881575528948162082091816672481312\n  8908104623769907013229353284450081408941518931109879654072146182757480558580243538161513918772004445\n  8506579847920254569441147796639922979053202771302349978644034421824961632018918118043264783111515946\n  8111481647264547761763497871308668875695297626030316668412146343026244079468697828598741839503171394\n  2900135590877225577053738582054889531696018068632325879151070588932716859422071560763890785976077655\n  0843037319077176693145523913518622363114271160854458040847500024799875823005870882654914622078726726\n  8063637453759806741647944848149738923875472845934387527928676644327256479556156983137246251045428885\n  0073348951302504367500924192903435436010856692082942618503883972921380359209785263348133849959272530\n  1325821086087156279941191224265330135185468301475883617271648821814983502877885575396597889061068322\n  2861861952982764025772256605724744655934032528658160143865185373616114163075572970379994466511411405\n  4079427147537781111425513397283496115287533038864432816081165190097196055850403199345652798222234280\n  7299181713054322774875923028252948026550571740861992523706296814981242042637768598819539599684750680\n  1203170391350760070019492084836887963851424058353860689680377544207064271651941908844817749095380525\n  8104482473913499622829643783561309374571147615093589594579265351844458244073484489100939557560229105\n  6062448456125600438212279003427907039318710752380856389211364039358354010582073711565980725630307728\n  2358517313619370779490857099847401336685002084129819112235959696822259645458832143393571194834778926\n  8345889740076030693945402135727476634284866657596679093779764676816301584881677064603897065832759236\n  3081409299550394583781385143772011353236289264203778348412135950821407271208953373316878810000342084\n  0576180389037755660267923579426458250463428582640582466470413641994747054661183354387910763314524200\n  0537808999550347417398247970896323065778806615087882093271595756544842616883205894028796721171980537\n  2836240656118907999138028832094343311246912681414321820670235390665254965636176151324015679568910354\n  8807955825825328000037407243165059153059069416552440264422265534657082709714384284185626503226274931\n  9629589024754165345761282409353540627014400709114820954833364938657662856625027302154425979845382948\n  1913014999381683903264080298234887741471682495878481818005552066910156137025327368239846402589188012\n  0337650092064772911586849770591281425393646332561493813809881934729589219122373029584341575051021773\n  8760027425700671307213271558502718326316567322974165569938789693238288866660475346398736332850561625\n  4877385435688300572624974075468515505447792066495159632292580229326617229622139077254749522646217975\n  4608682099390454206571222320193765629382978088618030619528493132084967387233260394748697307938567850\n  0759409394786742549882024204154706671982406807377080366075125464173710459356950619561033855527322098\n  1093912275466544307152856539660824821860992013074825707698853489469154319716569722476616161766706519\n  8873444896624586286251522253842901560874089954342176951754103353363403734750381964569616208605048641\n  4145849222445318556939210460917094993512309706812433674499298196274387393132097040166953757317336392\n  4066206733660664354609510478033905319817058757712382737802524734990313350046117788777274760720342573\n  1481597071163454090918423175198274427763779402582949213724616142441229924935894614340088093891446700\n  3203465218983727289742397437971531983072961242850269656158846639448405567776686058195053148337097686\n  8517186306676495978906788870683150525108802156270017004232925652577553571474880717033038406465942131\n  3222560288183751881800277819930167409986441062719982527455695968061642301490583712942032835260868134\n  6582068661120881999425608719239598657559906884794479895728471897115760112663523321187199746658400358\n  0218134043653557895102240963230644670362396496910274014153840261860400252104070107826599150449718939\n  4637653897423395944478094125964467938810595401770617103493179060102858481794286927768025160634698186\n  4876158623370152516023637181787999034379595511508651454025879726423200572504444194331712013746825419\n  0708531072152085126939846628017711102642445638079158824956674349287553422153367398007018414596890640\n  6936381641534693733580413486216823628124855196282073725171164471004843392677129047095449821771245997\n  3537949895925018192667009919231981513968720392407813173328822740618348993689159625882779434181259782\n  2374682335655696616170703773942455538602130433493640075319533984910869963335613308498200462205237942\n  1261127386469773435298406141202933574769854283798507314230296086006458390203266832971066474859280280\n  7062228941198468523711846288178252337801817573627386563385765251145897691425173865797681334553312596\n  1089216796759921620047777736601739698157005189305563209347680575208239247093075056486535401470969258\n  6332447535240023579514208088609935236904979271649529733073121762702277582805843309927781993804392172\n  6811176593651677463485868115239136038172399380436191370870417832458368707326879275915124213279306924\n  9368067256716409379581154374100844743180798479818456229533783159209437058598793067431495842128091771\n  4693715998839338365967633328550845214487173498729828022872245972111003370678851957086364693267471590\n  6123201811286192207037816689825406153183076538439839566907198048513952994033311865280881232170777351\n  3270097093437728645069055248320188640544591213111790441279949017804606511934621383518200791941711869\n  4779020864787750881187224477634397287600533491197235765406868201936808677188641543680800990685123604\n  6326960994085099039694836217157071869815680859943192755078361763106352286244358297577723971617124439\n  0007852725787442545538826516658015450494415164016924498904268345734562617340205714011793825315539669\n  1786508532861602277977618284482128672946293714911091163510449320107800723707449634925691218904931357\n  3617672737075794898819870814803294560802701424574027992891569507497718776325901218558321168332456383\n  2463542641366304744206953390687461804874269573082528928549775570446553072537265354490916550585449050\n  0908073608133007772880591762113407812702207157721799184691999647647655001009776601727964696655224452\n  6699337699312900316835211790528327287495447512981340250629138109549668572838779529050442889661515542\n  2823760174491373513862739753898374287836457085777879177722829418378625092628139451414028381810712499\n  3708570349600679768563369686476720810794013433268992292032107971528543223093687838982497846997755897\n  7758416212889666118309718939561805589888734788223858629836061482819706388537663870236997190568879142\n  0015005893278157667955412656153240777511837016662680233363450787841366979508958640285849250404849337\n  9617118032804557079693217083088711762591995943564413971495282622098711793930564122549381874381430808\n  4727553083891726934629489967863754936115462433363099267699468701922308814839034814606660954452470388\n  3761208316514201007631833758934939996200824800998604628306243249049275733571918058260532493551274110\n  7358603022530576982049946002145986397578505832139101615820893810253664043283856221560504818745659654\n  5074877137045502581458868787094158414236369582539050044102606727943451061502477228062235096633157361\n  2514266794341407466520635345465839222611463235578393993709702620191622134738856245398302016554714620\n  8476297265257464268723386362315313553556816636051903571895244664237586619804114480252199013025958934\n  9990701834644312706805990043256138711210450689055750679076762563050384262622513729065225654942654827\n  3213499848416053950047182498565601847314490742691964574526581135702651071623877334688337258997786436\n  7259174115570165529248420631521873791595246448319525159806339460374218673502419803903429172882058569\n  3526786658158201195876069825239649292348914679443084786574974508366962329607901893079624458748437251\n  7492298595716781255748423316730358061373238720790093363369257424578919538675866761134125824716030708\n  9431687496491257167276344430305543587943967279839160550213514833324054482959124012187831340304592944\n  1621292750499845016709464849534409152471837782557600293979425014893421463386758834589638702611272977\n  9481845303444231471312440784982148467358627326536286255010397360301794632125535434232983465042878299\n  2697952507621176604162749698363594996032434957912103000462192014621172228858441330174290915199745617\n  4122142548151012748826300946974835123007217022380251636265424573166829154744421810027776127607297892\n  3682586116206667022106584256981663821798412038784102644877355661996291918779924348976235918131207934\n  2126285808524547143180977676372136458404335992767255515876687292681898646645773718156713727127327069\n  1744607683702302787924243821403830439878125470062137965560074412906471083531304202892912152146345225\n  6753566839681362781899954496762854591729513324623126862712073070316867408660159570991663158646522388\n  7456234496451599074979209945903431392149406798483027225457243051435304549078550468575655985031418630\n  8483486501057512449287567182899127645724607259255296433846454729452076411844381790283425846409298456\n  8121756169389359659757404292955715291507682970780202397891696925219956916743579510728110135844878034\n  7612045865179866632782748015063649022752319205745215355728802481958656569366630546997062951144220612\n  5550456869148032744860281726828102742488640261601893418136540881702751903632798220382703820898351245\n  5779035361653446984428513345483864352548108312849983289418172916120839071390684868789213810103679650\n  4435251204222146561436472201498942002143834420124097014662363438582726929610862525525118921290714836\n  0456679559516865330531054510197832165741762682855934691871492472425479123271529093087674353283875056\n  3162595363919968592580225709413045416467857239737626687111622820934741373839530974538562283954012484\n  7808174876622182715157013569546601451452768614882194513411059801959086376897851029047454766574382151\n  8113451025024651282130788257311518251357320827342206955041620563142444929775785418104799619444293639\n  4669739813593669111845157777992643506435444778907866885667636555675101330203920641099446748697238001\n  8901857712373933385189115176152917903357035783597959554448978594989542466471543277067082726518943783\n  7948064033422143377240478678694063066207205650277370025852374393455794943717575948222394848213090905\n  3923116986640964837350683077249445046879290633705387963710117044090375203852640296257030044175089847\n  8007785474006909831594109288735871895339473582884735120247775144152864143330152376020257165466393135\n  1516958028866473153834042344370579637648669804291749897294330983715121568619296541976790875435900658\n  8519119491014260755969465368844561880990145071492835593653328658780734465634881032988679671646781357\n  3843886039356754812673163834632608152226774336103425627990445807102437290860556394198440975135534819\n  3689894438585629536549986258860485713492088747953260910977030346501294040228602836133422350547868311\n  7531048043788706828828150004082704666900724460766081328348616471638169678446051551761653711887635152\n  3592785897555315812735391683028019688722025518660905434784145591634664587131734675240423205137846651\n  4548485210827433728001348672450682567941253261976165988765239668887392524079984935281412709665420506\n  9769479109091969184310175731322507064339087907860867329003063983535165159800074053082689602417037023\n  2670697644702976026046981576139529220964311841219908124432974534969714035525042861389842059873557626\n  5543534721231099641807557394304984758358977867534082777525594534690720294929013861369117193813173601\n  6464766254974355119237231903375664039955424477839442983518287742464123279166224872611661531195565153\n  1837930374483071056491908637692464303925333281823210265162984382479889408161531526098178358205420475\n  7574239190790661089061726333635275358836728525323566999568627018308121674052801800025536899293369386\n  7881167440777299165427880446784135620093629755456915180767133129637553148165799090729310413796284759\n  9417790724890998839946581298870509883672688417262456006546811448063717429508458798293125338228957064\n  2635558951957479210047487800990674713490817711659702787400484855846184436218804559755361397818771100\n  1600120973806585206022746739843219801950690953316230458982917616258601136021828935305946736287128555\n  7042048740358073801752241601053644920727003135873627446547077793526648446408067183202372794201434472\n  3474168049821435321906618542992546902783902394693675658550471520114175000886374437528098633553566630\n  5314474278010855994616123990295628653163830851747979431177026166211075066725911367956573126107906874\n  2527132102089342043068644265621908898010268788167758633391987936068177968001520738645811186433222300\n  2760660979237284918816522192627682090188547803894435603204243307256873460617370232452680436617589619\n  9744461169110304860590553199705636008633935746768254932730261029297265221999701378474566833692781960\n  3268412053872503967733874100943023310659498597575628944088749450232447104514115759283854319043656099\n  7944177869456505908673727940501810358913300780225183670471294785839325894520337371154096525172614324\n  5821365109492864963727906756677570290788108245219873727940381999502492852736340743617223491460131337\n  4188261577753944998175824449373817062049505167229424285374716677617880644347567422409659208038034162\n  7847256942682902292521252384858533734791367159246949973608350100908415999161378048415807766179309191\n  5947188569099610232560063679650977588295435738186298518032859284770413724366489514614505019206944691\n  0055451753162806533052264007677708933108986747592363114249211964737983859542557785447923057506806386\n  1269020901325063079395192221338609185950651259496621115675247703172613236327036342371720466923617527\n  2964371717948451046238560425822273820574669416399792178115941355964646929848306709201425779742380093\n  5295307642131187963032500338498464286036340724983128555939809627486824431957818590388875500902591367\n  5504375891472026058362137766642009090107059305338719095934833833029991281661449330234883242862780945\n  0374459419962277192591212973961871592020847315534698082291794557411069295622770746468292250640769884\n  4047590191734774146649892635236134717021650665605904732803649682439836851481673729696986157231072880\n  5030865542054653459983217996813769385218793864713741529934848299188089577576066975496074257348997204\n  9994459247477655065588130988577915322125348254266184290083358153300425533240532142124836043612819221\n  7295783844480015460029895050118238964630978560709107880102649379376565094718793225833884460889554615\n  2946266400196083891130912856890749524410992955918508708629877492462935098430541631892065189010221083\n  6873850768604495583670088449719941471180764413202319502904398729819740588179575559249432469415479940\n  5009578634649107893595827727866007415601127758927156974669185672088046158595689739292346460865182597\n  3480987627803273578312282423971491807934995218964891498748911954466018464859793933432798169521734810\n  4730074648312530680755197063807910667955898766453000450685243345844501419438076057321597242893329409\n  5357769028928132730950373344137444842404965267264912307457602800339029746726007190696517893056846085\n  7048624192192189552950120649938297904522189071154499699379144340897775117026140825840144415357391257\n  5268782112047795676433288753969726244731879032952501475268642593745614354879964023555025562412865641\n  8887114956390547794276858725041127991197852527863555532605490775416372818787942166756748578561416230\n  4336382407650378801560198809577238048798808776868188531550715521356754582486210745365289042299172215\n  6412432965485960404760340108960793000197018816034018706687673493011680676253758341019449395995975179\n  9294529013819672487642943530349403840454890206908114517035801938191590053992538549904281164432095981\n  0429725600989398297814280181586790336160128834089182426560769657275476319967224533077566356514988924\n  0332801785290967159121559220796605920051664715113084015747198573315595081493132744386096777289684562\n  8669479813650313566094452938685876216472384194726675264827978036461664616546009384320096386651058793\n  8358408749636141970634373244074406175963950405430230842045311689261869054774551230814292867131454787\n  2493672262714019480580720895607295402660357300016591846228694429707353592797791351415457236366805613\n  5103373594160579869350944593076459253643501294918340746568221068024329544721198860420889704487725978\n  5222935514414359586661710840576191296480249689572963361908106473429291580124923341595072790860874734\n  7297779283102211703600785545769509313647869059130192897508136820693747662440979739060858195703694795\n  6217339092242356878719544888707655404175386489494700125053265954906591158579312704816593456876477106\n  1383451657286356567308144810722413625202977151230115216366436175554153777313531260736738451161060841\n  5135837496499914467183123847817266127832291011902305693426788974768845305927887905349031050776142554\n  2996293875484175196399791206714877105669967322253891393223401564458501503835897166317796965033760872\n  6334162566515216857077375304022479440398754569309976118475950363021128888392344959267003790422257102\n  8065129805454695532114953758276649718670663197079169226050790892188740761776634726929343000028544451\n  7296016471890156412069943099861693668518983340105486629594899465690353605541570293708695036832258132\n  3917400113357891228386438186621427639112016762850917015801323940797165867875199335922606774097310151\n  1742268902396322001301650111700896408566091596419960202060399859516759933616460872516105373830608301\n  3854701146917863353802341074177249771296949823893347460978146663308890623941931970797684886220394489\n  6652185530855371967667509635988051779747261793032691283182674862057809265256529034280190882705901405\n  4663747001383302588936160171501548886893591056944044972172021139245648474988858366001193030933405042\n  4819094808467898760038276692181719086769660182978203559920718977804292361836630667945726051889605382\n  3472875932823011951586555180178283133565830986137316525935030805823962559082865729213865472195779312\n  2433591473237524037869082536021646294813204884573987051367246382465059987311460376225349778221030101\n  4542987511382244821367352673721070466677797424225083858464887294909600521861477477151996602465522606\n  9621270620854168787239515997826861207922328864955994712943920009967608462614452966881819111809448899\n  1955881471379931481529329582516076010711662495155659372028930345139657761202158250017927165821147493\n  9898252164131398331629215911678786311490350370804672911346756645736776031670447118722869777749372049\n  8411552534228368936469948659928163890293333295967050233310631864547159461989211746960440747930112114\n  1664974922769663879341360554362801356521885916919160126501703473492198577912155996554507884590280024\n  1979283614688616696872940673265794485514121029331647678050432030238929162094969940946268112688477619\n  4192988872830204532548355595645610497507526105244255809386273420635892776828442281295814647347367073\n  6225597282943726377487768399286376323453936634450584640322202749734150248757659910215195448391414894\n  5282238326814839805199707655926889831544715769511831555106187300676856804057123078324335686278130316\n  9868434085520815414852556772088289519403587858372024544781686346084119703605994692042050223895050999\n  0547462252473281286675507560592665702381967985443697384303634755135301014223131859665983550172909122\n  6635606839627244308404652362865284232381423499086766091580811529985673188270001310938215761913296593\n  1457997811998234263059141198338941256260215214745561859783940816914555513000175131020838255631736162\n  1545903512910618001537992129948114092826421522700318799959583363724143264712437805197524452586298660\n  9139765363120503485519687014261642737394425538704104093401178690284831732444669643839274132175880980\n  0049498861502455683932136997226039513159990952783701454801275952792565706687603394301212911978505936\n  5743941306541784682021900338105036071495296968271934082499540824216163965539009310071446388762031349\n  1340775627556205877748079843945811949518820071320525940334421340012436887461101510266689010672516105\n  8423245264855139823924004357219566830736578634636284713947718760514239870777535371198854467657293463\n  5846988478103391466784785470873151504290874245923946132610892919503710118254923184207210437942006267\n  2244936264350959550337583817195105443116873279605675329829161312575435682524564650081228052263681461\n  1597532119917066036435974480828856219322673936865606254293822490061995607753330652464844307273487208\n  8797672926968147974853263746082115171227217434461213726243363240118432918898637112347583073897410591\n  6818188166895595371823995831091589558651551079391105153715928239197272385189345950241777905515151572\n  6497570872428767944097314530204095907691738750096132648370745595341535133134490003875280310133785644\n  1911474235022452362008865534205354859562097776348591737878062122554402259252738483077651799963738230\n  0909619759380174752578307961563233626646373083895738467111670927506441574763282421096818667021420776\n  3268375526077611108988944964673277534390149108961636184144351402764581222896050603815546531573231035\n  9157359227589113492569009356071479776887007319541022834271748757490709187163047623887234096963025340\n  7824746509725002722414526033508279170509524408937573333123198203021541635078677826550932171378171231\n  3716114212318124408063309815360743763950265425574723877774795160370760254863489482815303352021941346\n  4669637514327152808029100281629344182641082759195249518173693711365151453769757463035503968815577039\n  3898348715498840132387691533308860839615203879265983426272431774927686269635413106846562448434931165\n  0896687484469347103405348229548440424944548029015008712091167917658606527872481257977534747880316689\n  0035108745856817454970704973599571133983455436889482161005371526145300563991242445399625803132802285\n  7815556753370517961433593548312607199002585111086675429079991703537006064368388657603432842134674936\n  3284798134599509524459413666885886365358016564396724558897521380576361590214842158335086871769121384\n  5760044375608187454847305378791606854309384081019497206105993813537730874309360802543746183604369148\n  7411272220989011476728779478953951733778941126562046748007712938053458407655616163671403281364506738\n  9621785209078922246439167986043804019848760595357572978480805364654179647434163208018815226299727917\n  5361841901057253910235261006661285793861284828721151144331217481644040056183601867286327932539692823\n  2426014000725989950970512646811985138070288116929747036513882781618018114314687279332331454315102504\n  8027376973590692969718888934545315353695151898759688924675788779434750697095948389187091999856782139\n  0784326370316579878408076134700595423153306313562919723476311123701263743716988364569939180204023601\n  7065484741044827168499151197376191570800687543188967229491535191956193124787701048836490034307122021\n  6932716448737890748697168890556697893495574826859945388159342379901066924553808660356930934748516271\n  9970008372666259460916369119186683408760398160534571873044883787844599456410661946492827902987144851\n  3829662277069771018679726274836234505524986843346217582535199489358389264000821604257858150101486886\n  9194413913566869688314459862119923349722584933741055324623722317841154042257919783776260572497686118\n  0888568657979800450074365599616849105084972307353455998115616755131668419573344751329229644291365157\n  9966325538347945076610328968486987628172465341810383001694345217588085496074784900756730397047497994\n  1243512618421371502775616682736902616881508892134935073218269322806605182315763054160723036713898748\n  3779334050158419807105831531091345171439567188012503059886950631165440619618064708073612376753683950\n  2282439875286051051135181419197379569469363868127453165281063503834682835738440551422934800799366821\n  0804493606862164600676634483031922495893155954045816949724136805749636567933079196367152569807186187\n  4731197459621434447874538755676792302136148597286303389418237450498917697400714288423976680628317290\n  1190857403250338545222354033759894400897932960374120546035438418200763258809362869789359558085094975\n  6506799535033458370680057239672681329462140754013128286368823074537737549664487670662370586745285605\n  2628768437103120859783070774298894233319665993370672470968952524985445820981439492120793934365568025\n  6945592260893704379680883059217354990280818723942350083166725862989891886521707048580918439451741645\n  6009022597384114577622103057688690926001961997563649835723155371164800780419034073499583084414551229\n  4281776021521049358131823966276787157371499828414080368819714227388302087450157398585239725106689569\n  9623496283549272734508268912027147525704270506111845946471828532054542723345159408698624119906327074\n  6182667956011701275258350864738849204602785712850234784675339031318786296649552070645507689584383918\n  6767906678569477562130037760802451808273452521432055160633150403699415486061306759533659716800235921\n  6089478140468185331471060954683369162184806558707134105519361745103710159921613619950970865013778053\n  3897593988366937873954822789683336138162870025109398023076921640166695991773931224839082644791280998\n  5780640532434091371862188532304910289011371610830868087486723811585974218156537092967446551849292875\n  0040651580719202828052992244416273543223825649525174246715774826896121618525639989365694450558351032\n  8185664131997626697439111167780948717936965736903761431922383476655463730888517770884496832380581866\n  1049089021478787690731157126141234536496390084269944708025514624680875023203989773654607133043284170\n  5373441390389323484250318168830269138738845884794203557989165117728792068933863168270043214700842467\n  5785294166046964037538411912376432743868418340633769086563342469199412844660048651217780432768985518\n  4022775180987901106967645819095323132112878909014976869469812633598854195455671757126766788371557631\n  2670276152597776992561643721030108499313035437189899247009395752824298729692241071111800967264157307\n  2618623927137157828061141430020171114264825848892720722572122032771300998294999206516489224551883661\n  4215959589128237524836062172044495902485756809969155862344381651671463163310048739229322622194319536\n  5465767781209844862542039608301127767452831340676229436884135422093949607182598326001355753099690969\n  1637349665597450373805541787929382030075698430766954390311872706744220840025986793092414366290522730\n  5487332037499318170389925641616744964935692665215348150771057177730318828452217536385509090287600520\n  7644455852172346692659704934706045532756296067906066323102672442059559496173835522058814667667226152\n  5390990922373470014065613975006335694487509687715208483235189794212322592920100695072008942754098085\n  7268094505906415482184309235205988084931561998371348630863160817753099343135682611939113131975531178\n  7891831559922775024846159670664664052848809211928532569954957327013366289102018529597151020987318184\n  6394428005269519090433002235567601977870530906642648447231165417685422211916748623508214055524163362\n  8561937291560265630374851963379831249371251258466854494417939893950361305635853814653497429452024282\n  8047303931963919665686795097812119450371518494839553461857076075329697620604212644505057272373623975\n  6574400005188506438255472818396964755953980263000973297590967668112501920350862913964308563802687805\n  4242269120670846669566779380842887975906633338519183165807333128864107796998027738812163216461819722\n  9799382327922503439232071557065563693152921882935546190236507169076916658534114162027868814520633343\n  5182444586927795980466279701274348819999836714161593004038549093477123216230853924966881367722657236\n  6504800742866450667231972813565442043144422054427955692892481651067906360543142276229820510603946839\n  0735987427441902527429805800573784246772140507586893275782389649330295393167543655826368293342278667\n  9969086201880895596168898194833665683085048883617646031216687630865949198367526097189379850864296154\n  2780131573884226269097207549301238347693325994685064488503584484386598349300601794354979546847118805\n  8153183483885467009000362390165675090985197438260891762970517516264463210468224004535486063995436349\n  9876179329543924509327532211671851255361710720256583335435269680085114896326771841394897101579682237\n  1232377799817045313497795344097553782240414687831031187320430287713984126674284308300996375651519942\n  5640823532499590528093660801770815480297746804698730184428172248913336690764257349831495301549179718\n  6038684886416413668203152784150730160382876090478550704679705102972376240049732679654044375743461492\n  6309232993953102138573340394654643138039328475460166828945703985202898970561990500585663316810254247\n  9612249799416192380808171869561768335559308203432917111861194066142459302341685892832540228112237514\n  4878383804375333860052459837715219808574847409115965605101261021357390877587448522307072786751026934\n  0595258400443876916608889983769297115767546444686686822582163159384153340218454302004455678786165353\n  8779006847964816115461477425676643466678616571432139560580510685249293020348631118769790675737306130\n  8658049805399624983088516297448323420918709324865566316859988821807634263361803803309370806856552116\n  3083570426598784939627742574272212686526087553770343242797213162471865621815021272100153381435276404\n  4674384081792139852471765606453271666305344360658788502002162008322243397547438846569080848229761095\n  9890936151291814324694190177542972016826029260693628677593944130399807004856247227074616381708027260\n  9324491040716169431127216932459613466992507264935833273692236372077527056795318598698939329745192340\n  6580320289778734716023174722746080557162944886163769004988028768178344620062203271019135123357703649\n  0080845554425576826710914815596736553858259438221951358015637711971679367020622245686348546905987780\n  3465897456584478524088192688309227770546049463556158414097453554239477673427530500839360542653385834\n  2924088679140936814423285879009223052915279991590500906519247441417091004770849988903033856339419441\n  0486439219020225662877398462669712962868737572216188171278212356334904715499470758868040594632498061\n  3245053389545238627255245644008130368634687268413792193795785077498902782431583827323503310967089933\n  0157066419524016404802598619582946661146570878969931266619486819119516889978571382608897201650221151\n  5000045916759183141379528429240162630759069281025915047690687227211554583699847244222110127830084214\n  9489854275989287579626814082842462027344811563776158858566660628707597984538985888539735915067846667\n  7440735588962117649026388773046312288150082414864035251260700750590426855154587308199448361425175009\n  6919881214717769429055846364755781593888066239542018937490840322751020634892328309341028237894088989\n  5317257072781466983925467615050901133856273474822826535359010089528178689238513054833708012163757061\n  8687637859548021488100672071140270517244681807607601299422257578378515262372980443754897446037591002\n  9399148776753477242411230998381469118795725444744960420094875863210496756226171098065703754579778452\n  8755506706813330119403702836846318300506680753062470647522436185743826977839833542129935793422513520\n  3492355031032263242244961884867197753558031652147106199584104062211908359669078979633808121363989284\n  3731074315823093529694423351893330134370824326438532789908261497650024662233601347971746464208079836\n  9546513329453775576622725244620507851699672019899993401013335072075807710403826558364817000188252048\n  7386269472797768681984124497130143674446177383603784505886773104155213802955114829413819681116530162\n  3559891014775948075941177157011650869218541147100498530766154450326362434342050527856128683711788698\n  6242284537112278047537319214048956991086183575809549838444566013084746527651201522516404600863882540\n  8921010246158353618988556156795455594341539377450291006612155870640166529816814549150487091045363602\n  3369626790074204524510787476711108581603883350490730198454596575431151627225013288264132732720045864\n  7504003597538841150858712366767330536716517667235923474108220556620738971458967361244286013184480990\n  0996619418551265914031244826821505050968211722386212311526523007131658654273609247852137350152630873\n  6450420970868697527750651953873468375231671703179386470783338125470305674216067595718124481724154900\n  6779553950339497434406511014026688323398138407299525779426860509803857100388472248482378758702492339\n  2172716067232378375966828065587790533662110909733434199797844334852653243507225336039871946098706430\n  1678895409084338318327380095549056808509279132189616199663626200962269637110459230585985793321394571\n  8121849704692397468471194090316286548267278160233466412458675531537220698657075888456159200392763767\n  6159553914381141064107128036641827384857021316647667552407500949113768318919687594594576779755050543\n  5913958847686279204416073899438660597048755736032076189399290784732570121893863512434504025611153110\n  6159816041062934721259033810339622107691013592064184427275725636244992188419296928450488655716808147\n  6678966093634642719375556300958026571667406069670450700559764523975309356692672134756563223105217097\n  9726788201175673384420258585856309958277223767012426195014021412415170170625748239199375731539805651\n  8447478149788507156871414235362443327302122681085470827797568225700932570140588369636640436028018657\n  3558394491847903362635015543240087944455288584149451156409427092240658840581570274699062826291235403\n  8024579975749327018239144762628671972800674151064615784260870892100884337577739685600881081369285756\n  5080184359309963392248748227346979480784064776775774350810648131138541202668180146216960634863869351\n  8228333021346613369327916859503079924691147833251308207669101517857971695866018579272996719400552366\n  9049880576522883405403829572329495666610618163109789226399407301157002457628374773576308183798161638\n  1190797360315872121983138196203449769816206423985075228327733732583324372882160597886109873551913778\n  5588140372986508381751163266745475940834529696709262816998084488901044363992941713355049172185304441\n  3612755372740438019661670623338297380240490629825860951393502749589875052807206731837864730248913057\n  9054815627366934203153365934803545221237593231989288843748037324107862086056224621755669140664965603\n  2562701524693947009851471160099408912835194756827483296722721766829934944453406790736552541717488658\n  3901039319287413336870559291380027727314775486977554119840138896045288554164615529596730625328830411\n  8555011888298415869115770818537363775060713350543268713538259132850979585614230274360395764960678598\n  0108937955654308759455387321323500760300773010791789640837991887086196320867905115889137412620483854\n  1157848822039592359433270452459141147350780545504033581903384706481014248689197256381168631933216497\n  6298148495396460838748495439694585152579518091162665452367335174501636083335297396558922109211569119\n  7831672918442579257575500403074904666422709066432242851324544080760503099725830217902579218216908237\n  7943883480865654516580322492664139624733960511524759583935636607443829936677311897124381434507144263\n  4906683367462679651448757604216490046578045668108976237352466304486513946482319660407267126392740537\n  1480600202881411947914174210964506313055942410056398778030768315454955071573005820147925159590460246\n  6115178393678560161253240627524204371192506137964850891981909587770580992490842085600103886023943155\n  7064092622965854619405990986964765074089090371020410737732283300019434413131898982911460768793479475\n  6379260766087148325864793093194260650376503122078960597372119426458074333932294645621715299286987757\n  2374421745243510593701522448697613048297775612559901751454759543095729786727400721774104428762419527\n  0575130818896669903902513418046187913963917519996106880395794578140869943557929398861400711417249894\n  6051202315286273269232409802703440393572135190345840288779882338142266098933184966747889266988742745\n  1477269584954658077358949663204319684227293905402342069936593465517594644019356968088757365135655273\n  7827558456003178125785472579739016890446296702126248612178766264775483706533502859187059393901778046\n  4717594243236240820479795837934985204559679902540515940494547744176083957797368673769058556479182794\n  8871367856297647036197192772736875817422061934212158392214716939705250724783165836869092120660602977\n  8144229145154061195058652651412881871106491879697943160479965128847403654083999670832363146792721324\n  4936269857074070471305843482632931884544051058661940375587325025731566527539290215236220741530144657\n  5930722750888326706370582148843196156531041890179125548457874634053818750561404423146119784513097056\n  5453691268255794448780425882950076968232189862623811110723687449921424691504040400313321866823059154\n  3595496718901355903146969137362240776144310312264860376479193926771749354075341625710255887112283009\n  8045539403337048732823588397650909521672656474725802054809063989279095949756542290618460679476258129\n  1478097037557429248089816541744855096727088920335142693606922157665634684417142514188413007346342117\n  7091338849728156826975564830840913326336717247725008190383325739818737436603642934168154160852874645\n  8725565350762115073088506880345696823291535406069272424136126383496243025222734822076674328244625195\n  3438168663298333351231892641537539026898020923069024691880866165342597137031996465636551784185225207\n  7400377550133609358614163704490921998912980817235962029538477316594515932545751276218265882696502308\n  3274877952126416176015483903845869845831937117209368199083288932591601683152378984175095542145657354\n  2447703079868907388542365511940355299976861512185036911858118061965525762964582474395494638849523052\n  2939043192083470040859590624775869267390038385675195963571883814773408191367110130507853555897601972\n  4131868873517693888960920970811996086393237611436761070356756751954509856677260928307830333384947896\n  3026102904982778516773496566301792404581418889016861103714921870755368544212842300294361846299784470\n  9902389209087028258677599793290024068740412895878180015512623850669835207610152581029222069185058987\n  9780761031752744058602314927111485381252502212065908659017820258780104224742644030508149340088935536\n  9942155412427940242883301635560084548061142519736000794683676743928913680375452258525035643374923040\n  6118813478986495017912039521392725893518850322747972830455537783064856392215254818172332080667252766\n  5964316205418059448070937337627385191779318699473024590811653170846477848979352443357203806146987009\n  2327006538735123781189355588073827614313871047732133065852429217695200986522155832270762404786747201\n  8538357834377022350425081424571284375657147968931036341808937329972201918567752838733601339441772638\n  1562202849015960447422841069146815777966019357848536075667691643346140295482150176278079402653275401\n  6988343543419531698259725727032376723271043885021457551160781078490367273413756850547512833318281681\n  8068792348394235790283046532570909969893392931956859422151042753161377858913302623839957249246256520\n  9238098216310022009938517838786291284754647499738084609884915717838740446198137448390687340591284238\n  3139922683550617309537760077334415519711344778011363671293049539990019837057605614721077458334412357\n  5225879819732015437084932129176882040450744949109305178697056711770114196561695487469569955457946649\n  0245988058182052267828055440063055171620109170645496657728091231282730371179344888819275752509942568\n  0572045715600308835125483545318216700312020988817566560248156433398561210335218031222038724546176492\n  7719760756163989992555884482471253975444199575287553381607523828907495794340847840981905049954722349\n  1767808998973555428169119866029105054819004663413715557369930816878792785736669646282662826784498376\n  7811270499161680058808699835076429727402925188906394922183187369232560399158730451177448334267912516\n  8538532935334055740695466163939922312566237332891308244660515960756818641377290495515788532889906154\n  1234378136169948046390831109473541619189442527956102391550363062024648582096751952056686309608898274\n  2416026648684310185357920109341489959132940129700809792093387285245068367706352271937561210705529957\n  7005685216547395630934014599507090684943999526109950370114911485835658403569443924401813758729506682\n  0507129554209918508765071118127238305255094270970180836733246047964391637119624816712878168808667228\n  6327543572199760279585502124996042934207237855661033521342883540324720884075362274770767226570322161\n  4598530848070143271133232795589627033533113301913893098742633572074810144260604122194998739520982043\n  1409400117396015001163746493739333742500935967983549598081681749426411617589002974453790246451001157\n  3256811536605504921822907182084906673068373474135408768646880362810534636606363963705084006032259444\n  2368068407010904147914080743724325375420452945492320548854094472777330867728957284483519930624062333\n  6014894657010295372769319239800791374246128988062094042510718216870035418271782469358852896936838712\n  3395081807112652032316069421394350441642211804586597284701987470587704917452361406216647182684227650\n  4309872213025329208062441013565190192429768319418422479532304887222761999981305934343540963408734149\n  4009836113799290104049021651980016965345105093201186528895001349855481579764869199753554001996239218\n  3037155704956611140749069890614688031627456504309292968564920493914266325600490954672462450603867027\n  7906597782558864298724579515518278895492937913618643354949560747960629939433289895607101850074129740\n  2790275983298534453665473738254430506492187558490547253663137453707765892998875453181707580339014469\n  7612612080121923648496013191453758738420887032773631045444103175204216817020249242468543393848183239\n  7201173367271437591403573249742190766283951872620948773642289035555070995680644813853912139494407699\n  8176571221767587769774137476930080385309241470259267309724342514738979433308220709198444296349368273\n  4555999275654308492145005895949858388972194908048002110310107746945750302798672045602966829024330049\n  0195865656152338506601086085247051259251072368903914426044804191068856917115605546765577541313378467\n  3435728191355792152125244163426728793514579872623606847687942449245432959375932256803824124308040441\n  5170323303546805930255459808401814193883913099131378039516586688564053442504597686306846470385293042\n  2812537128881240638371919682513155064045865821220270334452515002455569718520449427126617557097790765\n  2201631409924345624965823463274199966965919096303150772162295973794133044906912354662899976787063964\n  4275439705307201015678667651462562096649852069770710283319925355222101790715425549106689098901571435\n  2252320882493548326405825443322899338818143324607762021192763535560554018124664011806449074865679249\n  3045753030540635899858103643050669178836044633760072521059307210192292241895322382915890934128228750\n  5109801463162395736714345765411805422274015650441113110505863376808693783303841959694538613373289247\n  1602532229369731322493799729280059926755672479757909534963414170020386634196145344182859054952805340\n  9997763087934339975978910568604133901260650786125608232043804545448631332510663723910133243023185466\n  5265092939118054325741690275954071908417628867735299986425460585144807032455850880023749219853889982\n  5763569046940203693882744668184013998417739780380225429149259195749277317837957450107291618969993288\n  3137541980767264918001306438990549637448406914582846426124204961678749190028707996979188534126248108\n  7950554207435264417947194040344796510910272448179190320555977587738427273813105814360328119623482496\n  8770668087190298872341728952793641870640694846398010895643153523342290031479810166843136947919614720\n  6097308580136150705516651333914433244858694690120492477325571823058188574716991463603187793301384759\n  7598611209617071626757731572976133468570481409796915486001251242060298788553533764784651123129289985\n  2004061054006583425034516346856303094050978983625277393412354469101293626170198997139567103939774531\n  0096305490105448365702167199187220346357563638244111617093788893854939355612500904793637171542240806\n  1034381188603305755612486733268456069417527934409497025997743501467019950271079144783210978457155621\n  8883274107109765306341681297933459346742756707244134694314516216704733767358268531719605428171285887\n  0830159316048841492190324363058050330721966018280900940432717917990576993235443881050324067491860691\n  5784062898734473767092342257822449454348280812656771732125804023869289361125565308204506530663405614\n  9010369686585620638108841621125072437468721892420926302653347648510064882401875311077523879905191475\n  1301701155512593650950277663865604759932677726955347806327049303948934897959809117789256537443265439\n  3742278506271653261710049130127647658588781300480840711844142690290625420067897649616996620372407499\n  9018383924962308016797133423606997570874906266593733463493311747238915673444128676776285007328674289\n  3474298435416914069489814464185413445247285102226600079613809607527010407727596892661516744436606657\n  9171195189270912069311570060784613104860095902797295146546772338319753003929982023067750861479378310\n  3409232516679305885809444971780201240607532058426904533209973279358065620778914455124440482552693035\n  3303513359014814445164701717409678054134220952991809060291260715683392766168926744561155320928000933\n  5523419347624811687507833375052144864123004693591272455168409493435643592020840086639728874526447641\n  6812224319790057403767520411314593569082948636502886651386671870984019126520871938214610496291771605\n  6112413262298472918197350192326469347606735917920473460195021468502042227254990605003905271739830882\n  3934696132954605823559616885961443855177325568257200408640667157261428742158656293653466676503053994\n  3726433777117552486333465468661747102947425707471145240840693574593305810664791058725770870394121595\n  8349720801434732021667320029592177831146547941567632358090159344983934360311394701960236806436471015\n  5265483303322903249484887401748716255541784323459835831317368567411948216488283219830392937820890066\n  6864165635632999002589124253674659874275784244531350568116333665037981361610334287691399779093956537\n  5874699178205295126606543587480249531054620790828692382531734870934885092202989974921677075930466511\n  5811333830478324658453779995964224511055205282259855135799543314078046873828830918171688650474647342\n  0060161594458175927648783175100615405715334080277700173393486915972544835849957031169089050234790041\n  8269611277438910111368249836511243522173294127706038130263418165235751483500779868261068935781083578\n  6811158166380254286394548824474315217144653188212265603371686438855279490837229672715058599839020073\n  7043520451962130066826186389711245753979831674835802866090243753365970379553017428601709822852543466\n  2822605029782281922967974950706846947014111471827123771794543954247545582317637072002093952480305502\n  4861529194258380746445612475663032936211194064385351261733638375785199093033778956350709984872647563\n  2881577185877829735370548456218406166516380521163355359561571365548830402308390484990534640227536350\n  5322131262857984748871208797423919712980651571562251453573762296496995785161894725860193048018878841\n  4077064277898211155038934041729907842887791396031909094756427746282346450496185589571867270893050509\n  9175082590601623035608541002615065995829409418822317117668561034310940901519556035941976295271519144\n  6546570114627356476034166407335530107840661217068804877676582960344592623864758557477341228559099455\n  1261972615033569804674294654465241074799894679978464892745481446292704610242772494517285427202517075\n  1372587973508902883565123730751402162131170264048251331975042822098951384552813626884177326700882525\n  4317243579889892752698716039884633307640274102072542860753914632056334190051780169548164179493173488\n  7812244472518611941008835131375554904941816728642441721880263881656275398573336004110595994336004451\n  0938252578802766481442579095548425763256667686186591270514838980441597550202022308442316481714578201\n  0230876136894006217159186369664756680115058939506917948617938811069135739111929119476457163842439850\n  6767609270156013876254738775551308216149178633110756769969326398363601998430563988679303503631101462\n  1259261823243292023050487397355510388061839630338392022445021877806341801390292508001654765599060390\n  8806917718524407509635151958193085485349436375269314283472601286321556955893475903752173339569860535\n  5818133404046834587120394074492363546970801353967029689205641532705761785074369410421620028138597409\n  9445803948437171223780859161062547291289418501433733201139419237769927284987921679570485720848262117\n  8953745099590160573191451033015921950477998616399735136343018127076636196256421829613557147414196825\n  1977845129239951809480276157790515052996245646768594108003196552477778443101848753683776930481208594\n  9347514957536351908366451038348117838304020087249543294359801839909611614425208081024615483437721590\n  0747465469707895682559178102153564440601396893159844515933212019827378778074605279848063188533935925\n  5326405680475871392736171274390494442064001760465960097267419950111801944219947030763868082018915210\n  6960803373114792754504691807086633068304717712769938884349752036150838640309236770796659624074665303\n  2058855795435358985947775420846585446621311741732136381937611174526719845377107365956594981659688759\n  5352725655305225867778743619699554527008888504312759094143302364295198309281704636367105770040823556\n  2634578787478523448239984694378073980038821035519714677936743948439795042261555530639372957759761213\n  9082829477616090698661599524434740720825487274741637905412032043763264976757883944911594852617550814\n  8236435201449006844903755254950452871127759024402682896602399138122666872871694391424233569071672197\n  4852985490650286693853139002780062228105465949194965767734087173852622258531958476574101365001688354\n  8356236992354401223596936006051229704848086706559828336254616249888405808056838747680592416721489925\n  4667697070427975947074439924019217135876892945577148244404837002827609384443667265579592053332863638\n  2118343620277464608717645601823692049975214261411194950914136593993959888496873253905456168986309629\n  6277455693159627111291389068753371428581683265582291531673412889027734335549344788683553410612823002\n  1846623652602520308299055735996294121284036158487698284476721665060508430933235779163412598672524107\n  4116285556088741764834982071420906963904058285391826216228998268695975949380590488575368152351745149\n  6466142696587956201997664381005061504180068707658470453477147005963307233577907943767064211961192058\n  2425444418641308896296689603339150013243279609922778353395891846625759931945266902421463659868461586\n  5059340714840086040303385526382246381589158118363359664373818562104058201328165698540316735563816301\n  9680564587348039675160571644904016838278201603100326068032668396046855898129134031175368012912557689\n  0009703604992591452651397757729834685305855369363518247572333780440075047551435090756127219522846296\n  0672210621607461237715153711868850400371478628178842646139058053647502894690723928909472263625662125\n  7205691977369329031393413587569782287912428335072502728595632347802504078961201978921641323874369299\n  1691397743472714978009964967297895391487270489581227501458990446238905869642949272303541293353238761\n  8921156458876442971363897816413221384394558034626557913144029141250116885199892287079988203332745885\n  0878739620195842849169998809625666397846140216095059729972870961243304576253129268156432918037383948\n  1915146495291988536197668964987775347004098933337972715949051939180303124409381216360642720597499374\n  3009579616220470674611740857341097442874902407222407192008491185818151812427633852311408809193386990\n  5247375517969791533483698607788473417923759000206964547789804654420961655824545657572601098292794621\n  2016035864590980012146110812974865267664937754855501638009363914403874704406807417307111491203955955\n  6476378636872521258664199651815527268261024910471618972792199637288140577295437189483001292061255825\n  0088095864823435031158427250447144179924088583160443635426313119988381503447473273977326572582918374\n  2486825322133620191484736976267555076004784747507130263315279144246484583105426179273255959789950216\n  3649805680167217023986364221513849136789469665189599636981895289292091091581455804158302963877917869\n  3541218300409986888887076505606757845234883714489299580313972269250026344239337293778361219989460046\n  0805192918157365071406052132436657117486518651095866553176699331817383034483252372392809606769052368\n  5146455827238435892090666957383546278011242910414205647458071394447904816658809815878347299839103102\n  7522874694740469677382116151097247127560918182160321327115448287990220915809954467179102398577577600\n  7593706623699315285106178001622280013068950348282438059889742807809786337323753673875156399625002026\n  8891715608720568198038132159271334649860797832469882632505217246773232158505276772769080739518020633\n  2392022289351307434265978605937025106926387895048939556321921166611355155598132690575754094401663689\n  4260092675520406533365539514595944303364729869725224613028739834973048301961869455565752979106778727\n  7547211347230810666512202661837023659008353118127529782410474176812005473285408824483885466837414233\n  6505912599422868792294835077262714575470462006165094003489129260399554319578326832004035426871828068\n  2549652538315835325773079887414298463873930588432411167585453287548999719550230033835213264235652711\n  0701750793748806830785603325414601943320967706374935741539533003747883990990070253146296598041526455\n  8977993948764754107248509319276032948979171741362137841981035068496164039387135610981878533506494822\n  5067534562645152529774032989275375616918174853755507337163704805113108209276849359945306955812100822\n  8531454181705533962376276768523646265893677373342803558785781280821115743061979155371243564354768881\n  1631808683393775827893152246419954930016978447909000797664761987833614645661921975754528302389984112\n  8019862103849883015774370873841082808014473728766681903237096742894197093402433644581613180747722821\n  3377537599246894948856887259048714181460237646959950801386604347059435174986009052318312201394591848\n  8907530401736869961254394667213996723140303493622862701101830211066751111569744130936944850884308639\n  2094696380055670063404787656103708240980486788426585055996477627529334517217948195455073849381133042\n  3859464446390168372344019907188086077474584650233245520572489711651503735461248395335503707166335469\n  5583359220890033148110931050356252415751554607393244446202438951629450718397676169870974697327731850\n  0836328590628633813257734717679708600828636578477101424365570873713729405753606851996199014232615351\n  9121878183240382660104099322768038702518282689905013928749433754762826805592644380644635852915698379\n  7510240859940571555962016906118060638530479462781011636883711150185564208324098816256980545241961108\n  0501075913425742311627438861264992086892643935521215084790616735964953417920335729931922987009457311\n  9991169784226885366510539372307341483362776594610820275072013548479905377197752110208021488139107284\n  4348389583374523960791312644616573885318211704659936653431264959034724197008910572073105140310031420\n  0160783683427754926384781255572681147907979017869070658706347495144162525321346591354161159377354271\n  1274878442640103209138695354514175104568359401016226775468370908677917638329951341468046889569352868\n  0453620097557985880107544175928524296410275443941749831975845436916715453758318798583064671534276462\n  6016617073652015024125094132891717472435772793642305284204915384313671868862378670068866990269549824\n  2234826535568866776437975758217353681724178526139621292352814651019033040202959808631994332812220298\n  9858917413312941254825530968687233116292184678213100262026568569686333898603114906825151840653582620\n  2849203691108013004510658289976889398622302002987302026668239598343372148343594114186800944102423948\n  0597129516215285958031825836245884073891924717130756271362697428833359520054337402297168977565143850\n  0239796312208322968868544151807687575048509919864160038519290649018781843282607380365794153750889224\n  7333091289023297839157016547098990259096337756258327711521976990127206542767363431443596338669837899\n  0691427314298771210280981354038990518196590257528717110177255359810918897180596906653462252559961087\n  1060290385068261037365951903659809459038756802348958120983781845663284751012262558117615391139727878\n  6965663647603878330958458695212974136021230392623072758316201715327098091760294702138897544744047645\n  3541813844023239519271050083654112614498747762957664613152927304082624646701708792176731621559023521\n  0339715859547058024228382702797149401860222887247744951501920484063908977847063936837638424702769184\n  3714011326399534905539160928436499378627081492308485158569104536572034214111838272419259960984403071\n  5132883908461395367071412105272205061025340510194029407497595745271749295390793858606386322716975883\n  0913157754808342730845003458209437567851176238291813322850072395652673288180902382192834149414495655\n  4284260221379058861020041883391973178632547226069678634981468979548112924564919562757485899108511676\n  6023520108670357206241041911139896508056310177625446789940282116489206299309939504162691936328525056\n  5907122368264291345975000114381266244639619402922612493139664600821783860242226340290988260707141310\n  1340225182292518114507453249611798278098090904059866888739465434533741529283527320684520374228670618\n  0187577441930845756845900830486689521818505462058364007276520648231602447922945765035027161024023604\n  8276091892925914186544310797306158572168975813014599779416671685835670145627974813776287791201997077\n  3376009154885054854373491910724448878268507976727424749887750371695099645685066210523598133155973577\n  0965590640499957013762197929214384231902193401513373371463885699756025752609691992041679698230878351\n  3389340972127413617967133318021610655335147840122718050005605899625441087429177105963861488871216534\n  2027420219400108982349163214334109664552364564157442547616280614994862262819794712099533265692883575\n  7076874231482565476213966576158701886088308735206342138180550809538710626433109792183401239101558732\n  3449789928640434008566433244035520634294570835086745978222019072043491820981652741547556192053287163\n  7706698839126538932588300907859330973252798030071390325461116679061262209148495864246313746047429285\n  1212258409058847153194384311331074768044632952910144117885336084147241830788228795538892654286664484\n  3467401260175278300532377950471739461989498412658617883899732766773092597723637251124093693571530993\n  4453343631595721100047780613195625664941902661002920527566702498156483747966409720938614287428218067\n  1772944466864229698980601045005527182047419353303659476484286197418817359912109181105178317173557233\n  6204876797734979795164258297228610893435015799839631133567144207775122452215944588812353931831789842\n  7767907761957475125202725763459241059992691541859509460537709471536644233681603453774944782038031479\n  9452485419024158225473078010510922138304388873009741595897624392851682724173540249533525649788361744\n  7651981462148737973733502013899631749840480314174733112535768108772820544027530157949921224822818831\n  5859903217642180857611795898305076310457939415167540135991645960889661120356360724099260713876870353\n  5308360231371618275879494370788026235451349994710057516165840831401814160964148485556955730484032393\n  2205248542084091772149915796670505394094970913094260358442410735665967515059412976505726814953177565\n  4706723150313046360845483584572144624672088377626519460492307291085755171808704011926298599674373996\n  6703984299785629244915783679456050193823228919978420229143846192877103398117953279196400870648499992\n  7364161019298282836441987022831823536960133729526964003143205504271571656300347801719246420651854607\n  5681103879480426458869192365485930336260644027694822097406835423424397801948531719202606336030218984\n  9987739570514319242794157428371466917177565362215383803955612588336253255619898881383941315190594078\n  3614415697879733902202666436676056612603417723852733817170074654328762267357799173442064014595759856\n  0581198520436099074878620106330950503989497135317475818349436118333585257563921246465585146177331430\n  0998747082934936630501465316745749214912742258220888494609209423211433462825171607831824274822368063\n  1197587626810722779638741191448120760796135398449987832458778085584707914035804032279332157013895936\n  5817735396784757753859198605907702571498519979291886207175540665044143674061959756902461075245136349\n  6607249358249381528623686592641392363275844595423516530266033702306645558408623065624456971108791978\n  3006102976488461105742426529547417648662520787040049090179046710359849647006034864761711029493672651\n  4970098727032847990599934789281851306023690074930957379371813869516821395468129591464986234149183262\n  0755026387682489509567486763202646934551755102928182498391196467909182393524187155525228632683189420\n  8769977596787361174983485889930089824631185447842241011310191145821330652805811241230053589649036369\n  2652436919364069404865160756328368948571924613377198958925336526525704820267206476980220983714151087\n  4808272712145526565400494632261371175565225578557854386204843972745128112469893039538513275572087385\n  8613633284515498099912162217608194229832953752884308497481526598950959603170767549866453741376304678\n  3260728838516515898281905983662442409841239767543381995641388773390255619104043407092540587331227195\n  1500439073325700740229108927106398570264233945072301662562178032650525080887920390398302390563040930\n  8301813017261457073083950018428619529012573812442180643661159699702227693367937704896765160022948925\n  5184171690301299072120129650133350627007142276635497411119992198196646987095666400665324210039471451\n  7812910000178032454064536894501473949749005669062242571460680569254946226479467048866362893504625320\n  9784701286810903059627837913196010909078160372575988890915668049431931958905969736237831810429437253\n  3961007287257463297767480226244825115785530275005860141541908753722113152887672443495488939371268118\n  2357650797573755918622609547587939006855053792263520713017519988485814137391208239095529104948088632\n  0773452653449560697377315653885478357543068230985809033063451846343524211935900991772519327329122989\n  2982399848033143071342088986768649183176648276455164850978318312757196668594096546739916866673803114\n  2877256054767215666764458975682178499580369793880035091827535854837351023803509660322552556599141555\n  4441736919449621569243311265081247949877523397160098964043204516324156612432501455034316605675360644\n  3540198147107297747801155023230507765864292355729797955055139760232195070145877926441473921211871557\n  5931178810856734946743677579086970048686007610485539674009396682669252994853769134670998340658310623\n  2213642074997103676648809063665818289088678365447656052399611687466435038854549657939336678299942212\n  3905754675789611320021463888751427704284851614103790853626728543299282619009124004269300184230897419\n  4723371882770765364599634437675073059724489094684373350253686017508317203951523600178790732272888524\n  3637033300444409278129059345368663141470104659341883474689282629988236301306013766926988217798851721\n  2454145733784882303824671916659511051746324312790315608741488607081554831102132540133568685405588343\n  1018870889387613937325023408807965938201480483031644811231762015402434502589721776700525987685752911\n  0799488761703346812320199323113219287434184661259987018174656117914611868926837025201652991198988874\n  9488292420616964965430894423463417530646262066320412705247904652222594748526298821801665103773915209\n  5692571767605139151290790833063089131384670767807136082989918994490539984327494024388971060176275164\n  8654324350417468217404772053579072978819030064762179565605159378531746997543678504299622806859383605\n  8350652163718143758120359463898013538578900875386377999442527513971642857645585388150959986542599611\n  1121263525218353737540893838299407147671947955656533381033560920916513587960431756452149002108737452\n  1940701660790742117146389209287184760160902492319110422671510290601789567464238340951983591142408642\n  6457110707485300762498022067363837798445988414775150716229321920310260500551509076978943194378348211\n  2231317197696873083287468383293986801931916537026638200348246498888280099530802191763804197594627304\n  3423705049816862663146331381992449951350409336852132648622166261430456380155416702997567018107991459\n  8371430134003203497652952164385778342024804974604813565562787670014116764532765709159469878574710951\n  7077561758971954701469140528987623863446660752169184051529203706434167143445810148812459041088366769\n  3696301612214043030796233418792780707414554309612195098803307323271225143074674379294908470001118157\n  8721760472562843687444029999034907235233647795614826072754304750733835794169520854118581414211633663\n  3188436139304608640443812030500873747407430351981258795565121015437961854018176835163955314297889210\n  9793350644218922063827926017080859661513409231014455095980500497093334182603462822266136524578624368\n  9338287481808083116632140886018962793337969179670238926003951088492322226248791469952469448221322207\n  1622818763375411744071764408256359777491004984411315866456552169347946993853458952764802986158402264\n  0999942100043342064493941644651586082274972790568046591058023199814041816664689710703815899178259905\n  2443794164767665313637038164955688078417197066690888187111892963554097089449350838086720874087385891\n  6782805784646387301335632900560817556570518689835182885385581894187618464318855418835322055865514919\n  6084013505109130429643867372670176920946256840482169559422438162836317605490729939838290187707137864\n  8219596279582737284384930210765170111412097127189513677811336345225119432564060929092039892030311428\n  6931102996162897157416513531226509765663872541502188189457696063382654025201746274843313786593668353\n  5892728894413722271223237303189976271218756359030552405933440680406716588549910892233951031852280400\n  3163077793139388788124263739945766173505780454864709713365612269105452680323351709465782235132634711\n  9775415664800121647618915383944543827074135711098802738252435819294527063872430289838878623739726994\n  8101909956476339872677974381882407864696372061345750204043865140481454084863722948089187495333684538\n  3329185692611600136090526980748507788080971992207905493846449129981160445105124820157681342303697584\n  5979313525076499172671897835920462441355835396802043901129880820848792705993984520815145552771604555\n  4509166391086146598101094364855299583415894050113221759189182274078858545057370754171980793576571347\n  6422566400785520271235964984181478091852475405178298598358719450900926456203221456793600320098036589\n  1403659248029705970423893401417849408983405889420828137541084532719476594015784918087988412786712883\n  4697304445346330011340784244697467610052163252314696074617972352275188891136610847282504473338769880\n  8997882496174571432653895931989193809453735620069779566007329207375987877395334012242628246381176046\n  6552954932776015165444339879779657596421303648495380297336297340540953656602715666209562420401897254\n  1002690308873068859675832363484860800313674933788046988108179243487055585861260443351113415506834721\n  0280388630798842486479599344269107098070530828950651392898724560947408991150499159326607612639813504\n  1864212683987924382810639019024427167350764624024576817524129773437704721153408616804178294996765068\n  5806251274752995065595324988186611187221699214720955606547552197614550491099906975684236752153392973\n  5597122527571508766565966450271917178205293885109369447210327912997299789495953721796541482204684847\n  1079713315292422565810659649076885751212831515757008915688390775159233949705557155439612034287580617\n  5188670398308678334081013481683943703392193419742431633468771675540102879059518554697024410748369099\n  8853159223576836050185875678557363745857714841063401334897590877749058334553977057953521359016826647\n  7382725085565578135488763598832002785770631642240468395161657169656331177116454122497180862165255308\n  4508026356189132604359629200964032384354637212951594753702934135578205609103465031482793614106566034\n  5442082853716002311366813190919641028730492085004174370383374462810464620942776963785580934275787598\n  7841833340399660193542026714882612819488625539504381515336088819835281749473542529613052058898947452\n  9789819276536230214649271640863202923565929941917524547761440843060223793185676064830394341621875362\n  7041474976139638429863915287083114593851766848536922452479133970185679661898100702047221233180454192\n  3079943922150899183397221294664854266918247805798787826538813387791747999298627164543339304246091128\n  4741410076110542008971258536672836314860898634346456934102417486756764886499932016760769139511745616\n  3032737449804460907809064030467634944431558869897372150230602240876896280899677720082954009728621969\n  3697999085628637818920687343124342519125716658608488533132234261843260558367351735755946247449424091\n  8913520207424891718440223182667020736467686101862473648492758014735888129615711645307777309918790610\n  2988862871493020467922752516710370807163943912374316792866821934446224765726040705459985968287895948\n  1812296099664498418954355051269746222228405582160178156384893241562942941023547244744065298275956508\n  5230803988104176753109539450829566866700980596803972387830710888730991670839909866670302161465717224\n  7840852262333384257208168100733965346032149843206972663930918651492548013701038387054784958056923908\n  0907147014680319441188291677410010867607146367034609701658774793861986557251491603212619971997380349\n  0164842267544912596739312397990074831055385068661830482906443355681392530449017556754977224586553701\n  3114885452145575276500340012894742742237558340321677426586029415028540595957341787349070980159085826\n  5302204657806921368634418238335855058044069078904876946952301682422689530301950384904574094772378584\n  1308094244812638676254526179071856678494915944757525890432985971556253916870664050033869114702527528\n  7746323076394773662205021243171119766975540707333112675955811430766435083776613839374188211987281402\n  4301959257723399249774565359917373704823455256901746838618160590685025236871722925582045471781431991\n  8580749491682119101061410175466753076202891546321342918722601569145323392446783536092923925956317992\n  4773642655885414299302894571429764367323222629236024015550305643202837051864402703207009413308930740\n  7897145934113546630626365872857188977005569179639209408954049496757766916683128261519805386857951638\n  8745693396126973669872220449857426520785733934500552182495973648387278103946120544515637979612030291\n  6594765746993415432710140747457728926544229966008021914307516320121147122336288689110031419826976208\n  1161023720046209913211643260706919886802864097226678090238074035935421449915746197968355714813677142\n  0102843682700410344318799421436138119770538705702515776750087453539287747201965450490621594472377056\n  5106196759999085694877759391491159420150509913677419640531912235392749755102752262125932903159292020\n  6322743156316398835598947694912780282598450835836799862035335202068546055921678655283576498156695323\n  1585885723872988882219155944803787090891648567299072137386053604371214396169103856951761602847570707\n  4122088557445480386155492999601110900895293056150928346650288039831552918890865902817664933855036021\n  1301004261404612185620272908635851705705207750060330829518090619335033657336926887231145986400466223\n  7348473629802877988102147101924585493748777453115962897925405501780747491964778406746552790393195565\n  8138966925439286116812702860780164924717579476900407138384187102292173351898940764080897143188308922\n  1639365968753798701420400378491301275010036189355286464804238014072668778949947024252513956832936672\n  0126727746887603228486942873013499735546344984108290399024614311248528848255524681487627399427149890\n  8989640658846538277748820154989400559486508510846581978619330248608338007255035370575267261626271208\n  9574838570781071679039632140611479857589273165206651387414183990141524080694271641531248414657507367\n  1621014372856615067280484820945901214115397057048462215390455053205451408649083481693367506628520708\n  5044761687047642470629251984218234056711931759773850712138435661612005412914870910999681331855034567\n  5525027394805609455333324261650049742736992368959557120323458164445061839809446368120108418926213314\n  6656721599470819817686659148832682318546016554172883453416704493091663748465689767634231201898326438\n  3910341875841362419674579946492022219798345930565636927568493597776710931030414113073125395642486385\n  0145550075794360426654494747022596898510266337438301815326070463610412035069829100774024752336575842\n  4349259806781961067661254989366947457932038348011891804623993440204860547400539729198870648908353273\n  8462542597815237701653934090663961614181369936262272422063733819843067752648038741771906134560708695\n  1288294213418894326141155983741984309650618079924824859955747397586597917835001625124791176820566112\n  4568789795467228944116120724622182150361118719603867594046340815340520931954899452801363923920455820\n  7050232815917711079086385994326625268337083516221862790696351346100018927287897223967334211224885525\n  3794962334805017456457141696886360100538717492882149746928962534740324906591107947746995501662902714\n  2984650883917957439011915442316633387279050548931573371400843033387711793984550288105152253878558588\n  5276786724654682252601394142126380025151105253620202850883368116711791314535182745826907936214338287\n  3636714785502540618315074263817135131076739357650065187225796621355848452519981400465049664429369446\n  2643253534227048108735843865153165747836934943817561843938910192099339207935917302351336134333617409\n  3788943324363676621020575206404986003394762611773065979007173384350861190466728309191914054876182490\n  3540960361117175873842829531071297887413006781572900718720285253473736830526838820885190065288899206\n  7114141756148218048590301612699363022004245730365450630834445212718140481106462655021833491808728134\n  3170005938945464777807178007554115944795663687523130280968563849766467416423979403809780240068223930\n  4397514877618551014680749244431304936842402797966380697010721859444694667569526315883828526261340027\n  8056513954164726797847201873928734317431956342714686128687031868026805130778331133364970514243458619\n  4339937603831348919536165221985717340060262681642333152627532561526998660446742821000163078713356756\n  4176057061036539724403434996407552391445970004248827807009018247852047697306068182728689501112304020\n  2596546463916882653440624513894380086858263099263707383047836303898086010994899412575125614015344638\n  4423708749095624413019599875638910465209667545877660086590395215269307249475934637655249995739813687\n  0468238357822213502275156277174392239955413454901430780658888714513281337076148502576852323638293314\n  7428059668809646209984224762074394269002794291723758974789327985624247296590853215947205332369490434\n  0279662663074027313164322304712428965781608109046022568044881972470679934948937439150755051735578827\n  3674663011336512806280676387389443510734047785428449458103240215302688926709289273432162228866530807\n  9172552536648253192224860467190401188149796691897238390489921449906378342247258297448757138716393766\n  0383531958221258389950053175670095529364850788840429000362324607985108094470411877669656985270022423\n  6542148408230742496591289909650888536308725432732151415989181628756781130705162568510558151267135934\n  4832178026783508960472580054261710332895188363891032447371674832059178733650962829745596943462409255\n  6528166566428133690259307587404400234673137376777924867261026258403688081693860941830435421605123289\n  9431137753391065117317425791903877442755577466603040662009904063042605149202987043184601327389509099\n  8152703064336944690410044571202235451171011328756403959370242331710298393490082072739036495979673246\n  0701174416574343254996117806917646759647468797915155727815162473060583345263648512898167784698088189\n  9113210039395551118696836023267657819460839277758877356094075598291775428086114543301395004552465512\n  4291004911372885966068671895355711890373330064908975683351650049482437502013368515728499636967464259\n  1495360373941154960982344314351093202218097093597803295497595988950811043501360621642003040542535251\n  8200915587623321754421758808594192994016616000363439101534009403986138161418529659189582746862217600\n  4007540224052349144874115414450603504256362329696036597208236492559421476520771374574795122002325330\n  7577273544066672546063855660020024685704460037275403923296087432532813924489275962636999746081980307\n  6121586944368125434647600582345170986588687578964346022705480070837900413305141721926594157615687911\n  5019134029748585051714860817315609739898187117889639975438593851481271228565920278693528607609610014\n  5004686282143308100288003423799080316038850406082976294182308278380860352272498102367705906046463477\n  3095240249025118717986424339190253045895732039085850787195225501777037652162664218528198174050734002\n  6663725152809340520811671011269698677937225985693349519432693201259024230765182777135271884472532778\n  0205511448358644478230115471184418352293251149325726988617491226032840207277788433002018243512889526\n  2643485040180117669218940030138462303925595731289815372438169530773158947855646025489012335984452603\n  0584211078366417704984380422727756181463614970822052978940468419642105195952976344279449380087623752\n  7458736540436860323925681203968153978062031844117517340635496464494688643129005659923971039802605527\n  1913444121764931576701250232821586829133991709434721860199061499472704193722324481136577736478433420\n  2259996962798552988234835813451982181425675924349886313315764355498522016187470094484862457290141545\n  5918948887077304374958672079248383857434010982500628961660799710944183699874784439567679292388862416\n  0244369027154652760022493934903690547167448296577083073924210015283272337960935692399033882446560129\n  8007919176430314202194237399396437444250881398720311047330446839944062988196979371975773532541936499\n  9703329803095057301944905176813411652445359329905152911986147095703537452655787424518568889601351304\n  4654670270758809946090330183569536601327917187944495410156034369228648022224704476758696090322096842\n  2563613405634836829717434394913450350154562712113070691281968263867332213184044441497703738450944461\n  7548305453689936068205803889877247411952389292421637467845624985427985031449329953315855430027667154\n  0262962651669580914607881017471430699174419986584732904016553566585762630805024149558847753348985236\n  4672238934163656532479436451005902522586321364641258499846796161843552340352324721110521226636091573\n  6027130213294482089766141037807091936558026221817849571220758511904228780008745928677362763323009690\n  4378031370895252076667175727182998614393655511837166922372541946679808216666811103956604393375037280\n  7554514848068166043674678943264045371156658637505315120812713275492053068222000525692985014308858791\n  8383385888272261667756834554600420387321665037563085408359999738344203187925351510988383385390032909\n  6587405487398852972968379972293660129231230716020550973393093605034590395514435053077998616792471614\n  4327074762450851301978973869927099332578952464554750676366826464527152552254333880535483627391626239\n  2529667664587548946734475772733560138382737290053938966565922305985710484827743980497205838211155382\n  0098920966136946893177199111474717037337482698105962706129131399606088218772148525578898249605715119\n  7409955071399286692015456583834310142603080858688493271922984158950926435718314092471047051845128758\n  6998841092873590287431203934376279851641103244122629263110011096914955445030945335769214098033156765\n  4806421257727767562525366210180850636818295792871608398234021472035362598206364552008523128058003267\n  1686683448151104637370484997348399072102721190358008843242221164334445080022597795281797172269973237\n  4386451794698445764806394894918334385251804287869326327529024478904759379404285984527499222779721000\n  2389112154893838239138287298993173119476173906115044782792876911023764755025225717321948181473706301\n  3088417889819598162999541083390244410692706737595956997119535930938496110286574076506367694490893018\n  5586498703728972723433457224927891532609223247702287726296424917698080302782362172393798854005036257\n  1554887536100890114568649828243767815051248282055049206761472527146521896630049688579599767752259397\n  4060305110289858039626218819712821705192632230895174681586477249400663476252399854173196026161036924\n  1957159776019716949023993287274397465880436565936496880168528639775155224759997649418595026804050064\n  0969843511307379711044119791800574646549307802152125298100873140604694735659064689241814839126360000\n  7362471055648198258938088745764536277429937681358765419179735722961270008929684713696493683678963525\n  1823038913103992633758596525796164964499089095524355086589025530278599077553259012730600235531124137\n  2288339546404865777833161576829861517865092413747423720887013088054395225927885302394309216595649098\n  4077060959426129628247967788111335332629528747975409878835566787900429195451576744148678404482363922\n  3350956600727547939140169710723185824412798923388200237794063975753657251625013351636726443591597747\n  5061192571301623009093734510047452761801638070967737009437680596671422941358960082475538324597480393\n  2060796044905017692070585123672619845895683093796806254340250957462165951887975505779654919550494928\n  6712332513375567387160573563800289429902488512188012405686792361892475560482487495532826387314646416\n  4205988538514774334331725912973171197400042649872224381061421103274992413637133754743240629667251815\n  6579138643702562024303964790489005044298526244657566236218820854094942368505732727377622836552938642\n  1319461785260626049990625479688474585304413059373947277930775350781935576273441069215589407275736285\n  9694496638890921585132706101710614979762053857085281209575276329498576677719475935215242167687786817\n  3437055674237402436509635179971533020571431114640135864028290245151732610767169202252500633762431074\n  1617874762431101802901331809722311238240044665270255791343338648233847824083641509142630321466554736\n  6175962561696659433120665985127670461450435565056763231927238034514025354212809618536406586065956865\n  0090054298405004609354853062062677047658456432303555796213970401284145071551329589154551669286582783\n  8940339152992238823329025388857260584924330742050480774965818966106091810585454197932480203796556828\n  0399926145969205463805877136490314877440480911274281654824191745721110244974231615616924754790847307\n  5166326609819523795676463876788253431508822081795667477147068016351059647568318898324971204609208556\n  9971337574144650469347830224327100384214768793221424857135656462834010324241282632765420816089448070\n  1691549541907889908583899738707067015416665338419583507169714519341920374457438205104077772973273608\n  3932416374562858922413376538636749550495430566377084345083651770046466463815328674448226290496018468\n  6050368834407760844823970025677621323572137726913923930959252379422056676983704392607890348267373475\n  4528332857659917761012569555350192620551799398021571031241431145302306985898701030358942128852315150\n  6444142065284953493622024421560328509445445462874140740184508573337343507763059426122501925255325129\n  9186342147658214038307979527387376105273026392418224264154215090646009883184415256430726001468614601\n  1619491302403669382475017141894225920208067077454915759538454237813886087021786642478602868245538257\n  0607007852827332226510563344566490874361582295226450690960831695617260526525349150207041380219034005\n  7017883118312374199817868723882510105974751202349065416840157335014317837335248193861982871799710861\n  1704819560792586428195619770249670042110009538004738803920047245467873090629279686005426820228388866\n  8402908313352076886505277918656290128921312403151147840465000757126177971158769600362591788995845532\n  0352877641847839786316650707375096690883613167391476683106804830017611360594125583902618497547666962\n  1728534035859219034523767151164313372600671055941435933213580593431965154632317833809081857823319571\n  6802322563645435465739653891585126961726835665295452993366536165073980298734018388646124416365174666\n  6698938924827378264542631427203865011755309707615587334543102676089168151624212648705807750635927882\n  0073571778056908881607984334565970610092424036098417826254172021527883071915797667428851450587738133\n  7614484000839126439568917135693227613352816047973256116480024364781339419493919981444634503389773048\n  3079017221897876114152675849137827671364048145222417009763802459275416672698590142034111588045151837\n  9364707694489921651958233263828168333632551302342635169444008445773426489193207412771550956432261038\n  6891038570095852192162848418489882732686554704236675275075298431229087305419839504408942021416678082\n  1968098279767077492898497124238809335414495108294256297327826692300410116180647868542163393012745589\n  2232424786749160761576954116883021345421715965846090848019719649487228542292491332269577189910652192\n  6823520973428529362798860921167917076294858474961499783598343087200700477102185689744126172310910355\n  8622624994683902497802482310610773890804303172905984770452243032100330495756965955759098089718773551\n  3274829633988645718778469106403556448961252735144868231053002778188431067681436348836868815197935919\n  4805864518378586597310271207805878176828347642204580417485465272557925932127542209355067091521746074\n  1863450104795444847280432287590427853279892586453224298523386332572078549434410071304918160075095719\n  8178380956000287475827557145959121423798241034420119904298000834846679847791736676339167559812330736\n  0449981783300027146207947153962607424019051778269682879307334273726355455968205132147577968851655215\n  7856382150610037574421068786981759087972310547187859794509341635317309713427557368480465493684608589\n  3279519387805483535183845795512788897107538526481259181979522714467314889783066814412948090438764754\n  1720328836793153948731927842820614083782111123855185925737202642344646616985206338453406008552668716\n  9998825468531836845011643354224246766319745613460084963085605745373590303320585846047421171983158007\n  2893001356115756207174231489330479644746806496381293164292352358113902966994946800145068838572950498\n  8003174294755623676743764994243612959018878163634223194934072584973173897184738742749355098506472696\n  9684412652067805021942042876107362888938588503873245685564388165788462809886618203203578230333800993\n  0591300723334132345096025973746052004357099860029814550957846283200151357359254602735159675644163653\n  0112264712786403244824007737996917646650602387339665635679340398356568072219654048851193224882054279\n  8091297110077004500227754612066171669155913980976565982271696317371323802330818946438128134866452495\n  9954457359960273403749531981034137354585996149549836091761262853953078738457075946329303714882251930\n  3817175115438350026708995826545263811037252548877439260135406025221454919816995798737164535132550990\n  5208796779944078225308077581699560271112775854486844027605293945142888002909538028485411012261577841\n  4915814077499984149629224019889130831785966691538822900994694745024784490257136735697263979283040328\n  6063454681985901480867741408921089040105765750311041922161494187431458784761367147739183053531438322\n  6695453832992239404561336060178214118865092922079294966409121600359051153880564921627054464191236518\n  9082065327758919973892229390120026823222236977367233003938217236746530526507439140683094747321260320\n  8840098990148026780199482685855351480657053914005769345471367320387577245130697596060567953900372658\n  4611384511323064583372505805316793447259943055217500853177863633981947217743849839416646214485505188\n  7706616890278874741977750727859461678481964887923839242970123021952643848769171169294191367645398975\n  3022131894427468986445119523361135808699525657384995132272344858932311386797831195178438771350648230\n  7870482998034471550701418820531041426682294816008160950246823597889332394676950155947575022359260204\n  2472263849410031136704409745365861030801205930892752761072852639425752928436218637764253542781899306\n  4800665696367275161697181990722601937571168925947974476124876288821798650136747507500638323479883964\n  9774004884123575666865716142158311084736091393450002732005130798128157022256169065526833030836656381\n  4134700708194221664848221041593434919082040564085952240388003780734926165030023171799931482592911800\n  3774744659501565939981386238692869062652382061233623674596407209835077011082990790280690341091750963\n  5731456182319044477049548661871606922803035013735952241233169641834879908074808040868998221727551316\n  1958780967752165398983096203489409368385653942119612308102110347105174241643465517192077927713852950\n  6026751864243969265536723344784100681455951149036782838817570535380038946002769070563127023230141413\n  0663168017467973350972541462609599578815941072780659665422853016083098094827980877799541513306341851\n  9778723030126639225399955941394962110041954607825206744250803288180503393892187565244451699554137647\n  7841671637307558479723386593926352240182260803169276708468269071288406191974911765628699969084970730\n  8233756477976874846675305269192985079280366818214376796073050873808083014464297598254170078643973049\n  6108341861969661959632201840359163563411843581859820514136319153091251744066240493909245135885190762\n  7068893662709905594646893766800692046828363046250164021027437917854480248512861821612512114570003573\n  4674069253679036890950259239891548171622541825245208060039060040615540589290773206873095800617499719\n  2036471209788419244666709204449749874824088659052669358894877525751640135436742379201453072202353576\n  8345446812068659513932726355927699659957377744110379091071568358658465622085862107139549354539122567\n  3280629527519007549409048963943888064254557072622115936312439491645972564910184257540822004722888846\n  6345128030448319017840074011676477395615436471395235581999769359010841775219733620308326257616596841\n  1936614585331142075321195292766971704206705185984249976283460412316390812279089005602391472762547230\n  4465613738919348291198454930609446294509615911536755252862610591271212204144684177497818630501112974\n  0039411193508189083573332905511440743044446758533039081986774585870646675310587332044486643819547370\n  8480984019014571108015111144466295074606523305173459452577257589307863700719576792849542202391372656\n  8259931838496357371745540503873578054083223542866825098340742461917212410659284052811166200923282960\n  3017213638492851047735852983920870989263169843588574220637445799561054144370524882233580267567460992\n  5440227768400935931817775078576733453207311853083797369573820246047450096045240556006415683554046864\n  1810641559159869257448903034714608636868420714152951953996888639944162985012621982654789950631292147\n  9605647184999313392444952972883378335522530665608113911155759997907138289241837357409051932411808327\n  5321057583443407862876642948811335953007811514259578279640928378127631674688525323298028567924732045\n  3209385421015807147401809479461160486277678673437757511437592333049254994572062768423364394693270173\n  3610844401875653569316078803127015677432921109546037466986463058964329961957990839163885107358365539\n  7358685803947562940402286352096347217039450470385257108531336244754542001052596712178357874633359416\n  5923235625703933128018819799348769808508853873790156788859249599338041045070956681978068909791304753\n  1270144691199081713805793823536727157978743995647891549064076938192367836672321819058213639903497314\n  3981196742174048660691965065868831513483401876813467904264395573859006548375807152818128951074144096\n  0450170439654853590538278043481358307724451600378609737374314721794026495307729429552473216428585864\n  1931339046225557314287679022533447878688563797709322070475438244713707210817280726216192203451676638\n  5698542146002937106613178446743494946034274590970779402571198873753139912381326000956320636823628583\n  0789874153227446212759179354631214921585631006889095807780605937282837406604517338147569406689687907\n  4464372890324045717468931622799152607670087495794636552981080060563205359323461491322115081869171155\n  0065566655477454978755929060742276192490131286777580134210840162883087292122615776509522101508044663\n  7440329782265047958483949290880913783491105270189158666597815395224336302038194307797221007492952919\n  0141757752516992977147935001371899644889115206473629667612182183930848992602460041899154669973852196\n  7567293096434216988980634192953311166015202689067552639251081017259294741159705724670208362379144576\n  5730763105504694796613415062949874761664184570782385557437047474057201870953392723123250003365765441\n  8215016266023517184726721533121075096401585101898137749142654529986669208708890369491023049304630341\n  7508983514679902569728765115044510267583560834962773334541439538796196861122862718377702626499995437\n  8975661863845224244739492492150548510122167075552405102103873300284593613184584427867338231426176973\n  5636427084212028318843673819283471319508717312219101203167211411093958999228846748017416567609937878\n  1968770763447597018787011536350704268062034322219624818967910905627992687206315734435950789785292306\n  9671951104333055667838495384096125277958389105487968484862086797174930084521443594253462001124108426\n  6566758689780827762768401346982941929580203305740047491397897105912264221040732557891314047746709521\n  6337310954671071478824347469732253620897184341401689515209329372895796179900974531322807631818289943\n  3189695689530472370399538905839657483550150819470100336494607541568093909482754499811810031151431124\n  3716206028508211677160529015030383998177874986196350048908052208969068279491550381572239746651144204\n  0712132800560653624460196857385732581380945079434740660360543591168103854745541390100521085682696417\n  4364592697573011123142761569164064382930414419125809700150147626045084302994739777044340602558483155\n  1837098621043718244490932449990941239696807273557499097475439290255798479709348219032808505910233185\n  0565958856934103697521787966167710423049423523510863007281287132147932780402066461426230078561408403\n  2598348925571208511898538223851362097287919518774650641861010501100015239214019881155010333190671539\n  1496612736381353490620189880118606264888141694352927513020120744485069394971565696370052810443645796\n  5400855804416248425718544837208664333866575252285810948289217257839158191476913646032684476202255833\n  7884307066268201365625670604291660967399373963337255981754023690188353530079901593967249287745723100\n  1781338885062942677684523610642620854720708060536737626847668768462104365662552545771558209684895512\n  5604270948386990045370602363886713679104249114919963014756467260027940693936292085268041593916556942\n  8310137017215002461341255538803212017480246619940571602598114205384973309909585864771311219005778516\n  8213546567692543695868395539592269791198151056786242787386355969635159652578010088777516139485947653\n  0289336591762402297065783698536071100495347567572284079338746963969820527548854138638091280465567957\n  8673802477962455807493572388749181720103008919889932379533927562492951430639175417565236205655375337\n  4784035475143499180169624212773057517531727140899284179971054379976646930483998576569703889161802688\n  9482866498396473822403052368385787917654987361628471601522751105553564227093034129063412140503747065\n  3876110440576312776776879558283969360687974929924730557570145071286487760372167136663996479516812181\n  5089563593221450808534862645244138042319376365335527483533321558341288886647780139622494602435843022\n  3059175741552754477847166515158060159683143469938602241167033961033143444142152378121270529004152968\n  3283581427457205480763417399768540321142787027099465821456696142049358600517832030749599849994536775\n  9639015443329837295987702158798404530424172368853956543113249128001668861432133590181459881534511564\n  9693087226879981544016379036258474494027676223140583830246323278355589704912287637551609935228638759\n  4826470923454896604043955282969349632732961945392634125404435830649127279699414425771537866021215962\n  8384800807764860068442119512842811118606563381627587966850467909393030243819414713450444610996238141\n  7080458893859796343824476120094314750139145110290353458464233986653377503403288751178445621701907008\n  2687537123489425484526795290596728991141621687172072527895413036625313121616871840029084914010882474\n  1929033100395853328090305689816195958414640350088183835447766161764083433565762829160365278550533429\n  2017344423999912982156065639233096831232606113498474590475348175724793522899893500943495075396373482\n  8911547110172984407907116384882298841792185428317498575601644356222646122594640283086477663873594598\n  8424504709908678771675009139300382117519811184256499449961925019393804725337399459333773125252463064\n  0434299251006362772644042522129335363983888712558650282148393519537829121923251329550479427077479817\n  5730690981398175836426749156756380340241635030089974588466445595105263773038875334873440217725854816\n  5703260033562049041773557909734759843947599584542976546367412107535150701385121261710170943881638681\n  8003253445607801138931545723258763168759141418393365682229624660091462055145978337911564647926663543\n  6278233025485821978207099747310916035110647009748740007315222876647396291277862184468355500202043071\n  9142007284627901831863978702570277226878239103697244548641105888916691110592202944493294362703541330\n  9880526880087934617095630484602882766011907089407300282006643598669430991288386695237929866628178898\n  4272697048886044737676094202615377177917909677512787197471044080915599067919077234172080808599042860\n  0454545675142277138473782341100531182443063238871528440862687566050697234784773621962023765844110337\n  2159043811894698293130692861159856453139893139948999833404400924228379125175552174621891287605139468\n  9884726771874665047852706643625748319169084915371258805414540363267478695396491037240057461302202931\n  9950310198775060288023797500255215749964464245334988591590936954395808452804500493663983056378225410\n  5626241683217301132374663650818321551390498019391996251482034852336035202979892243773111150091658570\n  1032600353644447517742469891589357347056587514976256326803969581696949039759946106397634323054227213\n  0876246685734670460622349378419919838013099392802365227419198605426424971179228205037053758742713666\n  7271485530946080779629080935838546546834984036355521684570343035006341023502853487766353047125068844\n  0872326675905655793347845911332126078901928698099359636775783128957269704288379935513039269512405891\n  9984490604631927762990564603947687565277618898780750820211548536425379197075472907112634428136059928\n  1191735709921525555198027605603718090518902071857735055523271391396250159427253930237186445017661783\n  5950053674245283533462966004008468072728533180835272486343316020649687387392161609559277707472091863\n  8361912857557193948445722793390984130659405999651263847999733328982724471352363001173194587972985469\n  5574966414860678319364121215726453407658070668960253185401478248747972806312019166738072237763920872\n  3247542101321740219317052468831195661303656707030521912378617793925690762722384770505239270622228374\n  9423814306103440377982382108877414396313901510708203127545660795464337135345992806287196946972555924\n  8762340560859976025423380535602919869909560761373682770704428667046412247405699674920985983836128293\n  6506774498024522167809570099379281101073932308678935464775565148775074794665008756926950491325561264\n  2806005988394995155162576408277981605727557443961201814749780045132178212978637437510997476733763131\n  3444066932216989790648141522459605796036374929385390580458098260355681952893952216695741564220430366\n  4372299146967604386441942130136759001693242269349130492467027077824818455231134611034534892733150600\n  0123028538334230363824715502555136874563216693665604441464245556981823192741194508279688704694176702\n  9660195074502498516529806186805463813475251438433278991996092710858122008935766222569799359869922149\n  9254647176821012765199595978247005014221747545861942960392394590928828418146877484191361418987382812\n  6483553432410169649346552629534556346170833510950168069402286750567763445714741321777516730620778218\n  7706492244447520828000983425570457784919191688417677178688630332126895491976457394075370098837140048\n  7025429260329638779287543770695604373399901002948526381500326289972855113010369858193267448850522284\n  2191805455408227747527607465389890506437479816983471777490761037600628289061945763967812992880200275\n  9672944986154770652047321954189029670858378060569502688599152022861683177931813811133700846648282316\n  4294019403501667489299392408705756479425131999586127833097352653843359384167524753096842469778191862\n  4343771115599252828273132951369787821407425451631268645232757808217439154214688943590977318156580220\n  5796404419421225370147991892788537903377743287340955117413783520191979152796500139386884855693747482\n  1612927167295727856384738632469385840529246749040224134389518832380107931460183429162163319657370015\n  9794273900450006384165131451765590859700264700322130221985224974139157795298792909634972898511760181\n  1374469220942531031313834496135599318178835441647145038785547166597698246724797440311660606198912250\n  4156909044764662457128363820616674275647027759689746278418105147670135804259038575306203657293784016\n  4916694827135928569273543067691788670004922027323162640407025502795620934962162273386194868110608449\n  3589560178708588313384417288763890931537407240007280253256276428402648656501968697974430425922584958\n  0474179227925340055252474495023408392656172390930942300609366303234802021086788680896591816847927368\n  3301432714695684457049365421273852364197627489417603760297520161535938944876220235739135468342725946\n  2829509057651431942095955160726127413535983319184123578419642134288725668738970843831141046585600376\n  8822032463086565154107992964690465777065237950534596024614940206156054484306437872994525822626360919\n  7006342345695812108101880429485136828673985213253451985198680652792016175389656184118252242529689346\n  3498323878626573832248821467182212392161452163325275670017042893990524654825877851241251856125788689\n  4555316654975464304753503190355902321438128581792753398401246082389071705460583596058677199021834652\n  8305718682775107625066537094529888302119627302931858892708475701485689985296650573384710386205996389\n  4320941335957796447699221415378655112464853794392540736219275246848238284997312571864576555150869582\n  4151349798157017437827336637993430650906064980929838630333539425021822566381273209743546622445887643\n  4994073553886358770672063368111132294229836540526882156127024596288572354826421831454614331912545833\n  1181255979147364840129146862219867375818977195188232785208093327828052850343881380195284554650513932\n  4690269115602676843585443935076285667261266508394535898309320803700107893243658291550801322381298871\n  4648091356440292471252441002452525445080232461578220635868716711055693285438016246834619674923755227\n  7513105100126776057643879915719948597065176021389146406317350223384643458394835435027981902728797303\n  2028508468840198759498703781461796686462875466703998963042483342254904924467013293924725832362315311\n  9971239894462176588427193382546662161038214006990230277426443857141757458794397897959481580497290597\n  7772621874827919154213901567104042498796038383987308071550425303932011381726233669143418847662675503\n  2586344926729416355440616416058126006897850489024654095367384485080441994812315226437778358928010770\n  5287235798131917642254407902629775223299431624405682282404897958586204209590301675307700984125504143\n  9517370577205755550817551260179018120073513341772372476220812000860440795123951426598964340376424506\n  0829599666156088903857106846402914127173765715134887944642689107694108953101190999299956309309050352\n  2277723326291470140178644514635311873837849554388250085692730878394745287492017688644731178310411019\n  9160063149881892999061015277816870842162138183955707918405119806759776959987531377577268878910886459\n  1654468983133474235479298051910921514683071632385535103872718754467670829529749053459537652593192516\n  5945147933685063816797347866368832707895439596677298327096680062790539599982945777316823832607388018\n  0654102514617216288678835870661909367729796642225593369082458671032121453015761406563848832046204655\n  1157310033106271776366327253551051140113729479742423417996595373489421421400236584408113388319761752\n  5505890092454531377560588422476286523876062724699030212670470780945124147162949557027040189986666320\n  1798423005507008440753327962569991771876542652570331254951397086494471914527294488305094601841529556\n  2514740409525798009901463383797769021293940853102488561567350606338634923684489507528233401007520258\n  2830620711371905942678155214109218605705420961030713293725553682257947355874625677765164533109298228\n  7602837922593025131851658133770605209210865756174301233428908469922349735151163142174525426713978924\n  8050025172232090821245741107761163535916860465237641185208310455600513909589498730970708723111425470\n  2312167332038108548092017873914879344888372685456892148778303900165477417622812605807283554153313690\n  0793139630006376970200762535050726123344151011142807093681940223698999130824742465401270194011322299\n  9932048332874671355383494579635836899288623290439722584493817107725905803949716259506636916042428812\n  8254838697159665305547425435455973433201650174716942614086413803804665953223880609959689304939813989\n  1441778108044017768041263118730703803284078136515237865950551008740358384973781723210016623052721994\n  7879907436057423140992833458661530302659108802848943882627192860592688546252611811506554314391860473\n  8638320149520141992401651017397674092260432548429456592585817768997716520267498641989074933642588243\n  0300822991408842303703349200032109476423574937082515388359612855402857151199968412130951329760106062\n  2384467853304303605283324594771517521109132184692968901359920399067517466637717540893162635269159223\n  1667585283815133095733518294423401948575999288757158961137352500733529944686451772778107293555066200\n  1116627864068458347421220153546184274562778139563100350380090185222039972627590546827269914375360065\n  8655126345316534223994033256987619903270018293229045380216469805315530988295337618967309534457130377\n  1285992545818022726137465569058225957869209898046116740093917323357544514241815594279041648405012175\n  2751116222484137648793952894876891106208346787576323688199506508172349368185004920139539693115045084\n  0631833169795650011516330083782711074977286046415193311497771862005817211835717658891646355701844887\n  3306567412167110459918528506122196801107322548295187740766699796023038472007253327600594678695267905\n  1431952573547714111157306283794871723879901011073719703379511138790244228576611951347093824055168672\n  9869870945885528098965550905005839479776816362135995896454669367741167952365593301962543171459828163\n  7637734830415853528871062820092867345131786705790558624228776977038033586718966440076045210507780109\n  0263740143632780046286289324312169848956969268126996557009611629781048808333226401158444986578869198\n  9155116498775950082011654710794954761627253597443140698950143479155214870180524406888053182445054861\n  5105575082458334830601530515271410340134615871762049327376822811793638223772636769508996060057645760\n  7434908380867249533034011936473642216403187735017426283830918160337130530819470054814566633422929439\n  4379129613611797429979597898222018382043393751513900818795675780849881967116995779814800468611110202\n  9985597696284193886876123274515246277330804465733695463654938404008197776097066391323765425391868682\n  0356685427661932684390288591996788147248350231950588774756415910641899124069125309416312561954109543\n  5308814642343408331609704950449309811673539831293735539341187320088670867106762928026623131366609838\n  3643075615682433710032476128660874213918935675213059506263362049826465500820665018774633318404810965\n  3726939935499250846093222363891818790058724923861078321577979026003556222664391725444460628932945945\n  4295831001567300550754372474262118465163712077024599682774758902127077460823281087774656437622050892\n  2117628625949233373223067991761502464359913563816206074085843974251331593898633831027241143850753208\n  0538973380115912508795623407291394530386270706817801468194772402893961722164417584863020451648879583\n  7610929850676053716776401041227878179550018233197260574617611883779468454732039891838117019778662208\n  0801810164834714314032925450314249522008211143307446640136242253192598750915751217391324329653494012\n  0953928653470846315882150495516801442870649484831563843727263048169479579203556684457786382972288953\n  5344118520610069545041770445474492597086698863609934470061993886472734499279127222316585283623292536\n  4825934210735524995285484423127322046747107806424366995842385286374322732442018283439734000322418590\n  1923803059005872229289610551499388306141350064936910473902129154397749453605108064872080131190490223\n  1107072307706242833919528937220911487783908790449596315222989682708220530489656016395945586075535222\n  2215957383495960928649204136611204987681652094163269125894048452822290360702772755091042347607151026\n  0847037204995330735661652016080315883563879622431208900709419217345047787877409407146870679225942590\n  5227518180949282295331821489040420843933377285890253665084263277258143948601959376487549244711520859\n  6616658830859553361607170585204247977505790595212049489913462737333935179735374909554018050208624252\n  9471556100879915414706965354572999224070932580384255389746776351480895187698836463589425494284220731\n  2036451005027160780398336131700022763357322058050472099901287776893533759857416645852007639216878048\n  5736753929495033840982293979706583142555539282959192296980687772279663972939077790821785173247610873\n  5564189670849418232302926913249449134037576977880000852120689948851950118704243081970477677656477051\n  6660073820649884857171048322723457119259180652711670489692290985807515362751709550528429039224365004\n  8248807448131857436465669844521805366646754837987356791642201329619035170864147973371577541061516174\n  2404449579958031556111579103087313472099035301894999465821929921964771056882282986141014201946390542\n  3285844381712408363322656243251238385947763567301206764410850147539814463428593104949686936382640046\n  4162596469514903196111048544775919170658439270676024003114521271764708333200941756887387594777063240\n  9980920684630534774332419452200217630004662282023808277804197794933893918898522440855068666909872615\n  0999343275594219513614894603275485400282474638185574303867224848145712041289402200141526884770962461\n  2221149992288764391919108994000764500426736360335956446442708189785274177077451339584095760446211432\n  7655989257121246407049760606889475217788884675365773130888483170413084708302811779259466701208771841\n  2865941990187787509632002811023755143635612304865546153298828299904617451774858147760123133434173138\n  7710905577093670657365502031757900430672293031445024199197742809676221242519928632740258370400752972\n  8174354804106393450637326750684346881838874833235411216634188042412330340349096757794165377908412586\n  8798288610323527885733215533815198830588045853153469043130898096369406641813704154859314966671159813\n  0899440825457153552300652508228496172872396746508251900453245582357486877200667479497121636028208523\n  5430278386536117112453214864879424132133170085231543372774607680663766996188951228804910891117659551\n  5736498473886069524716684752375144641521336548924672761225853936148416514385818691738416754348278131\n  7663142911693785564618171660966340291272053653025444763830653355045114641522470865121213129009990019\n  6815169592152430391022949696439063552199065139432163036534539747151573501445915609700314795373825072\n  2286432679118022285454450510066868382649729074813258480871020887495051426964293739258136771841690654\n  5215610876157378020535279580044684913613691746825371728035367843503618901245777758338646770048718755\n  1541811503714129454911427269687720886195290311000652148060479389430426121125047463622256753934768192\n  2221920063516876682582150682798801607357061108055578616867049474864042027000614400977944187614785497\n  6458239562498054449551257091064027083239081446009251177787652063803937135711764476329221621412656483\n  7394710745132290507372055423326208635230121119230099328216475364369237906325033568253135543303478962\n  9153304492311538091995755532944987052801903351167407527636655981472206121804385730030729787921735685\n  0001256233180674259887240109968969813852397306191955928336948611903239492535944158365958161383912185\n  4119515199265507043722245110633671266896256727586677388238790791336450938651172201396285944786544296\n  2183266784517002027818841924009364903662723574437287448563310872878958458482352508201562742207923922\n  0339204508281946226152918446070619758228521338779696323678640133130410995564537477406457775768490351\n  3791673253218265004401500646241636404631178277966053575667603716137442026691617218914299163923048497\n  3825428942219985454786894825670545771208306069664015175470113984382899319336352288857298115482869135\n  9603242851163621922207667981900638840484271526086590715537049718593352260571181041504579347353963276\n  3998872325606368960841031544136421487826119285418384995743044276868385145914918918742400661902831447\n  9859226445963347995310286302780183115008930007657628088707768885566711361061861689962499638799370291\n  1361950062155095910026639429805842317789649650662756529783441514973388255236336446520362201321628032\n  1350049361959750702691727832370138371576432302888101329633287393824573874624509689508223833084417619\n  2408476051027246860191447430391510803777481923871052911279590551749882293907551274408036416932829212\n  5537800884919287028546754254666973573970536536245400722239895620130676048113391563497277605671449640\n  9064045114809482486851179621640442806897195762975356223618168885002728569433652880013184412121411238\n  9838519527851194814679016652840688382186958683066129590397745990561487036122898098411382006158591424\n  7128622986004171890645301008203279408858038576089051226987600864246064826948504861862965172218487518\n  3556528814663127523768706746675269172441672973545695673316677184928439431385995773850485061097313805\n  7829209449944463239430606875958119003860261904921098398719699336474633114066294511147152055694804027\n  9873582430918597382639771340411416016623775269357722361477563479055527521664824146099814862813287663\n  1187524107417432987436275385045777742542057576627393156984043856772914383783590182351736877088048034\n  3742863236659074522885395228357786813472195376605008468619896263300503309360409978222914815147525771\n  8379528138489156804919218123836041227135829611649724710802612545920595248651142278339115649754666274\n  4867185218756181629471196471380668777153608541786941838614660748536539552580901696623778000065583681\n  8847197698244458732298445308869902993378877952657197280899159793941934367522718663437829079368244403\n  2062463960186699049723190315024362504081305535338306531610923789527333914369792593690728697404262340\n  4247587033791700221492583435241015718645398347845451758922412361367352913626017121554410849303321644\n  2300759697110588546958695711726320379851371929401448711950153715879163321253830793896944127468922739\n  8610118372085142869319715028646909873284817207387381520159116379451230101019666620364454129562919035\n  5481051912534387131600152412478550452245480417085800974416436084037596380188386074895352662695035328\n  1648096816794488017615939929356306431457111483516674756546277594216725378229613379520048290422881659\n  9956705076073487042908590849968490952949104632685176365224631701348799893768877984209294851296278523\n  0159883015336126834299177661463925494770519302050031055605493677633916328395389557886997769714313544\n  6101324961890191705701201820667021165776654146051368534345117330284374109752675183557592471851518890\n  9168989486576041645332124170280811484675907730132725479460941550972867896718796180122044335029687962\n  1964404832788637996040983882536293823039583969837394961017123582184217743974270364691125810751594526\n  6355464675143678868797822902295599477157643067126525971855615110357476610420964178412476830158403397\n  9360112118781120082317450371407570040927108374354010891993459498375670612740971769921395411095210125\n  0839813654956204515024366843113398973858736113065124745242321542571509170983114140086026489053937071\n  2774412440669076831670854240573003611786905243232054426823568650032703030650150774804738700240267292\n  4144800205153067732701911145489873963492924892062897129047830449268538002831487535810599705614838069\n  2737300968661098886378902955732473773218392968237265964099999476679557605307182161869394599277816445\n  2536969658122450093564589944321917279168676398557892539969660988248722705869024920017849027121486353\n  9553280594682884699335785668968529914380341052833693838980810654163125074949460944740888646908365216\n  5710685290293790114001017104187582043926198243372615611135685841730762865206310031274971446997819103\n  8819926090166461797540691029725658474690450719252449465833527641746399517886169056732659316334124585\n  4517825808244900718850178514288717667208311599555929267262117825611904459506934896175722832507114752\n  0441276776575050868936709803366686786798668095854516356450456700098282130467124423758025533584949678\n  3455027631075616185676110242006229086221786801124345915647756613627310796173252346814090700110500979\n  4586345724419026620057736717904612327442085379760972626868770094642272586850071636459572360638163384\n  7494349975206543190488268758253505156910742713458684179456955827177098027528168620203131954435974916\n  4686549228763080466621431318534173986503522645190258054517242379319713354798944313018430240118980856\n  8284287635611511359254505175900660902931753419723703731662676310455267705728410826619539539676802350\n  0467639232238198895390409926916785915668921976462053713869576979999088841317689151137434627023755761\n  3560235953212929513393306880410662258095597530152275907114307261209980406112049595447025290224582981\n  0326046036661079078461456247718072122094537822437960892084783698815339985784383584762331111455294499\n  3163589565451707434941008645637568236524522552890279717199986729963816213783471325388298076612871462\n  5534783529714630139379788432298529584543951967680386477081199962158170809443989580382507071135827079\n  8334780985661030080924836334010664378517170500867285605725665824900630381665925027603594014207243253\n  3503290715340643720991049554417219296172851893187876675409135877109975306839422832961708480658343497\n  1118140092278253026159348139475517360355840894266447493309584619986206812924842999006904953095601991\n  6735927003422770580777725794298919248350750002625357538268748323634227672480871144139303257644516263\n  6301415773729913585526476183106154750550543500397887915345327702159604456635703067706610019201793214\n  0171479697167384697333397070560585989228309253129526494279536183676079287994017708601760847530393479\n  1124788612396945329823362750327417646243217820505863121003280810253530905228112133576906734827893771\n  9290836686403502827994706248624768867044020859538534724137046928259372275289596415597499167757872687\n  0096143793390912193869911363019731897109456037301611109766624424400181780650555724623398592568655386\n  1168261270433407009518008868971398949213194807654561609544651226431496693496974361698396168741124092\n  6925087916495101225186752483635616057123486384689279645666764984846476716504656126699086548540370528\n  1050282325415823196482458286149790041803457596958657165789359912026924047544686256265670714416277114\n  3207057262320457058642548648538642871832592358827210050178192591032186210252542906106419649321973848\n  2292467214508802767736310025106146589875281845672592050079006099263317935029302633914975478998055915\n  9838740722820121116031847446073130926422360572014068318740741436847356693028138596844963678163554669\n  0457525318548265991161791886475069922132683880788802178150798752627095916528280767673143687407626055\n  4027715833284666790562252441503160456864894181125999979503530707283995418800406218376904052860463782\n  2068355374436554856947783615062635989936347870279090309974627721842411001764821590127056711820876687\n  8227576467699428541130542428469796771293655637190811243475249918894104423899887655814909816313382834\n  4398678830561422069948656437056345681695102097143423812653705290231148917416269759846890675493815136\n  8823125531785534937461150504580356678194431847685134829172679530465154959807564116899823793686265452\n  2544768231938216555988168975654498984722336080402362152126378985700273204797098350733847558808852656\n  0046011136366410695357973449086862143285777692977138838668754917368355359148530578245719109983029831\n  3951375705252562095809540178976954139461517202617649660795210633054864581189033232775355608042092880\n  7954813104430831425411756469379644937008805178843906465059869952993456228849781367900568424690668982\n  3480376722839141414639383441970505255527456615243070311689399586409521846800689011361913009089342682\n  7828837570563951953301251801823500492931069727258057031966431977564341418649195709519441152022579601\n  5794217433299871249539848164321588401682318015676822058890334434057690623837262060541947083026988680\n  8831940015177925067757175174593722384717722050820930704159311736220200038813060788840091117739664188\n  8367333204465296464459344197685964281262445125625778863231538319095654286792308345124027616888359652\n  5102882925470174588508778546743233541314358139890052342270388006077143178342526680299665251595805267\n  3968256629757854112732459999634827193710570217727679088300584907363364013164799368378780942754761608\n  2779063539802635477089489921777344518972910084616490569126445840049207083085260645566055418879410176\n  8916027728337257152926339124809056000282337920177526406893511804497791997323780203805484515346421441\n  1215740926117175317752534252312656527895654799495249996613418668561137172657535761612467563936363465\n  8529021988359358313921924913934186424541359344281660384057943034058583059516125841208664179704045005\n  5709015103142797901457995856719745613645353724475732597176241622166560981547765107924332845973035022\n  1418019104377848724061746812837199614628391664253480309667240241178483790511869883383917902679307649\n  5649132796657819771695645747593331331342626077489713671970058790516411057560868039039268658263487063\n  4540551576313986167638107741445122594128550754494215952948573989863056847155351487711933227943103860\n  0662876069707269223883921101042205418231418783870028474888838905667506331222092051480787061361084283\n  7440600890446146679737158262720291116842293247482478917896858777805977609418186443163400288502645364\n  4551355067121340118869078555749941020501202058436935943833843142118798496695796671231829694191171815\n  8049435257952406018375850997934371130880264021542881644344306720286303061244985371567180909678367412\n  7520201113454134998391711172535385170214243067321000314413728871055440789582470237649047523203097059\n  6062076120274233173017656903200367749269422733032275776275170079415069130235233822952293804237429919\n  5531100137570087357404896049301491001310514828563869984292941736475578552941533379493920244023171942\n  7160290231271594369364613047780157046975102606154335602353227271325523781649405525365188946498390345\n  1788574439635435801343497602714738438551198478108928668229457725753597842954543499095269077618698050\n  1260973242575667396516641860943350384149618387370350938070380101695366304616092407294362211337355372\n  2563179924520868182716706419610045069000178351726815392178658474812406988299439446928475392120476967\n  0400891751698004473501340113780055210563049882543493206799641734183811320822606619087198336021714825\n  6562393710727708004426030257864375469141406467379988133306274980434048844433937285851420929071406931\n  3278515053469681273452320463635666300917026335976323886142443801882404910085101582522932565567279300\n  9966171516757110370227909005772432264519348539581533676201804307906634693859522827634852807373926695\n  4153406812865943469956911804724376608938315621924386564103131340589115080721932867391688323814944776\n  0719920810354753884234538967326548496844080635106715752371203075032887685369166123886017735354040091\n  0880395892751210025497166937079787186642922014014558824562342414467031323035012810324420163216305765\n  3771387099052725968494087829811861525888492527218603289522182402628298323270081763455612997145774658\n  3785472429674618246643849029786530077631593791964425478394882826806550176331623401014632709472597201\n  8823335388133530254565390463483105173008497042615373676406203301379064787387371214645255533658355828\n  2531298690853960026366890725505682714100041735228984821717599940268074649141888703063814711532964678\n  9559318086512230266369972047113174786349052776694142734227232795808700025982805258013785387832003118\n  0872150984623227074316277615294128040427317387669976955481915380842773570932813737605617669370728806\n  1211955806890081599398264876451200332178564869843209063760256299992888973076124774122838326961611075\n  1648915228250644546268306417227180338343173765819712463951447878320009351333318655222338955660251647\n  0810190022446747793987501087746162698894095028131074856975128637090065771914143770296754856231438325\n  1595038525173136644265502859810576418370704824060732078711770552954530969818351972929411541825195835\n  3083363474955997898763199425104174380877385642307717332540519763611239063521989491743905255002477559\n  2393944610777614131867655092406892223028644317156237562055325359475888341884110318326056616085707801\n  2412132972749166000048992747414021583437012481574191298877094711693311104113046464573198787106957011\n  3548766016847239555580887290897174691220369251189724680591711257457394391145651806106080563786530895\n  7847735391188780952243969780018458236443954482446565562789229023722984608325547054940682218788034731\n  7899183416054026859967487218008132077885533824305278895252897097708026085078817526844197474750300894\n  4242700277303247293819695799127666762690253597622952462332687883138948400393681704468721851013957132\n  4767540822323043782281750498121221849238110607200441017372402920022571947628031499451547833447030334\n  6453163731315274916269277287196580757976562490296241213427394749494996058045828871922218243736016280\n  8616446829421784486643308194165490980503506193935373441844498848185595049650263222645086225208709839\n  4179516137292615631666411637908625996619584832695382064061026825170404948988385791924216865098291704\n  7583952932601194431057299970094882000646282506414298088578461198438509317434993315875405684618443087\n  2481690382849694454914912112838991744269803554425667205923759401508528758412056238186705431189016681\n  8097178919022122935188742790921955155180888689031344770845777714549283578452961724874657333204316660\n  6413022240780940992408614861966164617915731781241135208581516991824554105441256762164334410701735120\n  3236836922470239475223198646809466576700844147762711278182037067394773027252712992031143845135201994\n  6347089810581466817328707877561024420480747530842041044301634872633267883450445024484231091775516736\n  7076052841051752145229349324802842648388484690020994452862646418420347221657095686434779811103662204\n  2605284032034121534186240396136792653976305723917678082394197387937396993118579045446878731500279916\n  4768258851740784400056127034280313124159400625600806031689679607752678055851584447737573204098686615\n  0895683261795987193471910824256221882689002334105397189176036305647134218859359916610040431195689986\n  6854709529630760786863475180887668213990046769273709484748663262578526322996526490290475572655642628\n  1710673612277932681885116213824241463851419800618482560202162079647746012249996696722868524506028513\n  8006176482634185967083763616017717878758478721135242571274834527649231762646257436709226621130773355\n  5205683386054307054158740244929003575611165555716998579313100068193328538001828777472325091411581985\n  0576954509512870720057652266342717714995753519942375852010832755725591013419830661178092084032701596\n  3024197359149660681090192953878864962912091547913184092762346231311444102527801585364435130263119592\n  4384614550783343687132109051148727123095875779712220718360713602361416279336302762006615130143175584\n  2436447252712844828608334767494112067999001847319319046961301417860432255267100830950296615161233914\n  0072324812740694337484813194585701844194851954609071396254069592655653623192382949857221286126450946\n  3919495411072692219061756817721293282395098163294236973124724084346206764151658372429522369301743268\n  4138741020941322315904311230900855917808980986398114724234312597727307258749654507988460850364940355\n  6360642136024636725029758258821423970906963894751585219601005670875761743422200688184018678289640797\n  1342119879894242005426232263910916080832822172062383218156600956376613115070352539431370438476406712\n  5707365986370470574729955770563329249287066767157842639748416481898746442062732629180918634569514082\n  1112621118307784231880550483902301823855961986897258663753836854851880890027567239148796757475871447\n  7044963905966647638840555139832085110518086946733442146964388936519874292945007963579336776306583547\n  9134409437498487491781105259529349460886960396179237563635270568286632335693875478284960491495594355\n  8112337629627949110896272845630669590312923738949873906464548234526530112459709369166368198429401975\n  7039611050180939637076776957461341673659491868407159799409774921295144753643557051040490718226804775\n  3468921921922396655988926401383385425649428775082404565581803397987528075009321325165955626489684326\n  4720950845726942676196203246524253611380812855410809861388993231752761000593682748189193057268792705\n  2706681650947384411241352252246216405896697737766266947223060479259376589040545108908727196692960261\n  5646056922347083077659724942225173449004958810325871173498512933407482889628228684514065870595822088\n  5463566222379692684577270800624286247083910001271322746693291077595784116055523253942755096006076083\n  7053344808069613574798661003456942905048742886541585205718247493430292664502012901522850857613745521\n  0972739110882540490195467902253732559437010933022233435336792479155486508905610315092010532977003311\n  4909933191441582540393767103856151258970841315151528321798116250944078384463599269824851477998262383\n  6715422818506966671626620176160970567094861125093594209257672502737040835833893160975056783035442840\n  0003970020286423333532380030836727576947167063207271563288145135402665452805370561633756575655615604\n  5683973582112723349302665713737615780888148416954606951892450897761458277305644711560367234013737512\n  3911334222135099520103561776430770908044730482689991779764687600344803644414864134634689995078455510\n  2030298886333848328181072699200088982857193684138915398111676352370135996047767943273521946249418339\n  8303417727528719732165352397478366615988300018701354800725499677948156412225073198207773749493693405\n  1592615121472524091331243285352266095099178862420621470761814443651682059066937026972848443035060252\n  1914049775512614504465725697123159579764295821796831320720497667628657047131171465971689941414194155\n  8552792132916553410803586453942360439763461695335289846339014437097710317188526335297860098669308669\n  8435263934184369703188574390628654710685190800238247922659706695796912922827797760081119896191705187\n  6577047154804076234201469014747012300723672006374794146524884880021869725445463705686004723267422019\n  6980822142277847213930550996393066658835120573420953623270683351905374323509642416928024349246375291\n  3196824007038389209946820797082050855302650608417290646789432924890422666237149391487185204533360509\n  2819272200266783545090067219293448357187400486452584361950094552025533853015019360827545508148367762\n  9431734666870183989663273687066717388978381705851435561662657530589349283799568837156619051174693401\n  9853587525067274615771754279297665411243066168857921466304826537623629178636344787320604811685644513\n  3196337759745210891420642621077337168716290579109047378376399934031761013295865660178686150841320259\n  9439184688026600919412070156736705275210446025424647662225537968562211299822221366194969278051234613\n  5893880093787006445888955300930967808022056712229117324496219466633608501509594916809119443188318875\n  5727288072604920484225726950234777273625668174264307924072732430554923883140548639459295216734612059\n  3473310812267074435854430639051354861245846923527729555959508163391240344880846155748316511028056596\n  9126047382200962429878618959522873019383292859627993498447285095834161821543866108691365440642590891\n  1589698129897442714708606373440889508112079256324343912160486709803726929822324855824995708943110863\n  7654840373752138369775403725350930868402408318659218947543425465681993319202869736416876380780559427\n  2649094054318608688358706239930380932489377606395880881692788217232840100800778744685528493009535616\n  8133698782188131987960915707800606587512041368105515013899140721605454073209842445711240786902752955\n  6371764996922732097345339032749384224697177560429121963794004392913939936963834312381057271231601654\n  6238186080341693779232360806484166851670088458007079905399019138986928867886850125467916825295729795\n  0907781400775837291959525923077898529009537496931446488560420183072483668164534888900616418487213140\n  1761979206738425388528296023984285540130893392381411757012080830155418887191011712203543960412588136\n  8880489293940966294766794056226564819392253637168630106007982286989053718470719552486361442452983986\n  0549722667381399271232326979135267819475081542475158259570718215174779333083805385422525935868790011\n  2017697150694846872323977569602190530277291344179895332845717225695951393984500808185505028461731209\n  3463323897674396686784116298253664412222350542063236389978613011604606427642524721199538797765254709\n  8991387573337095875444606881810333079159233516940026805099690092016813695028758939377149493311215724\n  1590212362251549726987858042362441274878998655931459382697569314305549817950653144186683273288195130\n  2751995672175382370571522522917889973898390630173991729947859647328824514805731576623972746812720692\n  8354685997204915820065493214263737853653777657763105425649156377280018981099444126794727692115095607\n  2802362828488060198203017705573603550343134769074127602842407027856245018676049368092179666630506285\n  7919256903216092155038298157384365049568333881991420375632076289437684602476610394352022944810101404\n  1168409635222224465266984042964025300170064070372331719352207617831350035742568452310201544861847411\n  2946240496328898364055154538023000657624314766841533398052677981987237595528463455943508759753081225\n  4078311528564591382669854061989075985920268537279230084147530346162184574848815554875180280750087011\n  4860205663005110795262621816509997046246093820030562461035531104034228743366878696989658957146052636\n  0133947402955027742886004823589976160326074985704712218455866713227141006978846958171262714993858982\n  8585921462536869196078653561335684500757664674333108632471158007102508635704220042755102796922229828\n  8679505160390327842273887381118303297732968241604268323692533434394805615130277475655642243538631283\n  4139392655972966202638496945337587293946902596287388740148807094633806597996983165111929088025119256\n  0285817304991084121641799684325236402041202666033906135644140131389322120287306294453261319831333565\n  4125205821195292932149405364882300337137813069933752626752573427205471825985193439712284754974232282\n  5404076626173085591797748712629887002266741047470611468698028702735148198879330690780405185216982872\n  2319131755837755538329306419343327670587118572766871456496475004679237066771990706913870008711630394\n  4297482298951815094107419158382849830008905156337499709234458126841189055720390138093744926726325991\n  4733455221666514058384741593179377470138831092920729725748072689274863625450102261803654579949694183\n  6305185203348583061388608915374757681450689048305047432310417567254445678677540565353246244263845011\n  2540158811337628792279144576999324549020710057193890243323158180677444472667231766456076823483862792\n  1390923872430415110888337404826020756447675776852313457857843464984582933624074648014159794645214350\n  9285544414656623672600705710744294714808993054625246150539546672945745477522309885938349227321181401\n  2181993728972747836391302422295422832265812729939788697581742933644005462333979847923661918522402262\n  5456201012629622742562381753005177632863755395427686041957675848786829356580164847516468108506725307\n  3869350186544318606782117480706710238606132897325712447823979443239268514685587071759326786933587685\n  4716034489616776117163412996673364505897921107546018301236333606911449641883879341218421949353787499\n  6652379751539176305915964610347152121465642747239185396502131632591123081652835029486819565713588747\n  6772396290191693199167768645873058755288747597090159188858413402314944535163715820461193929538650063\n  0901968781148725200246325005859550973265669759408809248852766267444246672639849454940963335885449443\n  8550708277866043263766955889909423392133453243745869236955358408441578541048678823088765914992585877\n  6134937893933817239566126732645860588609983313023881770669293348340480489448144118284346563752808166\n  5602947298876984895191128972799505976303277305177693767829975992595734475281486283944418936299209900\n  2413580600242332685520325343646493589775270690343598809038877648352811417289852206157665771897459969\n  3126904994274595857748900715017710280050510218508746333748028182672386637611059367212151178910066446\n  0382809245724443141738580831441736587686372497575017241805055648156458882694424136256973792922559459\n  0205061321039231722794686286895619967419234007390131687938180418212831728509935919804705998908531525\n  5060611129029607455276541605554323462610167088128515203185163523305468450163097876868862516095539218\n  2019384304322085788084740784823651151685245792053763628583004724889499062322027715010389354247920672\n  7218039032318085454935230021570322404830357516834614195045183770461312945022064049232543372082330956\n  6895789820800186133500506875378551738982296086457926134601229336427894129347237377241183471056719947\n  4988132556630241748551125446135307313825080177595900205755256882935354103329405824763345954891191480\n  0263059411228562902099198297089226752024511822200112557157924073365057461275883823812394802411040449\n  0718897939017921349177985750287517112124497071036628890526745050625093926019965399546707668561456593\n  0046721731049675699045562486633893772473508896872455308678381939797414983908087007124844406148488248\n  9613102697330738591249879037418706260010514215839040887612370365371352029294878765054888518285342824\n  8410038398553662313376457670923704477054434480282490886232209658664498591943363119205831620545310144\n  5784822337399509556817273414508503565028059306482927185297472128532388175324000776256548899011148468\n  3462321804607071758237816362115737939333656351436126557882430018387059786827453486224103312709824869\n  4442254632051824297733063193782880524736277279010236575158387770445736380232431010591330252239746032\n  5442284253047639249936874122594125253442745719143579042619855980323554107555171796022257310079403792\n  9632241778553617780508804949631587383212867555429706886595155552168285084918184671511976087907235697\n  8603646204109197206493004123150188837770458311397629187009238052681820978751665089521199378270494551\n  3992044479894337884842312224876272598929978954825746643485755792646037586224230854016062202312395837\n  9396790618608202073848623338500638603716795394641282798171911311961478216700083080895078544581326695\n  4818166386256950925231648219178221346241417591335437979028341423778353888920595668461979810523192825\n  7665293832880911966876104818588964544244022054274896911206933353455235173072013952795452161236905634\n  5572702560858266064853839180881791607076066138641953390753463104231631434614551495468392152545717652\n  3017627907134670298964119348104686248731091290588286930561548550109865716994317948320400204615028922\n  4283253987204035091938364542056806579819349237779739923616433923284412229124161310236812384123094008\n  5955594392123890261014800241184367325721856692868521171174389577355671369440365534188266303219673712\n  2047784613967242423934382065575710146521083904110580254990574309270936597181213253729453276129255716\n  0338115993272951200795600781120533146361127222089311501471925179535242820970463835362813237330503957\n  9921425714309960203390688005783518739818893141181303060737189155369873116976049855114076377510951304\n  9911398393241826775067861293093343419446004710929787141898483801103110274188437832920482839062201145\n  9245419765221268914531787212145133126779878455604456159595249754529857535222154681714898414511138425\n  0814105501308548962342436284979104194400095354198478294098804365041833757195053081693362546548668506\n  7659486021084403208883697917857456235888145994833927128325817566478148930763018318845031751877025433\n  8151217217473808647418369178051185427139283059255152036961544265579274334095174087902928468948476751\n  2818289936936963800520966258096309522447841141623347063886751542015041317535385000813287716280810470\n  0188346896555554432576568037656735020267265299682668844678106657495635099985961788943244307515831054\n  9771763453238063905820477318116208907400124014920080192386954492021367930242580246465176983105671485\n  0197856958739975556787502966173286707949082756613216383025793652727117235764937197729881838765016004\n  6960198076260717297338719586498709909968724717494761114101478259018801182453610215220422049819761816\n  3530033988599978726056037579759868030733147522475640075715187922016448589055409022006921571006776359\n  2498572399552763201444121684915435778005526595484999851247978090199909088142554531420111741169391548\n  3314820573828041454362718046468662629137358234966482875220896995836290036596212940685485088790079706\n  0971536150493030709714479356640149031120553080824095024438419875824164708605864899073940687544131101\n  7445035194648723317674626024900661157888610971626885032390425642166579301971423307771445355387862843\n  2514336021250189909452614454005268521377177876674943223919259355906514401227995323657387859633667188\n  6798210051122484817540292475013669500504759670844180126373458801066225304001850669818109719049088130\n  2291872876366011259816340730258132566262078794293937730883405816982294048034393246806755200085304321\n  4053837036811967449736426643299033781535255022524682542776448272604906490826977213886983755924420723\n  7728578067019484075482502459031366717778767945828097120074709141033453979230407021247047895972416306\n  3167939042624636533153824680278462999849295582970677703673617809127448651096131947837554214734726097\n  7852214220697744173339302375889154517446218414658881740633219251066399862636936880015612905397748917\n  8692275227186600000648688606943843341695689761910479315504073790699480541423931403427721205641761019\n  1846519831622755248470937887500888830317863573072829187673035632713538749271862784783688027045784857\n  0870734728184365507652351170625675594045614751081746288865138894890196169187358664401789113965033124\n  8286282127732341495662570381436670394964964220174269652541250313866715492577924258247183930406221193\n  1552939524729565961088349107731184650661085378223722765072330072986433681676406634827126596611335519\n  4054621502427959882603393437778513689665892077747703809123061987976754485388849348861517902298951335\n  5151317816944793898448055101604475387293460208105642399995653132943818118179491682066434229861417488\n  8862468891091040157838357890464703385062422545091526178581720960154959041901980817249863332365323996\n  2035299833581288184440031231668441282092157103650031779327671655485926788764291194438852182338965094\n  4951082992926077565435181399883335003165944187490157382515153491173025292109119075949224257483071597\n  0710339463947729017711117954838753245430821919571097116313655851113361677992674500225456746172702619\n  2658228096930167652635367978562181504406855242502063277431207892459280730831609544932281990578760422\n  7141254698992203722558094193132907397952984690749668849730282861276834244509402541973342783863713321\n  6298271886802877048859039816542665131221746650688390343880540662876132415147364980113225683524539644\n  5917788087746545702095388905755986962043372578858288766430401486028813478566777522316770085281567031\n  3517086993687228395979776142704304433875367404610340962659814007959537338037660820668071019298809834\n  6461125352172626474614809062450843560918326623328614765717887367070432644964237558311181086135320630\n  4527313550133893258469803965075894599527870986867736616656527294096627095361899238083435232506453540\n  6536366700812380843142129160848939260647575042436077337007697801048622686697327206131308771242883807\n  9513682325960493546269875478506976087090621394446709870504353997170682855777324556183385967258415295\n  8438809541003637976907483263922322696763108630399810679689234160825946605411965782508337910051764307\n  1960066914226778080310863589495491266601968216898487279809973651882678777310532850591912303608390383\n  4063911136575293847387327396475869511903909612921446578009656278230854852576498319237213841985818804\n  9149140812202983666476256389535915309542442102381140094220105435873360217656075153784198983618305840\n  8095095792328872313144825688115900293087041948841952225155771425360196960007116347447439350056845634\n  4376900335741760282554910888521532392506087844859788167278966902631720010672064720740459424890050807\n  6282339720351383460410116855895150189454592283258699909935831848388833334959057125432197139992855669\n  8368262705426927598788149893889555327752195716198846758409266923712272429452524398252383641763866889\n  5023936487670293181515076725859767848492337458449430892319353106512504708445945982293233904494552069\n  1951947530503597462788335698461320222129938974906934284023355296263560276993322927250894302020639727\n  8510558905844300789720504880441292348947467288678389150262288852912874295275043556502096294224736793\n  4640352551269544793314931432012374843865246657866338104602907702516740675225470354471781686148529224\n  5879861896172324465895281971514061410121927327569484710478372857694609245181691687995355804049841241\n  1049197574392925110095931428097659219158870146386551402977596012953584700768611682922644374888309035\n  8961861126606849828180729560094573218650739506343957012535482591503536895771466916509576445043362651\n  2511991682040885348821839921490374688320638921958396771807212607327885619513135576575243413453665708\n  4865934159844354645376945359090314079655081066049468224721451838346650131789067411039280361890014419\n  2600451772699029465191226253027545038060324885188360479364632249905482580495776019740854482383090288\n  7041597312047031639348365489265472302515290804077270773036185182519612016624249355133908758669104232\n  9502521962227426242566715929828930404311900679570412010084094782659788365032760310302848431325642110\n  5347720758350314603861753293827376171032952138127566993973744418533716325063558390500476440504318465\n  5505073040899038926993628862046940269584431506310889786433825298791700659552819878337554177791762887\n  6197775025249067296380621847945014014371102715759436540408833825817964419430833308599847759889176852\n  2529027457842168969003684371389240369032563217458039652881882758186777509035040778567728215280374417\n  8285539246393030179355759946961952814180998160358562272455412759745369637536195570980535234513266574\n  6446826235548397593427568458345430580915983825089473892876921029768874299871189541517320435806519158\n  5613271735168111490983541922118283470365728867448815599802621633472873434300014617603878659001368802\n  5581277660263460014492081709590733726661036073624230859884385252469347359660993796975691783492560369\n  3389615646024653120908008670272784774156103600087897533676639449245622950923406638335836132514639323\n  9122021141047583736381538827391201590659474884818049489836365636223485421468944007752508002307778637\n  6424808628191028182034711831743730349334426177975436953771948128215642985465056109643559380311477664\n  3035513388882948516981378638751307499107404631767287595323655332912659476404873562844117507971390474\n  0055133239389619555128569785980204776976005252060680548352054715812429473628012190883115120816936817\n  0922796178050408945578359913093476322808015149969889135696881361110514023419878417059507765640482463\n  1188859014808337761115523768193830635714319409642574226714354981847395407794813508778895488544130013\n  3174612510004307332540107531424253624326777980106057834007304622567359488688561912669235601232984355\n  7726500006474319751470222670528280388950057002152053908057026851688179096653597758126368885914769419\n  7974829700113258576587857266967996800320896771899522050292034907180214016910200562865477296008692638\n  0272911146940147119550677284396877248732715812748042859781030245051328997441075754153570752061036910\n  2909431370692300027584895321251197846884642301068044903732891922605837738861309121071177058775287031\n  8746530455255581540388785652417324957369774887607670119504928941832459182180707700622495028789984059\n  9660972843531403320074981937074803208342455636186316599741500158189254372358414756584357119349433485\n  9756354649191752511745608308191804386335764683071924141075004094886850106059961850142045861653689695\n  5114758739606606076195171626252502367814350592999274323654217871595338031759236278898782949132690189\n  6017961588736995835363153030503048325861920935222145942082074130397798738379090640621247797034395114\n  1630488008217868194136392839249637892044245671039999528975670486179028806273423845473978447281935512\n  8116073381263279174219928320972189396961112814976972284264370275407503476407901345333133132456496302\n  8811571355381128154995238826309068009825704032522248214189545731194710504933927455593513204206562153\n  6892949366468640905631095853659861276550296528504908502547745982156692951273711332174559075315718029\n  0994325883405386994816409967232531224608321089931752489923443811948206643167694320572801425335205262\n  1878287214890835065610874192721644374574088327016759943094565014599538832556482404066112833332293469\n  4473822981475820213179753550555457762429632551222563613964468549978940344397493681610165919412356501\n  7327701212257496652664631173071157348366699751314182591158461432810857875813421737613298382076751955\n  5975541957172396642226764547465200211986278228782024036452599026354617705964647041183230009657954902\n  4871371179156318995621081675428352688809117989183270015100894309335022655098804172681489088122912870\n  8295210976641544476183309811369127897747712298020213321274658985263467192662455538831927714499914083\n  4101059524872569030654767321855578141002838442058890414682109669054337555206532913423204111494441007\n  7245985564152890121622584263525511470785955532136098809328950696448376187763252594271087013146790767\n  5027632598732576679119043428262705147524536494231169042157035922697585321023117194458974786817232156\n  1144409284498744812255972316167944415034458684482061781214268917234825687477876627836168367743249408\n  7732449489886910631126003804788658181342462107208455447364215184728768745937138298428035092082752117\n  6899384594910962462437545367749182746541846734745927049744842547339625754198994080811398880961788701\n  1452014324499095869529262140219339730031606517359189393323587541379546540821388091274730654354517356\n  6449093275849006172638897645842184591345904519770084034522599909618879193398402889543235627906082493\n  6894154632361167752940382683462355519428633099565126369680011564888048929462661936465231843409883458\n  6027305854133387446270545353835020397571542522128525212821830130299332661790412226923870614682842645\n  7480684458555758248668872135025417309371260417969124276481319974611402653413800502024718139556939770\n  2665136484009479262014589759138181669048177231659380550527069076839774618455309912602312300839997984\n  1076047829385141598878724798422390914376454307318765451890953265023109477426368636396795651027995433\n  0455019629951028984142909911558001888557617770337346744546784876147552509669944506590337393015003131\n  6083832059972984457035801649539935756873406560221992121815670455920865803054460810365368880519721305\n  7760336977912821309760536858063007951517605647629964106247398349695899949168518709749894440934598359\n  3523263468128802598854253196513163595894431454200681572435605398018596809437149428655669441490034911\n  1556979734615304236866068945047000453891921643594562912220420454155483397818361155128983312621025076\n  9674369298551683203785418677422376337169514555308472609142939192564006809487739878753639043132845210\n  9577870245721680367654253697556693376916893721596826427575374494974180054169944270856774686279433457\n  4127819345975089292370144992534455143533966206168461628694631883411638168732635660966844266181685087\n  8358302201726827279515949196298894654714150300669941787908569445027324080377784271503413853735560505\n  0774296153837658200559422209594072775101931880464424558912948593645383784405015959209169180992093220\n  8512267292474920514401517221610979212210269157230236569349855124309230660305936577985029687173529133\n  4499724162964734825673764078783302942775073652195965175395117328425384809993466669701185413116405189\n  4952655495008143931482664881444646402094078323539342361234953898624815016462628725140684415403232410\n  3038129212028434275834077158714583810420168862545619529592250289375037943829260402097400297659130668\n  6065952755327510698794454143399655516194986920940659152382011727678666162834438312481666252038836576\n  2541266998454645663056269563005241453508164490795914799096477820024481302876707249446871007039715991\n  1375934701497108624407665152147198933063018602130504808607034518380062795641871228536242328066541232\n  4259297091097700292972121994744426228543308684127337911626984752085482300415690572101220265546980356\n  7154815773525190469140430937889334079783576638924079458310538093398617146133213150026795797258189622\n  9057661511991624099919326321505998246815961203508619616218514095538350773709738165512965135202631895\n  2939243562395145390317544223633130657390191841231458942990560684292537598977918245736986947330423936\n  9233735211154133584762038181426924586220681605170577372233329961192988887052130039696680004463367180\n  9692370885305036087584320402755756772967005007093445629219875590098517416117101049895879708446952195\n  7848116947199891507108449626352546703160579177421169382207722093235260057182342362393439411167924584\n  0915260616864130025591430568111117797082777361518323078893856675090928097083693313274270041040190294\n  6144372591081348354917074104732302975622169328016927704919328931914111490886972438904204922187582597\n  9970675643926559694021381142671289816729574280407646858336987035423399064120619089258734901166405703\n  0824007649122612850101872935100246046182225683153238261980699821183840107194822899896073720109075703\n  4014732667850030562583899804980719849773423190191747246598372272074210855769543250590340703340504822\n  4226143087628088834201672994184495616288695892134723418576797210819805461815839733317831479781392885\n  0648258250881896576169717918714150170609154500399663989704484130921254691232004758442453751004184464\n  7710493477384411257984961966549943416890264371295126805623028208527087804399988117787752643841823140\n  5761652466193118860690405132423239531733139514493709568694609307469314164276161660931859705889566352\n  5960237753074830431316525457281206579123672849821857534745553875476826027002266247481546710531782539\n  1142737172074582716509627640099158475043363431826546354402640405973284371165072254032651366553949818\n  9050993479379819858069782186550218132703931536004981536976329865055365877436341521795877561245185803\n  4830994833708860254890915258282377983668348739557098706627632980572519218791453602855717737671378299\n  6157796051868521774624727977445894561254974374283190481535080953603345176201862224601260462488022681\n  4489030208699540534068141543851849396599038459111745869040957358146683360303234564462806343052444122\n  2099497111347024145602396931181520775528928748789363961892837294870079331117133257969760228398317745\n  5775458612993110518107239694876579428203755884462077707173234133890415195554046475576327027653380107\n  9265904501991399911148631955713222124599327298591184973501322417377527672498332161573711800569092997\n  0080181244718689665787726800545551153681979719882684807894522754243348703672318842103520350485308724\n  1154459384754965862009222207569799320338036937197011862068678541949525556332466091158655042170617676\n  5066648772023067335212871229572864628593292686770613076925551413724934001927652248539432700595619641\n  0907039162084403283279898661939875924646768939114950318280834793998604665837250695021325692175649023\n  8876561524018521701221162127468589481789850286474477872880522352356822852035937224412799366379674282\n  4483964378068084949230172094688777742518660795932453717290802613994109697676546634094312714343688065\n  8920699238896633992377814747893502809437366027590036462416130091873498595963428047847369567350496512\n  4278435885422229450338001132620039715846114551960415420912023544705338201478038741000722524862318388\n  8193780192165821037441670975857353741134083939552285787470682184294374504489182475143887812334555863\n  4507762627021771657630862420917470500401708664012755923070392599025709615495474257433275765180189688\n  3382854955713228848591640290722819747439084329162549923360313093772591162447164874142268157619944324\n  6160572956060077755727121477555028219570885987610308616526997434567736849345330753107855095203683421\n  5382026867636799048087551299768255483326900052195031300284825693688810115009007083340100905416054397\n  0501044880124123142517279266978094246624616089531136154168053097688007906225531274958649556987999188\n  8536255300611324583354828575063694882255737304037192527978009324019657545394260194974997779469639167\n  3674187369879878250594371175061368451255835800714655979918322786715428353719341954906222489359562248\n  7235001596551595820360278287417452051357454840974327538257555219568073477789127242952528547537741631\n  0543712273922030540663165394607929542801194972285986886262095970577136576745769464229858567404085499\n  3161468923354856786331441819221221368862997065403171115279792138934362829963788413277829395098920549\n  5568478674730118373845505613147815705416301181460518125831815266099326685656447494864272361110063990\n  2015319341288259832107369494952916086270297793904223636251591408247034324703681924639827518952691022\n  7950314933730899837799279245439411604715911973315412320997178133722888601536303280053212834939228219\n  4279859554554166792585108532064032098488506278156616214881284667672704162016898436880694859910074525\n  7530198237645384205604722679798456326015055493416189255332635667717529430341119018787056822355471201\n  5982950289360956336836118560837692702315069334026594230419562045967244077011364731694969106130497283\n  2176408469533539206481500583501825585103085490348803833748183194421881309584774220376952264714441724\n  5993959341190705441636307972141768559382864112094716562019410130765693954697559964008297600535418866\n  1788231110201727155730225505952903350137402586928542771974669844636030298141183451832193293466211910\n  4972061197368362956703341942779167623834154639216655897206710021103908596866839052817371965278139213\n  4501547568786291318332843345475807220124754674876828981892346880324971215786221858465238181791603387\n  6220544502610535277301691773664780882417390884452589138524041891705393013605620502532289090913146599\n  7522304654649626487270505042798563552499956894354846562905335283890524074768282346944251242205243214\n  6049691151599502745119211568291361987775744299750819945714978774047543664667121836718639985938647758\n  4804973795743103135561069226488933237941886210343030099671295756250603303590322176674941553563372391\n  1688903236692739237960555947822231835025757695690484995783553419927080045371029096730804871931921873\n  4905095783279092933409790112305095355177878797425730259126615147330971950212836644394579639594272143\n  4847918265638596525320195043897241592694683925242421860380728712661664237383521768393446568942250005\n  5758131518403085059725619469623569650725848509348137829283722170682289794264165425784454200928474864\n  5428513828372778381335135819408279535792283988973991137735931487315643412685577389382827974403739403\n  8580890547585376469202656818166100037622459230782536902831976059742661345582628952000747175198661393\n  4845228586067098922913986007376721642745021841899068751282105164071420660638958780283243197758108844\n  3726138355462961246061281033813110128147483064925001565512390649263760563155724150594446447578971934\n  9309910266809570814842381048841857925500513676842913511411251757939022262587400884536416338712775753\n  0258196237227159074255547573401193630835292546627694571481133866548463902123036916905804954067841731\n  0559465918598303503065831399068316976483876101199519366253613888976226616508466733759478466304203938\n  4465890384648834728228452379531706994116136410819446969967244407469283923641305679339230152919108360\n  7535780895440722657842315084058834195478235687997366218421868049687643075313951636703662637544391351\n  8542939738639303504732241669528654384395492271047001209217380103835760953115694497464875956857723939\n  5946125495083017942186451249760690958553284814130398283321957441569941230839326637951758977091254917\n  7973118459399261534522139961410983491061840577367414824444133572465291503100508044625750253745275459\n  8551539294860423302145828071311737531913940893517121551804301704622055447973766966747893173096271481\n  7804320524153739850169540905116883068125314868090439523232437602316225250438836689868570661653066181\n  9045685274746655871617726585165073415506594517561366784259071595185264923266119894199276978330288377\n  7941111750144741042290808902366083391940652111393237267613597885389234282889008977305473363126803325\n  1710912983926148497000542686160299429609638488644406004910294550396652917023423634660650422229602109\n  8785880069442156985770536698448410868673105069630296090619342316066387489900188289495125615591102404\n  4628205315937709684265648034603378173148140538450449907592035509064459099090914452597256714953028272\n  6452152739661221826041346147501028649224457265765754529032405471437060123443121775206577764552719001\n  1539533425054180753912191505983798526157337051622954411970307888743173998914579482534998715896943787\n  7343737675161566395464762435208186531597510366689707775832838650575235805017140232362041820853877746\n  7983029508442338331103745806536419079447497062847706547679482962188669259068217600673139160665816078\n  5832842513862468330626033667954679124922303238892956877289476121515363960309406276531197669010911380\n  4874054937787515860827573236354566858067490627165972159902992186708613896895137370683173156800919554\n  8277920465055777750668885211866929765211039077863184433695906723520283999964323963876867320361379164\n  6686795031121791267912049422686319695226494152603183846016537045092592578800424405944349467622855508\n  5452556602069422687732189463339027671535820222547033122347985668270282524598801234683953776355174689\n  1225367881238189199546378441270332418737376332561304223327118444507497424223782661970461040111226532\n  7588955723849850576364804940924804011116277087155527988407903612572788359124144608103336856769783495\n  8256973338399561692398900085029353534299965740696377950214085190300644954777473548411684055102877611\n  0864198567266226787228785939335839702878835954512635880762654146340514808297800269911581141860547629\n  5128819943083866532048426740555551025332274613422199310361947772049524338821178503225046229221424569\n  5555003313775842857102650520168844871279318563741260727741141786989397154226727632286584861696775818\n  7395294670929434525373350650056960134607318025776790991551345034841583984675265057374239747147481254\n  0093578195354597345847076500744709732549393103595244087802427666984630842644463867363801628651193925\n  9851334195630392655957116711230449799232117360684897591755826316223902262248984622865793572796249103\n  7640382310408048197494285927024632127390069050749887731732188546893642438942096492856644246175264232\n  7072727933081557155886648416319531614117369090813201902738952842515499672243034890237632805437291613\n  9822725299083690889249738852299592377545012678088732611954616362090049010456572723812186073402918544\n  7799535289959211945518805213829562617740804127330379420903678075311256760080426049507406190564878080\n  5023437355891615538992746563307620080099691290761006320537323126937279620073905433437462210258995721\n  3978891909703175501973559378692404636111602720633833840903223989418916722494065846038688359912725214\n  2008927927430986616350795728379051438551387295271129836678961619181394864073685794226166711785990514\n  0382347291400900979224913024997870400380541456406429066379039225230449217160958905202817816159901170\n  4358289134091358894393049509659960511332429448250983651074985148901512823058472152580251850119996729\n  0923019534159104663497514809765758541954441938660301023932894081909479278480783045240452965721750860\n  3472258594175772471071244270779869072099558068222519789986479329847328307793432374088524818024125993\n  6076280749955223104632199106829980811820415770202403786723523630415869096428133036466253394949402426\n  8686257659183352224135410200488785056997471685240672865751943425706257347366754736503125572083747217\n  0777317324261128030775906546923950229067582820612767349847106351976446644271672093846156072556820379\n  1375209490395388168627203084219274933011968906502185542429917425792226204508851936642892877228775513\n  0094773646300064241099299000459324667735313744405486684875877715788647542882513257102499583552305099\n  0406816463413145731448493938698331347774273521501166697679503234920870266706333426771215264880879536\n  5929937351899242067225119480731326592334357720796452977775486743842476892616068173391692812463591354\n  9460964501115658857292538244691171975572851078655298454278716583023412111155300074663525550482452345\n  4104857318779100347623305884072578334984425498805845876271348453269204022568383164232223709764547140\n  5091236413440636195922050000387149001957833598078100859888605597284847911653207087459343563080218716\n  2111489589626800897330821420606706376919309905812237161050163381359939183593187130304492618018971089\n  2820426100316149965985859667959009433747212333443895178821392131689613734560088472118340553704173908\n  8655022155389774248059789541723435365861490158428369474900604308895256061113875543858496272691509108\n  6239755480590136238040358262600530735745124871077414263477512509773977309390725282336321002648028822\n  9727064109520105288380786769462037156395760476611450058080477176427287800131312774132443027234088512\n  9896856038315246574743679823704601279075780608924227128322264403079900615323141020797123800533820530\n  5121911738709301983853679081734700155973475132833216025461225027248671258349531573900562069353295402\n  3597171539469246442743880275961486494129247527733741349507148780335377866363118562306153486757767063\n  2549018682958003825878848517645563087087772192083183889862253677915514040364912819332723464641041042\n  0881109312609839618401855846370235435946724857491530908048594183126096729940667484419440084259832175\n  4803345986174002004313785082861832997568177657103119631581865995049067237979178736721907515640653437\n  7644763062170576698567087492270750280876724620422535389447414241343631101664366396998808785733504534\n  6724540669218104268811566954384513391960569769130745213394121929508769111217525555025022707891471738\n  0068542365030323737486778702558389059893630502100871664697857118051661731567029479585884426271984103\n  5509462151000546726532666861744293511621047567390241977309661472422087045241117074333885178666262283\n  8975950520312887201895235448217394782194244399758999835006078041238792193065679325724872870197685892\n  4652325066961147397300880047710443386543722688439568250088571648130946844612709565431395575475805079\n  3514267563138193621702422973187848122776831895740704846233538362165958684330857962853761603136764747\n  8472565866092667662925760874527312462223550441586597063699892768170434994116812797928212969226927665\n  0708667244800880233097892820355930828885978535341197850211821400468425054674025497714173333668952304\n  9168314443762977348272050599618427960138243826409005405005054389956220325769403114107296693855412386\n  1845341651357163376862041548822631196037539535157965115615791687520081674536224127084386082271549504\n  4441606876735071527867361649906840791020504384460123082621949618692440030831429304478409256311863207\n  7751264305941995949177170641308906867774638543917793819757616446811106638932358361840915953211635978\n  8090633295173261028171014866694864396113101717553654033227890444701001976312123410764636362458309773\n  2689325932774191957149924498559646976173046729152699247405557698159349663077375470407104034797497551\n  7710849312135392429329973675722029345975758802576403917756905121552802314521029313049965333937302320\n  0920505409685661504058680341637934252197386129365897185693312537414578482782700860598921654039560817\n  3187429758719191069327571217995208732082698186359846006727643387648206815611367912284097379440355613\n  8714059739036867993047423692350310653421466641916361401970239342325752694299027469339644081593015791\n  8795154429053346261410491553156884501255855500091332206111270101844350069521746173065959864168810938\n  1630424976087706154578395449379187191797782140502257904967221220778160238014923812940085463237140405\n  2972776933521421226846185978211744358524205910970289419846246899952324223981655590466771322876361960\n  1838487431946537298122963352740628643961041759162471820635419743568571300716754368106285383585873611\n  4148832792331046006134451413086470002471956472167985528236769001963621404356498533319768880648886200\n  2046177902558022709496834234610834925724753544521339268873693931289850485958822328147510381188809460\n  4514397803692352923365109003413934584678504122917413504943706196058666194826656431821665662964560637\n  3347509328955343251749727379136224270823935645582443273066007731554713017808401693196075223441839922\n  7001189768898484463505526607269164237837900804794161768433438322845853768413811825116775638388925839\n  4020120613567446919670757527804706934458182769157795686023249588411602895983784051152559797838818410\n  2901478476234508967028966728888964765797782306997988192708835134933044589817086468179711128381820020\n  4419749911772154103420516542702703199984663491469520761598650684885220316328732259038150648355010008\n  4517784375450743614505922194240241872628249035634126526431192655030406320257536605315091862694230400\n  9333102482986091924700441157769350573870042859048669736423070558612735640205404826776438809032580278\n  8508769099480925732901733117165305467839238783985992084494944282354551111075567141794156706197119864\n  1995640898197469650383598560001537763197865942684706532072913018346587824492507819878301123504261299\n  1308041293778671171441743649417041309599842774961523852311952163541571620418554261725773289754274896\n  4252455836900805206971989783405327952496283264156934156139985728673098742262140288518128600190846032\n  3175013330780748312361641782613805117793371447041481211899591909802237467877728128904530357995934005\n  6720430564404493547802696346463971915660009263686421734741176193906414540231793906317382851890365239\n  8629007099830986252248923437122606098581030409576388510924389509763364947748584167476644141210442699\n  6776851984981650675379539545328708054990529826809162734102724026108419569462737591630570306936049304\n  9551760291677145256732350336713095707817696108902556901313383745115817342608720809197689623761582472\n  3279969676265949176968903500018108711473857434983640990927933694547181562903452870089331778646260018\n  4845835027509394656574351979662469396278967133275300103362167058028060203271745531773549327571281289\n  7223016943175659529582131377364076503258241209583942276617489875728184847630287518607461981595309145\n  1776753761422878153832469158203968556471318706824864146943554341864240898653402265297935042531053074\n  5564744585987765188270858920942199651867033066055402432358530574124988971883964658269498141403272968\n  0400985674094472202944414410268192913411094218741513282873310798232925145066107827921012180103111970\n  4277690769430354497528305709508933635333331851096902389069806293571634303881507485149898279017106593\n  6441270747611298518681777313704723445403745600286219167913221365782707024079509967914180334821962558\n  6266951974361124884659465827287656449897715944442118234927551749896827448384642155445225433577710157\n  1115312646908838680103921379271888579610984245440176035892736009257986197434102460936289896955972601\n  9190217380700975580237538083550621119923314740908846814351990335032977622554102622476650244698571713\n  5357265288218568611239302212235302190516277356974128634983540839032773548105080711638965572944766845\n  7921741120944840199655614355306898308612084948698645171066737076918157254460466820282052648523358699\n  2499908059551927828814586941368229897692946966657523038260343104885807605511708300919710119849253648\n  0728361569767818774221507110373995369276615245244965350910034528895977702974277885415339785881066071\n  5689492621308277949265494362107345696787855068738556113335206511000951672238444435331586671798353595\n  3576451196680957452740004243401544004906266613796295747065274075783714609400233265567720783707945010\n  2526980479349759953631214724888120659995044732454052956949161135437651275923571260142803889143997132\n  0628419546819688588417529292266886442621434063384323544903587183699050534709475844958153940545298839\n  1465186318150939736233214054509690894535311623502316264542428788803218861917253625798092179692510697\n  6631553486672128902553534276632117995418894408023111712410789106391179138011169084156147104326412032\n  4352019466878197773271630704885109519004363450847138672677153789281655621250931993308461735522700918\n  5624196261048152846404552681817698323603329448717990508744856244052584667057078202967384386993693546\n  5436456444723004453622737526653145299219622309881176456806767139785437916584732095046944304384883707\n  7186501843256927011517134949617369807824269408040645009225068239337956837176121539057082385854829100\n  4571562854052309447709233679921158488718861524422945904780396105235477529451843291821776470401267419\n  0255625784771039687550336529962214488179352640586781333262159209134904418941231255215399597795265706\n  8257462407649548661139248146700657227719602495734508058408702213078799454350725560360218895109924837\n  0331300766185308525391274076920389698099676917560701484757577914252713802209415938774884940496468312\n  0257215335558064888819994902449124874438702696481904561785671518215321421458688965726342557795756265\n  2700629297845964506174896425300021092247981808889462516757327350029677147050327998757989962912792874\n  6607578196479484752392035222645594063126283248417539754817457010657092602259317232087409327491400979\n  7818697026014374214786317938531308155711671801618419885007706082881144649675351462171955213852392511\n  0419841081641404822044249417827953801735743096369443649506351874820396050910708920984431416784064461\n  9109367713615057721430047516429278462760612587932649555864471865902984818220160210049977198361803778\n  2118959565168922539341826350103713632115778121460237093669106321911883916952705363199942535844908602\n  3980831429872436326258410691536617915011710034582739884502300190025577477431214334215609102142563004\n  7292952168051282215647987913148361230334611027752033829796984764875107530862096284647678635312023068\n  6050987180875128226550528198916999445054582528742745970634022960335685388694979938282801471099860087\n  0595684841215196473343476633762743513560052413635371901147912029922253153318866025153770683310154889\n  0999536990171736942984470666770482793224482341820656742587914678111518974774907255848915546647004332\n  9222039895064945277075532932299426267433298828142825568965733266786575619337195939080664291914750311\n  1328446751487396357728793429897564133604265814305092134813679852888292572515952463686670526471898396\n  1963598492113415695319863804558148479071780907869529272791840452294301029428367110839506348425063820\n  8555865392327654528622726648834185074874139385493074176302795550310290813677069430289701202531770184\n  9418209149792382963165602229836198034820405795231938132665460972135883930448521662872143525751137236\n  8450592929824956114742268292183057942653346922593252263720317019199984476757154104896916082005560929\n  3880438561539393886108000388931415514251988072813467570939331543005256903783714451599730234429145056\n  9986414675950303181271527278942502383466726331733374558809943544395003677567031091909407161141154055\n  7340884834283353599319214437106006859366026469934657200936031623444263821514244283917159614658131742\n  4731705156325348237931474944920069795480164682189884332759152807095398821268398936423181065489044804\n  8927684892185471067697886135033352449811386163739573102680251642313394115498106267049750201361285327\n  1679450641310008468510052112136399583903140226191080728990981630702063541311154226660786954871773820\n  2141054740140240326319645639300962185517129143265244274594414418275602144551534404540028743249577705\n  8449408098403302725818096317965249173507014948466841572546592899494762363700598048903965763138240276\n  9423666262269015147894711690498025494902525878222068537260457330359730907758353931703088870854234953\n  1223031802292879599064050177373344213062743143128615220905180899239090902879120512231186846024133278\n  6097500246750791712605774045752925643648232591599931664450989019146148028600254823438719690337398705\n  3600376311002385030885515627394262315739071459324738698502972134778226071168099600604407499093418534\n  0057217199340913082088234123050761235269621245455084222401498616621573160299790401496699491727462378\n  2673017894094249596068843773894743154058947327147016961985825091282157140530857846619186132280610365\n  0342003901308140379286128430225378811284489468830537103303123570043462316590768763089808395415916852\n  0545880947623711927889907467857536699281423524704411716652528910036053775597355884354254237465176941\n  8514470731452547687692899700595461349680397382329362389980198620565056246066813102252036805483248433\n  4969568965310038523754667587856799400946425372666150546757091298762361926700835987626785550302863066\n  8799392265099377398846083906682082066230124612997303780115748296449826052470590020138856244146334105\n  8145336313282560532052005929264808303132120350787766295846454418916953734242813903516292914225048390\n  3626144425573581074868348925185396565314981963055712419995035132382195118696723815145833934908285975\n  5991966972170453430432731619357189676268639789788684438861190418094418582586957960263456303755247758\n  3111543114762035938698507377670742765108248192897681013385969978614342443000676843942075955495740760\n  9325016782399296004574035775833310658604115555081469085084839959586167662512905315303224394011724448\n  8740345224071805352218797147385313216889626028531253487585855672513707818686352116963311057203172237\n  0604678119508611426666560265806290848488172315565972646242491374667624461437195284569352215618440020\n  8981301595486002990251885850735730715293231231813184991789363734145399134110220355654105101077243598\n  6055631748277847240137983474630972453826070078510252638166027436710934976867796097426453923241963379\n  8976824844220980191330548596452868142462908735370534116434769696472966752583007869309307984984271168\n  7904408338186326775973380325268242243329680739506418067156560271426821123031234294855165365321526945\n  7610646824700707679329111011960165468779920874150621869243525586056608143500705463657282512899089865\n  2988276265682300743770361058062226645479965700376271442571577258126868254662946872399564065097283240\n  7761438918770424976762342214513091793687746062916851839024680313643989741696135882918597365538906457\n  7513081193455198291814912845765152299640726298338964187393802463224707363927685951291328962522675690\n  3128989820889247134957014294468682265559575277458228284299728097773832127325305141699246552250666146\n  5591357598655474894260157123808779428472791143722367111530382747753341424240717948860202834057759385\n  8604743995094332651136487754324221472663136485905777194353727858104371833790095179817963113508959960\n  5570568421753214407989559231848085248780836755006834594839342478328565635247641894933649224929770885\n  8162423150204913980435904498100431493233010594490247471847639893163168444347404750568117237464392161\n  3431838126854709402109279571879936931386000038468514368458211668002182820129991748092639890989566539\n  4058295888600282744802699916980106424049242658107592127246906309924560742166116941838972040284553170\n  7331523151114205678509496575612039007683156747627210704573566171878402962624872115917692632706359138\n  7678465536199985983182304514554009697426850377501200832133206958860197305121870854184388061088381433\n  4713432566689792627702443419921807686310016485733840408240758539913655790811783908542062933068122947\n  2933559716393679462033539152709063720694673423381513834269471410243982243883086676898962441571506447\n  4790566932331808524642956292310160051118640956880068052259396549137978135636662786584825404606873151\n  6751685658713053052115870559273837534786890808148447224684033527700001191254671233038886156296696015\n  8721813302472824787916219784911643328606722244635288310532085836045805147849852094422354984713141131\n  8817352440769169838170078031706833636151053133551533095846623655392600802125833620966795554446296223\n  4869224431908474639193517496015959286204453799127924439547619127992304158443289127305216912408131923\n  4088661680918543382424029454461017088275160881042747219249209453946970268602852630794031070690991309\n  2204311596450429819108579944260900152451424283341581548822767582003641525105027903580048053428092302\n  3699820894145946331693593899070015559835064469082244498619717044307628693201445951564848777012594850\n  1151405397979633930100438405319067907436471299584718332138871109099823566722126380548683874189401010\n  7540013788101839315914880874786587879500151553964407616257750818635821793101172614404666888481821945\n  6044051379248831971545712438419343896724755144423665893647185182260718836387507045929451981123641178\n  0972307434095521941405244642200902221666865483560810185144317155508745203070668135820388435215498794\n  4960394947296065470806398245627394706397440640513789295335728586689990085990869067039434348708008176\n  0714050432569032008815369471670760999678083787526081073299247949817333213953183877832823591673701258\n  3124289064735474215088782551498414142350130167267508217911100255797251742760073937319214210392603297\n  0810769819058988038916181382579914443432210529156905787884745821110382660549894669376430572820094574\n  0752925336116365750936006367349850284388726581710725994107849303081301175864861158329066057327427060\n  3069996948240058608640332505107457077136203520688649462344119056316806989240695412565563981942471888\n  9220352243226097231754888531728266773910375723710106739337663808981515842676046852036203672407891490\n  1879273556180766175587818153830714572203881772971875938956629614975056785345081345976592828371823671\n  9243140097410543729784451016257543958762457903820890293493150148104836451353888928030438603690164265\n  8923162207218966651935591627497955048009255515951904618606791880818722697029796220208880024877871779\n  1258102117894250727613197954310962466401977209723226100268637455300186190885982565656265279366085407\n  8228115251551182617048217569561541627851396377824799523943593124697524369059218677942638333073373920\n  9231890347396557573966490982052618777270846169558736145592952198126893316443382397314238472615945308\n  8525408871886577640223851051087973101722522845299769476173758249952632471411817301602018331119181122\n  2813508856982100481816114616760485187369995611471710489695145284969675812583453612978034773231329653\n  5965223906335742142020499047977949714036872153280706435798771212837235867186123284810142893866885703\n  7620723484479675929144219538642201210820779887655110250311529371693291996515388780425162560257463240\n  8504228844997762389469269631528657293741343016936007603532936970641782778773779306501056973945611621\n  9240336676403090783541455138316434889449979237557815875014455206486934713086498330073898088056894346\n  0652073487595248873814528563311886966371772606539290129962451213621618212497585510924608606703292781\n  9860265252326322826483572273239183834925820212759389405715304112736281883610271502536481549937009962\n  4982612448826291798672824976494874375237721882327023286078786741446467607560018209489067346574075767\n  6455255636422430212091679637261321178552432544516726617845496108737903746066329417692646345850239275\n  5446300306386677951156431097661700950080536746629214903192289315461344795220517567305078224066541216\n  4309774725130449522884992542381654379640699109303726768644369877159674558387881782369993907291362951\n  1356585921262470605123799207098445306806751021923597625803820917959940362293224160002144948306949888\n  4798402571157588664260148826172477609227552782493180061245468044327036949428051996932474056765621398\n  6896794541045778067938189867874389603154930808754485087084139693776973877043177428658169640187113187\n  5555139837434149480436738506910996892834084554865883150782980444429217813519681652065459628859248994\n  7217333292060737007254838521659865898890770988354659504458514681125195787272983135614348787393577890\n  1650631075864406944483973846508885441240799357171892723876043392675414211824046241390905429387061282\n  3904674491829046176385817767365973869331068507357006883922614400496752244109439386794743104730175735\n  2214306870791138992751983374317080328301799688937442731252158213563170635121945802432086185211252156\n  3609484108627492827688256250168628994059815893041995881642867887107620110956075974128723052213171260\n  5071600536828028137772342999917730050094327364174874089319317228940480334599855226410892982215449118\n  1471363488518083295243711560960510757651097870387631281243959587830946173490398347583369466057915452\n  2058959144056918656096427650852458957058774828812041326123928589487352356033810431400035728912378562\n  7432502504636500743890095572740636949446188365286660543726152454172205829830850965936482841958696169\n  1157259324198273583245853831440167068161487347508612648751989780776187917496827001171248189184661389\n  8797807611495726137823984153462245734739133766906177880605463474924802150100016241121217139454356212\n  0000272927378809068638911983351608116287091044323730701597837680528428190952153900899546814560480934\n  7727238999210771270883119994083118190220414788829239645428650979881116428598216955662881290310706500\n  0093202373656256754844374179931102181762310080201404616668489913449894241224497019175557649285423992\n  3972482065041525370392288105886341191972034439414870165759984553384786876567773477091766714680382367\n  3134016398284078802053495468329590014417804615539401292235930446998544589414974439097524012233423549\n  6542515475897214184893791435027789414016885281649814395529829554011283072905955477612250008820025122\n  7256136937374376926594900873746044344756874791717024790073562716781833766636490104058900490891903746\n  4562017867738315369910284000822875981974853524725020143724210479284879675997055778633111140447469807\n  8827521309539908080311709187392213784736322633200766495163505108258978872205344514715051636392345586\n  2358747744662242736212811092579582876119166254153684657318540677262662818074645612365270570261399929\n  1616530551980465265030554548499179403755411083989139053949669149956241308657657440203839651663557873\n  0617890614207972461756714788535806936170019844579843509116551020022736519845348479824964461874462583\n  0476746482617361233386321767888312504912779200926688484238181854808972739446180692274654904673210947\n  4947459117309631426559931051181446498491646573488929909562360569180745378234301662743162359500345076\n  3718679986930718629506983311087556768767520957403143485900228811237823624226101946741693084249295818\n  8229097115975301249041505839344052802235065103086218445972740352939276989646953854696237284285171887\n  0062273433716976454998828682355302327643503763520442330312191859473589456042668354496126899092401308\n  9983378701351245239487953845969039342470609246933983359445142833816687683906014541970792247310862821\n  6859276547233642121807873842997293257587252274196921100888994834956422769640231142753912447443241958\n  9510468682513841571172266308178034083469444691605476793293889420433966208647272271340585034694769837\n  8481116592561577153522840427648249729162557314786408820040147197345096547770301284755681410163286181\n  3732440985906856266371605889070719967656969369557771869700083478267984657239831280624856641195835594\n  6686463368241014706634969054555589265162962210076841661897345442324855875315765411575235082441977440\n  5089409900945155868296661067096709024218856726351302207694616474196101248350048832439909968585541868\n  7667730961363628557499053167283427905552087494170066782095830556996249477733433635071383166500916099\n  4458603070199120636209472616281628154305055797300197875513378835228335930191701502437749238293956379\n  3589629549538010617350700506211537941161369245401779331106731368079062915857711534352906341740273374\n  6525121883693915935520571525480391410141160760734932551286532242006682870834932947027112382304481910\n  8063670170555516816605161708525775389709427072966869302260064896574146620726150470861373723724645325\n  4378255759009256753842261930842019301417055445797375197530047041686118589733242245538937939958889725\n  7396558578662120421137705850100415363247338063484930878170556606153341128860737674343207140406875176\n  8453010249189447882289246709247645453578114727268341198125157937479385901365363192228537725907459494\n  8916500890635310373293460482081275476655448033468975099417337722730080088351386612163960876950803327\n  7446327520211238336638907570173658688340714324957376376131890231795720119331834684075713003556003589\n  1019144267179484864097507034891571557880121672194813174243874698484019368355064257538885953635406457\n  8459525802634894053684852456612071352028218360912107282448603570984859862149911072056038245919485982\n  9823543664747724431874436259385244319349885976950847699830301144277916640235362440694889364336665191\n  2063300227069643142891417815651576241366067940864427739315087645327820000514311441693845021360245385\n  9527358241280822840514800724995059504215819802203211911703806022726228531527782250798281601848480446\n  3884542381877821710453476165937626072970888421769980440600360950716305937923533727603256790842966377\n  1490318446980759242293061592887578809375455664416098881032273324326116095521520558655728808412282000\n  0875492308382839802493037018529206223877098770427810125622682864582582074893745065734680589573571270\n  2446993304075235454486384826117949774906522988066396915491619456757341717414665666776155891302285172\n  4937498914231544042036008376023193268910997554626585144244130691699988162808907485969048306877241500\n  9109248226072211953662783562688880666917145514720406546986724461341839275466663949242227578726053861\n  9426620379390926492695130808143167659282504876472104863583938056093091373069208483881377562730641491\n  5510911084412526884282244779976582804516708878961001559623254578416946031392298780545287215559674980\n  4085046227082625986099215606656776059196478661965350118610338730120681862698898317555385634933349620\n  3625458890583539704996418141434400220806029988614134685842391393401535642324721425301428591205657638\n  5693562776247087717263782078595318143314668428861440577879484394185441455390118963375663753705902427\n  8787829869814914979048998218102052906879742490994284322732392927379229358949375634604471174134618118\n  7637755675531713533286944678866336852529977913388840625205355767274522687590942502698802623029029591\n  9800718727154390507570920489474278808112161753705708177786065723273944368967597196132409349773380717\n  7485067680661100024970948317758504896131681710471576013281159979796697117964893749365801828293146885\n  3266706863564738459193816300614124738538845590045829273118304531949237507394953597139353273415735585\n  1621085639294721898095939341482083584956933469183118947980144332181463352839107766288844960868696378\n  2651073755036361644921669180879049103339948482442207474508737919354745696156441020723233200904265039\n  4967045947946721723223141046197781792322796891151603338708596999475128428050100075079366668644883362\n  6725037759025211026258813348489287313666404959347028020629670055707734062202975577334989184277808485\n  0329492415000656210226872992169408430237869071121487459408905047676091555973770140654311513641993910\n  1532216931977506053626463245629378601040851025972253251730926509659234796949922483311768116594806088\n  0008261892370405949807704001739674582189242954895071687713310010397851533534531471068595709445060537\n  3359195365861719631497006018216015116781644587779937232745484370216719698324035215895168535513924782\n  0559128279615349166301514580517888411480971867069842722647325396278568856218601357551480258411912578\n  6169815402760912705074195114039656379289828828522740860145039535211265389538838677939951729586292709\n  4784127391152433112925946400072613464924997268181094515144033606300528712881176345574744004968524233\n  4339885902991306423665017309231172549322356936462708264736539614701936146564880823663856871274311814\n  6280242967084161021875899860964969235031298244682022862410158118338086958732157760182237896180157677\n  9989263352748408957310408461068537718696398441318584611504148287305023118066959863417933895317469817\n  7066866352511778784457585311149522528920915042815749224555913847113304271589135534111423495667324043\n  8530735724622868469222840837937344847060291693601399304095065459619003081838025272825630822093726975\n  2752989520766338895811003934670501955027215254070784222031586900159951308263848419748777684991692392\n  2196537231665447574407641010099650617126279590178098819258884779270810165459373325352841280200757510\n  4825911652513757834010089518476852491018622117355534863696984157401995560286512422361874058340908447\n  6878971542125953035591327072076061508973819799481185638356745062572946951343691678918263066507952431\n  1558263643719976037744462018791016135424477006273647656549196267616444680772190922929080866228112959\n  8849247811486715342571553676031195245475615652369677038537047688660469802138524803056117638206875750\n  6758136412862878013776514061907267002330978458776691822833391651290787076086693751711689174162769080\n  9551757279698052016821027162621360697060416091561788705305407209797684930266376389686627360501139889\n  8836733591351396031547428897471385416969392931830868002123289632959938127165372211852951450167108432\n  0746942049020976670074228274667222156833863413023286091104602401561230498455914095239210460975654364\n  8344461508550374997059553366602213462604839960122732736419106949439922465245700052391362273333832849\n  7275573933564959431552309012332305634341523510569628228677882109308461215686611444387076095828406715\n  1875349808971433102743967023207286830105305585474061120710903593522245318973774892872122393887443165\n  4802090390081081088526692277246193143825290972586311246157795502759822070616687080487695005424198755\n  6204669927466398863934848684014223352872821444039547842289174547658271945439737217167460006085368620\n  6659734305152428332728939125107799228171714059172236020738527892642080373792927864355780211583575735\n  8359060207378135471081449504904591832117553015450198368358598699232679936322436043562460202847050065\n  8345386692633431478982991467853814916433293733770647285611977754717802105720656241678062049249605068\n  1014505544400083691585386399196405583027286332121027159254780491989067089066871512194349441699015818\n  1216296916452965667288822617346469987438060666365012549193529951563426706148368629787919482858285181\n  2784137702694022167558068283567621527125100272253217550117539167618570824410005697863552015457177509\n  6098390350012825128730291388517597460971546374785158162912190028421493728409410165155706168620646222\n  0736689554939314543518226625017737147979968920612065325275418413914476113922152134614069286419355821\n  6544796702536944885444171239433349986029802709850271418159541678025432450545151692226883222768070584\n  1685710882489400810805982436388069304940140036054058825147274558825823285297655543660060976141881745\n  4395068351899430644076770973415827497543346074110326888197363251029598689127139183273239406546776520\n  5701268560215837385465875625128673719730520083545205711511563796715242285437561231936717685670090063\n  7354250309455101918511962299514032597437920935437420911843155116834985132549158654381928399557383125\n  9453672482506711473896296729908788858488825997010742272525040354818049628522570520823634851226938315\n  6280672836714743505598392797326066842950726351382751041974688976767259136901730651236573171953243101\n  2869561072580528336315890095826698417353963848720165200490649064035498544923722942741837841103308077\n  7386940393450466333220017422240536339407527505982935749108698818541052273129910222333976612533246907\n  3008027004902589119786609546141221334121389196263882666178655614634421081326330771760786638063634243\n  1909183254194322747324115237704877561380927960483576499695368748511308807062476127325750376659107831\n  6587857685506619883979458302690860270196411220225736605864073929143877225989074073598764473315527068\n  4661916708199094210860851403328060178785143014996799473634236622229182069032445301525015578576015228\n  8473671518234944926548288571797699263163527538455765576440677544890668248996613455952180097814220867\n  2688630564291540138296534685734899671972420171760414562999130251414447524884878859521922268437236453\n  2964338807885110699339769612778269162546309732353545146226413765213929750680992477659734726126909397\n  8722139280745585647099981589429668515562704033660587623053403109834593229001269832269205022015814343\n  0280800022365801546328825529047068250736300630781189568719809407671585126103344019382962718808600861\n  1697072396703943181261309742471117179019857430123990754035471650628805126492009560551345333620292630\n  6649809154087581763402129960016194911103493751576558875248272142376797264256426977368198890882172269\n  9265553049872479047981000650468434265519305954864635159658341932560199539427254246373171515176352439\n  5140380742442385772476565961524567466993162860282648550406859122463407696639769427013669388291856076\n  7582008669438337563145932941714551996669772822181470620906203497631712086466030605675614933109167359\n  6869262998033651598521300888024046181683318608779296650027792213476011617481352000602598951502189632\n  6415385131177521071464107072577934971822527267900599337018659615793278006617691118316761471579646487\n  4106952245376114568879231150886303623840717691959989003565807547270107199166447759227730658896111939\n  4275860246657291646477829595177925217284078607443295113156581166361862904473631555156558233734102054\n  1097055398105511858777484725531770169456197732740007627466291601557814989384991548006700158802872713\n  9647788555334050152578884671964802052467242449395518643725584409996006306300289818578112735319400344\n  4827534004296065595089225351860155422289176429463530972839057155251922006718225204483456957283024858\n  1587778354371951268596542670816960798234661679259260735618939895590289542298200690113501199927833705\n  7617540712583480582780681238942856193111114132504933164260528023303981416900679889803737603209951643\n  8489058699369606830710123179615266924530464923746322846279908242334798330374034450178644803988127559\n  2259020465366084691021379484236888145262969686621356647670201426725320564435031311714441377135146736\n  7169726545226546510614403820274351610225460111162195775537690901298148136883286248160366899277390833\n  9405147143384874769201164261948192396449463200446384746884791115170448439193867653031100824238704981\n  5245204055739620581831624869450329535091985805645898908744256831229254345074737341519527423647641802\n  8199548731737721290125242144675404294585540242390647170225700446424875936387663670677479620244276809\n  4377854825766512843776900931420986660710187029338593310437732853034371688951848025477991273331396336\n  6725069762400444399984287154827354002136228003638783578086193032813099949059658918893750753834426925\n  5703320890375832462846794994772016161849244806707260664239432321923207176003725231360026007938117888\n  5240250457731492535024973994254405139909972427789185118923895556724908833225321079886270815640003225\n  2780315109766866228334677738349417461225894542098000029093296907437726013869091027914062598515250597\n  7668184401078167066934000751493482854055561430475539110533143757464229486209744679084475876468363178\n  9277308598851113550957947449542186298667749669615947444409273113200669786113808590545317626494590167\n  8196971498613994922697223384527051438093895135046443755122548611170891396680893667779730994384880861\n  9331909104357860720849673073825937923963599328475100407272793862627167044754075719202503934191972545\n  1894831172790246140496689551790799869102537648909648459816709017139351206782839579961226311973314913\n  3778183433841931852367538662901900463343328532834341824921071916092767308013235369472648489276442979\n  8706811256546280611726046073321917630474121506403020178932057956876051027752505304361222709604675845\n  3127386616521424194086834083758914009511413392954577009473174811688536409418352861099710341672355817\n  8602823498202031499867940174041719140283936210519480604819018245180081701371042197459212798404024268\n  9630053355368549416400863921774567695344586508832862982165846016450780000359898521290123959007042026\n  6074498878506271760776222550606390745319477188925099058100936729891954099576633538658378098044793537\n  7991877121429774619764094727212140235326551777236163419660743763915386601945017769140062406841273162\n  9586080635067629377512529343675960734271996751352015800873739548389734399012382565682907859114425882\n  8521366169201402990041314621368063235265086541121808474998758441118362909790891983411875376649604809\n  3626489329104390597725632955813887767446954618157978704191597558335000377286724607351853508854954642\n  0293097158563694978576404837415055580991884020934333351281955145551857333488816491676944277824055543\n  3697731192014372254154192745059760137984144373599420287605255571893780411489261257983036183801077110\n  0500423923926441569227790057027947401364942291847933692535432484048780231777445184177958355825754761\n  8425495753958785494583430848044173708798492674195289323031489589916006854228795789294815900068735373\n  3333338638139084209948725511726171087294408886844785081163455852692141540299672098869371588623222033\n  1485581742682635950689362344813422473786939460923256600754721256741410342184901311896396765473291674\n  2471899342433028029092698507522949079709443009238672877439362551113136287615919738324134916722682612\n  2826312779381175080740895894397190025426412664947980176442016454158813176018972659624614413913192067\n  8503524638306577640165229732047089201146917133722878630370384531341942644142496649844744048617738513\n  5293731080998594728151117365071913988126930748269061403928642276627849432955882859383721484750707783\n  5511989622491195588237045064582005610170205324844490215022945617655618592145743990095548229413751544\n  1361329150430469141799412246093381651362627902827884213812207758942403884062294331727989259418366829\n  3679259604224184594177065301954864394817033552410287470447311715070347750834323733311632587672763683\n  4685844486562539187239460827324713500448957086803150325038676401735315079400345572855037001845602769\n  9615061568291416117061046161740824846267033518915255188248212726007259576567889912567870201497866790\n  8471066310748764673098909147197987925985906257336497349823503126098309873468616273935805790735490824\n  6830497284097732381167082491516373468087051052191917620541698826254760544581771117993776778696542169\n  9257855772042634424430420744954897033904345072061190076973635174019526563221392825831205282400374669\n  5459092804525968798460814087071953425476138836335351191121441431485055201235813806264923135383387675\n  8091889237975855157320365883176242411691675238145885920751640352366843726791759063705392197981126597\n  7081139473516719629999705209017090758985691638906642704235700744502775120104903948148329457443809746\n  2603510578981954076398706078758177407249118450697884299413834206081242839014881487259985418148029294\n  9227878324356105549156410917488770670678201198591095890983868839511718380134914825499274914269855259\n  5177653612624215726624488960961482979703084202105160279671478561594064613638247758902011025199234215\n  3210060175230257421223754210749591872867518955215532994532268942518840942282675774422227552820761560\n  7277103947182566802471066067738312063031466284744338620474325956850568928716265329083278784399650716\n  7242206138294532916600463808725630595241532881209370099229896006981396279686279567635198741824018562\n  9319849226233364318993090170488199525882733880795326588514493938124115432732058916457864229452684117\n  5188081840509569046913813443077848902114879712116283977344305484614980793562435496714129473332666422\n  4830500436445454702749172320783995650868018761732703319065657954753952069292520153070643504713068812\n  8903205385455639879921010956672982873047946610054316358462344874415554071338143234413117884241960190\n  3702868696242276246502400420813713504640159934720532755679503533906712721617790603021623997804185763\n  3481005448388703173071625525647995999986935319681301015629709787116730696494027491665726749434320813\n  2314613886925533494929411831638778899032594010934111572742980133181457828168791351424395578734205915\n  6145877368988080791707114551154762661682081777574724842787971298154823852036895916524054373052466728\n  7313030192582952498763932098573120916105613572201763927169959868610886760613384364961695186548486046\n  1684848240743838118074173422244839478939982780147342223057865410217729264820914094850350132241515599\n  9901630714781485270516144322582547801434401095336602393626424931385229405475364168364670415743005583\n  7298470401814557100296962346985059977885573699802182230354923831879762989415697721236384408891789275\n  2775284714477621892057425453151037479977706862362421899063030962822117732197082303477454550602385859\n  1140389896916662207787683260123961741999762365506363266016990661168908868774133378091951614977054921\n  4171181911014954347869382062098082787895731327899060020863391127847153684304381498150970304770886881\n  6359741925341341221913962874578109934248327141091782763176542096312507136692636588213575119987540115\n  7902802850780669833384183382667394553683196565717031946293364109272667274244992747322913800983574450\n  9134079930856836048467786653542105866800521154264867497239537936421566535872081855412598194547427516\n  1184169366255632419359158569508890535314121833662399878022115042456600150236469108159974192025443787\n  3610226712941228298888053367943950329404804961677110728788103161467730371502183528902414648175430954\n  9059448875410425016804069999819671937982082773346485581585910776178828497505468567913990401138456243\n  6040357440246191237694402200760421433573387260392537246640896649147146547300721952927374176796135652\n  3306780426820002423074121866748669462805878878738299523278050107066101385402880119138557309113805727\n  5589368194030938071886379375821544435162655991203087848205239374935189559715815518280481480783131053\n  5096823567161235509631615286658578590195287177546425064129849451057303533243348909799720945729170095\n  8784083221404405014741143817095657712526715779817097676384786420648761367939457844238586035649664463\n  1401310486670561346276901749283229004327112081922956415894815282655842219261890253051381591180342310\n  8851491226653917944817433904322700506874288819967061960688500673328353614680498596081402879119631127\n  4825466404370384782884007981579134452321016686737411212944968134510122379842940219479469166481503124\n  3187396911960215671211422794306820104087675680937389820546842147856014277688201880717174141274936746\n  7817513227710904673001530946777306922329095349569449160116904681818272347781619751257278515355698616\n  2922029188474530269830156638749177021947605094174866841197276604440854832975049890782580615390200301\n  0352180271792099508178391212339700700278329061937133682183369615408265203927161518022791528640768315\n  0329974060928048310506255157226287131327681824780116915493786248322401723837072716088641929421181718\n  5646748118569400870529961131410594582938703305286297918826493247420179551244232947629034883495272292\n  8308040122263722761102752038001209375208856240645311250372640153996437123370790374395120320285350254\n  7482779809303020219663250932909448819057451029852172830699622421954710165193932976937065457633343243\n  3256433136391221083529135557700812650539793164681494513412075121883505473968595553878091947374656627\n  9031868161713641615215540774535438041479845458406344747450856802808623241269693993112296405603273109\n  2793849169187933359614853517001814969826164800344027822813985879014862852128674617538485034806838652\n  0168074767440211476655696438739675796644295886409577559154192615071966537341081706497482220419135035\n  2239320369277923907369558805779975526019030814355084924759818577979802981264125192698083107565746594\n  6935112856279759057800341932347600136961144729013113729326518877314672141074127522101051515586571349\n  3912768855730064565566635935253545094573789688358002770721080754685197902156776635596085899524492722\n  0497752998154586253592955688586552190862034885742944354883401766168305532660245835994454330952973620\n  5642829474539664101759387807875790401431956726445025653896405200714870685370656271174667615719181064\n  2280464382686780641781701710145579987859492981028674877471679017435503993169683528592116481487861286\n  2891163759927684710887436616177623930982949823406413782807112174123783422241440699848632882392406563\n  7743898084631704339814190170417704585646785993494113767101851048288345847591129859911326180631166520\n  9771093260254577766404781139798120273962790521780796565933483031963863726360548172617544026268435726\n  4514741114361974748853281352543231321040655374753560914051335764484512650315994993984759123386762589\n  9886282674242141065631702826842027427753547852784980625547796730956213501075135701081437671209736106\n  5693389811287700643950868226352419579899875244531513268435771252695511656842606249795300564134236794\n  0326869432022127715528452294559060131663002332978618427293697054256408957224731479608422799606431211\n  5572289888413406901570607916985539706270694986922613155059545816240665427626536098988246922842402217\n  0510920884522641938004050647235141065446293973629500626870691857435034689078702526688990310590307332\n  0209977070195562670800784214175004024877643693827049667540691448956340009298523549912969960465402832\n  1299512881718293173380258934336088863956188145305493633210224670237123490797406812568724883352801820\n  8796868376748932865951563500158437345427148615342497125226151780864718350199049932178199155353873785\n  6234550871431390503843286965138769032905340152384282439639132568672927224870847796968092736560421516\n  9040230075017366194993585447144041522141064749724216152303724661255301796533454354088980086901630718\n  9158808455522198431157422312945196703758626058776263336684850752752847903442501653764916331792832073\n  5720436314962933262171984120414969390021578987584055068836313189782803270681820620114709707824647760\n  2762963513245135225192242786044766017845546358689564183440825955325433408871016151070367468245292204\n  6780848531852956030260393369987912529602307327858469371627037491448388916337500526216973323321524007\n  0875809848564628977918098482534272120248127256555150503057004181198951860921678780927093724148047112\n  0320927521638219693005366775084683589386544528152235347557559076380237852151946018272456823639549056\n  8125932747289545698934471141809813153649597485154106854609786330324864298777018635531367450811076763\n  8604733464029576882115288981356644930949310435890364514131755241478099253505914813095314712262341354\n  0646090598039300729540969213694564498578781314849834710618588580258335380086634822074587547577692067\n  4100675717787021480249068099354034049780869747523182136878867192069420344186215299004686685357497787\n  1014752845821521535098270986352770357562938493139316042388716899073982395618988722188420611902770942\n  9903227573668718607977070772155923264181360169717277740702884134571773206253029881617264064980178019\n  2696415503872932862487451156694400901469103714665895280769075063099165801904028249123963456798392695\n  6557159476136694387393330068373830818123094204415929595171871924926797929712950294915811852694465448\n  8816064489091085747384972252662561359833739178319495991506543998379398350900517433878817182955161844\n  7325706942293753652551534711785761849774779733167716071499421452638170475227272955705001733744013560\n  2978121687188613072957200868270472815099449365576135300683820300724872389186045558234056763187626236\n  2589043407960239552914408186887350391637299347162815765862853465444767189779664009434202490164341084\n  8630536408494091288771199650698045788071379779515912042538025709198604559673886019016344148290099729\n  7139228277863871263080176692137049349769043808195656188012979091465075440684531805169404962484549525\n  1863363242222261458699500929790456268865970393098396956023564388968632992332376590811424860358035451\n  6978206769488924866383306879176594263820092637789031658270502911378572975097400493867535805163232169\n  8473633858419735204876339455394642739288524974516748990465145947388497787436575894707717794356270743\n  2572285536101492929675650265851006003218146153612928591069343214878686374342977020598254510958054174\n  4556250811648819563443233555509154070228734506176634898004928111484860336673588052242980276245065806\n  4166164609330965832277412016870046186470873546075946002355373436366858463000829891159321746543217351\n  1755315755510186309658856027447328817436176453655926246176438777403799768860801841457644764303571298\n  3995556915655942311745306594836250206036438221735440965535395090457436938651043129342716658105214647\n  7362856041042715237293978124871060598593201780757738436706563113506859305888608362023477806498797585\n  3178401672905978765702813875802603233337988320303896853999145202912912522642348966197633971826810602\n  3709597596629809185348190125040315899625204717076766399868353153196608687529125423115375034755005153\n  6740686846995676773305775107923504903457787782633964738764290564016443331682245650903957006685680098\n  2518273305819042432261128948518491882214253968613100337137224301868395596441734670841783204007571512\n  4168083755413148247924004524308125367729689704440679643179742681593592031358215146396789238533146916\n  8480192378561366570636094221329625671822214085376580706834616858349637565564815213278800208251696180\n  7984840474867542864812471892324572784880995178492002381321495055976860978043922721365667914325583872\n  9396288555753189851339047123780845594071844832836115336157802570583643859337129234780510580916071579\n  2371735883271261645606567945034809907997205084227305474190778110649402160166666295094593246968082788\n  5873826896084877445611837984486573045432053689268403491423450881535101678575706668749563760666307293\n  6364979840910528400845462332617818149797614121818728612686534607116650955135477832306274118114820717\n  1646652654270991484788077768928234579548611067150494736473997364806652995373677999340235327496480103\n  4460008563976973633732229471469730277640940775396288390125824662939693898770158620893799185516933084\n  6381599653959133926292450056440676097423169030780271559700744418327838639200591504192666472875278979\n  5492770341508263915478969268833081660479564209112379312512452382628913239114259259248872353135341403\n  7167337993061711996480374076644403610827781509371989266789958837505255476092942001843074443896493496\n  8142535424422875482634672599399787959797254722441172876007712608840939504811921596748873955586267106\n  5490302132402247707926524977694495520510805641048220680217292763561522377385106360209720313789483890\n  8760877304444339107037138713316374909282154921296609435599576542505065970239239800133971925439883533\n  5819326042355334640709072858048652141533903522297060471220130494123455357789547124863000470556288945\n  5044608622266485238473107331722303856418653118021793512078836789316324319258064485005114528227697470\n  2881297556723041938969669115168403425219126668605613003845205389336911210081205025241087952203462366\n  0139062940958680638104861567034918952889959443421807536331295702241260765662837857763105841332497008\n  0210963951349160864205194055137980373826514725989990212475135972827648704803024095769246243692551113\n  9223531786948292842185557243747361826577956003518901587687598144266576265825837773537988011685811161\n  1885458719903282377257659747925555015170352252043295945668950459779859313354603058046287121050992002\n  6539199902203280298551349905589529620350811851911623933176841545106106551624788219806941469531402163\n  8542948465099305759018425477258768576414740917080050765864163376935814660781872244505837942437576287\n  0854540335011053709267102160168897425190172664771091187734019658761319238244016778669447316036433235\n  9105304639269254864734057622116648426993833030504817439731193500536761645050844763047325637642166613\n  9818172167153111289102455851620731970070031125405052082382908931287575642187541678615691797009700938\n  0501429846668521200159151132720592321337362451009271857273494135289481232311599234615896909789674454\n  1306276268725633046823353137159651300040615332005626421384322314827035473586350919884465338356840048\n  4168465383514752987266852104759009105167315924626485357070819430352359875504929773330753172203557347\n  0236517079315932787444549816445932473938377943652780031092775354373492970112030888508113851103629856\n  2059488346961563623208283108425028737613641284672645036795749821634469459924402320386636095796527312\n  5048912012359996284808751700271355908821282445921236597263623626193171749930602780067270385204438694\n  4202396265943071733875448439649357394016544694254389183159395967500993298475531832019709586811147403\n  4114643077490787323473238318431697758006951047596253478039290531227897202831710307704415204096202753\n  6066168775095387491356486548993528510813754662302301044164406078743379938865943431973972762809887255\n  3596421836886252528684292094076693531017467606143615040224106100657518385781845943097381666527422822\n  3595232656315600436346060661799295434268127824698023110783192217548828248443489421559050962496809551\n  6816141784081058068173009002631527217960747234579744753439008266238408070488767662012566975422632476\n  8414436029961270632036424767255662395841363346696342018339637825422544743063280535146449208028401169\n  3507171925134344917591634464815473816005896456760840579801659025574897671187722539527000178383461807\n  6833574250619637793972907186641657756554922398951160504436181020594168505418765847159029625940307677\n  1869386054624379389529177382974148463926922111853547905990950972997607473872962647276052104595112827\n  4356312709605950237557318061954525987653198881915837078060946073010461531407967225257577860927309190\n  2469192988451739871631507685766351864937976297380660316503198618172065118786733591976523956744318887\n  9533652290886520080140499811495657664501357148699739221946031665890119202261370639549215000080968080\n  4936515617904441399365473211942270762716806623267993172218125745760915245516705097654927987579284966\n  1673761936853435468604260079278210505029351060269911077292583322331389423980871654050463146586178672\n  1994997496972905979157918464803703518738864382027060980493400455678609307653826192652631811202186385\n  9251656925865948327448316434614594036961723580597179588829058381523697885331682301331452292999154059\n  2302274058550374062853590459765785964573806521600263159177428881248018307666463770771998546947143246\n  0415430871067788218769070796941313678460577018382839283094791609157762283512933081599452697606840265\n  9423392885871105440868306366385810204736320944965349887762757862699053539155327911881192633510691931\n  2733976667409148613974561452545275688380518228526608713496328388418368484801362645828954007306507915\n  6074102889083454659625380869625526263711592359482638454560872583686037619817067263374481287637268299\n  8877722944540407706789940164381250027554201698302306954511629983134310718899098625410160029355244154\n  8625913761597478709185153402568888130198921884456611164910632688832423448309628880496579742710340822\n  3736673828255772507677153051860616483063355980193407109897163098840874672591044598887595960530329248\n  8993638521193949096828371086457135234560158043864297103538466830596898796808358734978576267855658883\n  8364951627235452070877953346765867204916172087981314914169891375664645456974216663388028870931159655\n  2908909685832466209423687259552095876586763964525810627609539552914917651817376729189876677984251192\n  1680755258160046926728928376965028649208798782224421071404646730748519743713976053074322345155253212\n  1235870851616285214538008368612462951548039453329683773642486296457024358189231686226499499218634983\n  2468121494673751199481950450744965970432717604013383552223608153400047959819368522309258814575459795\n  6696947562389495724732524848660706542882562876735928839761419619059132908399469163841005321889186943\n  2565720667765232382473164380797696044457296944650283430616652216987080261757570512416411109207357726\n  2039704116888594037610584331302931444829065955684296487296377161321950732199716414417025654689461012\n  7030824597238418283604031166034891537160762328639666165618560009467155491519746730842325586767410973\n  3402984616967564210763223153678979988580683198922830859763375092946490387910743707740084634936236240\n  0830084950073558164966916759777865808111823047707424696436047327935182038471988961170359008300455685\n  1252805095510667699602373878235376637278226774052051061532018998380611491985952875002662945542273526\n  0581489488099794079523817886224433013323645543257410388370423239809214161496327553956636176867524381\n  7655662510133743046480820755285156491167182834541304723879598488899915627591908215219594535894398739\n  1987885447878558839301953170347124025007207286819666318891540923756298247737363589629303730274864925\n  1369197889067635824615369075723811889000386834089303979375199306538172287366775385114171618214640630\n  0539934079367210950941233283505714265283194967469485021225058627404548110939587405372888096652279949\n  1313504114857375818994915227341352040220177174269756103240539002593855895784915494068759108510900445\n  6698779029635899957858043995947222843355440391384551575459051012236770949004290725163272506438911414\n  9403143929338160492141148298696151260756811930048851604289256533437306862399621812008375911431730894\n  4198998029337723050652250270984972059596353606069301554054235809356222199901761551336947568289739010\n  0935189886891023056203345606747815955637373724315051310463884368461660222105807660550163384439513392\n  7539050471981112677893784252742930717142873760554379041535781461948559847060404010163365311893068369\n  6593975950084585133272847308800484877403931718396492321212575915598639683100503344056052789887661147\n  2430892073906771713344899959049955652866870431389745563864195065256263382007256053250254497912589372\n  8660693665274756954585549379365494669059562648221660110907222716643362714785994645999926749049549615\n  1264230852976404043695030783887567665223227853593755677217005441761522757890068849222464725810068548\n  3167616870537047140293293794295759712945613452455275456568249439714331385804950973720607539412574156\n  2910110232605185216108762961134662379674361123425177993400596014944329479641646003108837766887059200\n  4886201801963376976145058292176891376685475541938116074706436461835509504278367638447274620716138197\n  1191770444487975137788922899588473820082965070462231272806210512699103944589360789044290661289121648\n  8673293277124505955764999531645688888539374049657657168809130392423485693764450199912028784002735463\n  6310802804883903986446286631594078401029177968777418982862222702853291914550355495243566744611953366\n  8970392803076336134227848130080590245232298645365347593792470097712372514855978962233505503714082373\n  8855989996357257681528249857323029102096633655298097518691642928076192749832296521944816960437154884\n  7590855272358644048020175814257540052934387946196431967349029347026961869732830560212662858359414291\n  4176432704388399714037984862965074407226526416346342898291915406945822384005322871978130120342846511\n  5000214159693875605989584674337883215104458173349102931408492619625443010694755863267361339601315493\n  6002702882265375501691319481721677272774887979071308645912517689622702343482671737444762540360443612\n  3834266368529097934730262217743440936100473438325947055617962424701479577599383961282821867040465947\n  3671346740038028868906734350560654196291543982323319166341577275777262556671272875677647403587825186\n  3240142935123099265241861053652623906898057679590093782672125122055111315834782392514171893266684869\n  6741049338628805893314125836487308559685236487095735227355156417316000570435683375128586486798777626\n  8789119701741989262975037390169668114553105639638913349194784911260028872720224362955411330210328883\n  1252179038609153411678577623388013856364347123025313312758349214962681684346180565506437686484432169\n  1600993297935886971326345948047658016730287623626375404641773711712333755529076168457609841203148149\n  0671265447881308749669265249507283763395824831279554241699844491415609082123420144663561151439878692\n  8367644038199996073613035658764068334110290878236852304517716218148049432624678420340375691218100204\n  8571334683860316409189049331870282565113342259651395183628517923265340031625303117768583043905855303\n  1434700094995404289931062006909384298598494625764243642747550200929598219970537138567540242399582249\n  3614688183578390529256276625781476282549052153118845167267925851062996411218904742903268982903001953\n  9195564907348181246684338993876522912442311981457466200937808079651108208092025003722176564662265462\n  8516780697561651229846904028763819653602313563613649766389022197923617233885491819809573522970142320\n  4549139476002030983118265134708319579082742177973229110014981104209291997270793913105416884305647668\n  0682881432639312292484752803515563282795273265608341088161697961023963066523100437026823091533999011\n  0185178408534796664576963995643862325907256630756039470551358975851270259376353252345454607115787656\n  7775171323140719849308707274172599038347990837752226623850161890001369665331022529573865193690993625\n  8963337910411775860518781920708777656099941098051551760524338381498578844158021483003773807294222057\n  6114221873419120173809741916039089694570812869196186877182344133397780597593991704085257402459527953\n  5895516836710461224141484882350704209894946405334610298148181498384962874854695004074324843010042370\n  2377026935949778090939009555164281254168379512226340810340240060173185622836711787912863505765122105\n  2346487547089228654757979919866349134336745731780800010159228032458041560620405881497336905468838305\n  6831118856426927446668256282605693182711497110790802221674273725205608523980970519287617281829491707\n  9681084956342092215680052226576590502708101059646896004191594139713443207974875200619703621436531076\n  8194923146657468333019425617725802965628710574635667936196429335090417591547605643722848231520544883\n  2642676308711147460636034732834323009419042086748123219633559808929813901374321723190294403380213835\n  0378466582478492823716028457090185093998630876897463612139222874464372822230689814427108087673984745\n  1986859735656832475850237902290438743386565016354309204949751394651712042399638048515240438271400499\n  8736609221595167943665520971624671902878497234306879414622093306540351514653335343817621214097499529\n  0813343668874219608546300562941871857198979654903892260994006458134576989890293752526031594793520517\n  2873837166700721547961956375740701285592607563335804361178569570327151086097332660021100882712319916\n  3759340997123032026138109889964222097317552741425536341306159729484372048567305363345356618321960256\n  9723677437664041985539084586654773133442430617212600862976052967207859322562292355846262846333189292\n  8319836100025921871137039971505577493204875978319767136286320184428233653934716363794571277158840984\n  1768777705511446946524042208853820282498929639508467046570193475974601082109002237981389393889173661\n  9958702353222196294149913960484299279341165867048778571113372653492856653689288750896260840586049730\n  8118077965006010068109796230455954801189768566196762423893127565241655983194566147167582205720515073\n  3187438649959207729217154115270702515737429327406030388997018176392492844496144989211996008741455920\n  1197110619178135600831179394370021856788080126118115799464147173035479067670391626448036915230016380\n  9750954986478577153019332075870767280738241627299798565721981668444519311512147215394626062415474788\n  4492531474522234289814443935668965208172835201849104468501236353466594439101771286059078923203698177\n  8144140657657953141693427566274427564792495722561771122441508205905726084814714045923953079597060427\n  1724592752165506005137153967772426318259343164959994084881348962944398019280504469903074332958696420\n  2347799440608555298026016876274594816524700132047509569931582510565956554511246812167410441892014971\n  2917059113204648692995218936078725719895433268702764211207971112580634371790702853656868188130649315\n  2903586491231366257190281160804499253317309331886197389137211839634887920380921481773975151215550607\n  1421237847824951464949328585000899517323133417944919571954937381022516204335585096404429995065494821\n  8174918298209802850161357646979930679132224784985129587419897623402048264287062020511304845432074564\n  3630546829858997903588405564610067458997230028648958952414533037922186076757219603000199840534610423\n  6967394846598198903322644713641778288583186156410899810633325669588014908754891185529444754877770703\n  3254281654048701145290259162535198012387414010436036309205281399608185782175059199204440716799015338\n  4458640154205422766039495098525317146476566588668145884224627681547177489770602016193969477385529779\n  5179206393425938196355238038842483958103927567056400517745841545364779201707342682078953784241931871\n  8112513400191354907522301885366424561518864030265041520622587526974644830596060008664808467397587469\n  4031004430507110080328575618526003370683321783410069730737036403212982503954591566451625180163585488\n  9250188649041767130862347416451200097805267165914094586669529719432662613627554666276397479883132420\n  7660024708256555168634654157322730379846334974354176053391180554958485171003065047146570917400082202\n  2033342084271621025506998295166962322792052067901249991059790172386421758536906421361877237109133881\n  4995600185227362965360920637316839784737149841162314047954571631028508309649294656142890777360309568\n  9141375737242200843195367673720751672340211743272646707775707205664465381708610430491301993304747985\n  9635164887964619449295289058257309790409506277206668356944279880549619837512732746507601821215205334\n  9220808519176266170836135723334251006968310417820797186065027973257761157165072402736511990861376703\n  8988665032755774389422758156617307697218364368019421958476811417575765780225941229369376285483761501\n  1371209444777267883907263765061893274494741092640586931989590585599696009720463567109558642594222507\n  1342281083161078785456208386552686224968775589567428400965170789743998364521940287896992967688552250\n  9924548113167981196095844999451283017439565864554253492467331927699292211498644288427428218962343777\n  0714914385776080580848564273037171353764245306793786945790575233507643881521810656607927075157252883\n  9918515710526005618833910853622127568842615368679981807360170875673642170133324263530619346354543601\n  7260388552556774580621314638205488997794379948659252807324771277015335667243051287455111305227076922\n  6215106526147981396130120548259553984982903822165854000278718281794527593457598160626825669353591091\n  9702531758789585078642512381690228684408855504623386176809374387125500306276779114460427175023690482\n  6053496822003468062797939752823723519731070856662324732554815669120184661565393448604754035740573532\n  6497356594491899073616081176313352491857472402949142219105534669423028663739063083795795265229165823\n  0260997650740918733400133052343101030377785078752063516583462778448353683665590270558349479612983505\n  6123943390247573969305052295130811046709132498820483153789422613223556634309811418309866847681028257\n  1550286827483833975719258734740115366467168262937015526822442127711052390917969319239127737977176880\n  1542246883496201400997322757593293917724086463489283646444353876181138341439888235343530623717836037\n  7270922206790149131574946123524864980368060944848857198938411919684715248368996081472224187543173353\n  3374236949008176264368931636788534545428571396360327509922895712580324146305634287293186997117594565\n  8363103616835157351924115291745856865483974709206998158899997133603670512517832216587046941565206271\n  2941883036728616973277595474898327009337617091038055159386077975183164791131510918328012752515936515\n  0488607939884858609930811934938012778967091084784084709431548945577055045503618218115460265023335986\n  6262119075457284333340654655923652677967900972402255903766627701571787453010678368459746242411941460\n  9270255181653574496408037076359218204807031707800495030515279198046841480292623759144109388211758454\n  2230025871050989743405380196080967060017294461315943539319021552498639177030603251093959660382062356\n  4441379417884276524064389978721528985487390825419481126849740034138058770293316002349752331437832506\n  8346832390294862961289177107044987706230858455583007253858193699956274947316552089561794462764776882\n  7751115761470499019482284323868027347074673862814752675333720121010716466861961600633771352137821138\n  8572121554773972169330440194716653483026828509805531003676041798533591083991213560094604211825482838\n  2608059451163333745999330985400909567553128225040676460073412663544062482616605635769125279981301615\n  9259426864869950047247753327706499938464441139295589691465220429908122439062860004650357381269521702\n  2563921682177336732020915867504500478898168703646096151846004855741439881726097384472127464419545019\n  8335593231768829557830645802089829527631549073550054654111113719476304362617329785902846513191614666\n  5516766350641193345758667137818109841564659296236576908362716072233814788508550638863177490787234919\n  1987679896746362545471260440954168197799220710427640251548433196477390558104961000164705989515785294\n  3991917985197806089395678647197363890098524223400054422376311640315186427938021795265684299781428838\n  3213895982439395887701557990783944892067091706552034967699860541559021057651477157873786751371254730\n  4466033499423963787796271176836236896244596776440199697869302789570435167443150980228986501287745403\n  9340739724267160500255878549888894099384209100168173874898358456289352751707911705490005436219621706\n  4294043278062798737866767302228520183704159213524224275962837503729973495914312511292396853190129753\n  5611629672308486174323176389298817540247039152280625468479103097962829343042133940228841293104759404\n  3460835668343232495613647542579862544554498896351671364445937935735007027731767348845174887099668250\n  8104389915567709984887401788299074948442331678830180605973715188996429503241991398806477821402001041\n  1177747896883955510807421116480422750798779310315115110843383177288725255853668013231927523396907869\n  3015925808524191590883768045362608975083421104441911728556321464612372029116740614660357396431901332\n  6735113831808685442753061156822006420507762762431630907633957468027315291779908101253549436125914719\n  8875238666399374852539797888793077692813208745702729612199390812546255462541090083430520403871083838\n  5722642176756302904930176929511528857908547895413427296790845515266249771074342215376569954921693119\n  0035675588797196959360894440560279853228297459230057292902250191869049960515196346658738457662861655\n  8370926229549052558715098878019153598544171672135730700635697462366450699943859586530458169557668141\n  5188637516729582855194702568148675216121345853932624252174469525507007692700832805350536951638370248\n  2620563452119086436094550878637455568841651474777446606868027320905274568175395157132037546217069826\n  2614847590710692505568871840363000530513868109575388748063346329994876955374348108245413109810837369\n  0707510452638146157137362035056374120611543698395643113673185097174963434058322907235834016182906087\n  1658710160130421591917139023645897059027348156810722898671953025796837645639897187692251759331558679\n  7334077373304321675565391075575423891616070212271737592070056307136843747821213528898979866821776283\n  2572533345183230392747618654039192087965652589286081930704035739642080989321089432200851994167611717\n  5273539788820266187445622820220531528314278483033868602799651751797558198833310256254382304160189423\n  3917038633783579210320377866821806189086326486741966200834537726721380300483534966960106622413864272\n  5292530005372917737061162348654387360333573151227139300475257703092179902691056833698681470070046680\n  7131900900638769068942035418676510749733938247585986386289190118498516056762720635681836412579224498\n  2802899653618617776686778141029039884734762717902348638353671988418153776428435790683635879056700585\n  8121342784860173429927311498525829426381306584979321719602718883988881367210302529373730687284284252\n  6768184950327932957470704537523032086408891882046920257811437470677421043931464527865896380704085307\n  4482407805394314796823543620540986524254461309609568972992532000469372276519264525234710438680616284\n  4150263272906125719272577676314022420185623514890590306131224408194389634712598106722230807362487403\n  8823446428048391759971189069304948686931188157335894633373137830646307582206036072722165120394083173\n  6077127229108945530997277130413106141567730248755030303311974593678235696920692900868406551784355069\n  9097961301208591342082523653831972164002578438653155268518045595065276218297807292700162623807539845\n  3178749321457176744284224049806304873363455955714192165559906931601168545680475785694458258146525410\n  5690942130415186078742436405050757001169784515992851436363314191985622039283636376980736964248023175\n  0529550137335897960359874442590363690717246275208403121238030892613188023207103014046119559039673478\n  3221472762103942851915451503469923928686060878948272040131551785488924211858750326012076622758794866\n  1078061994316694602312466700366406945698803378941916927909305638007712556961113855111068230718626350\n  8781301659159665719956166392695240132819371226867383997102313023718606144240281675000278523701329742\n  8005731412337710767305263002918854321849520377262517251966548985863027520198580555286556701741242478\n  1398441147945614036133723592910024028800169542825276370017260558174084453430805114569010709200685375\n  1074980056229956793937036094216558524012682608620139896639979818266838146426887629454986869869560183\n  5872133246870517519561716040850360702192659349072702510994757252219108424455952078308514342748979583\n  1409061138136873218656247805199733098940110047570718189852293784438141434541275082709849791964579292\n  0802355036436353509601251717716805655499827883668720305795332335489227358143909560512229294254511059\n  6156659899801588064005422943187694927076222111028476180826159644660270430972905492918095775775902696\n  2478243427196842521066737089539128792695710391317015524198956659379628884094286905195234919075493968\n  3374338510867886831129748407742561428880242025456470750857403395398767464470647241224405084157459877\n  3169274280657938451080829334713697457317170780121504655607730879875787050244201825130662513284579379\n  6693426746591767544732128729799255322939565415828683586256392962270161695814361047964633701681690383\n  7002557364944013958190229025904302917933014131985196006053939593015118034855063021486381739005927865\n  9377962839746005016600245619242505593516523938993857858329225917116476018331586739589226917986771992\n  6426770722804451657455450128217130748500736779344547024871488371884766882437818598556832300391829250\n  7222124723395438145081249592057273858216386717412145544407200077462566779999303388581438395224684186\n  0609946505511749493126247475454114900899298880244751171439414717156204843166161483490190460011909296\n  2556851628776043685120922176537252030663261027926045712112346384308976910057607603820506269489451831\n  3368129757008494650362783044503424298855803363561984544505418523948398908251480866797159530872371873\n  2952461752619649890592054696908404522519746654776340655367050839612952694377982971982255074008724675\n  7960737559298851192270040140899223099769250729082437252930253655458496293343701951694483160099816953\n  8217539750893931830881834902561945268977264011060413490804531314501071393769710546347665429387332788\n  4965077889115704433899875968620677669411702353257219697006335598012767963217354057017373873456002788\n  4615557553918888819015793780554417315212471104852527959766608726189792991456157552097970404808675605\n  4469428312274540256332191157104455429631522523043608263630844221033568337100347482864619734312032202\n  4724439322933802978839273166096657341966481397117329057631860775941914189828747832911366843302535292\n  5249647921101964649065217824280216584448011941483756087062646822170527885558666093973084921172488988\n  0705529500413886690763683994300818877934803775541180454695193374369307401500438691562902746936145881\n  4570456637297627949440616093119931117418045204492835456146997128768235017514453738928383768007204168\n  0696395364925057869308093258643237958397918508366785268709394339609878348151314236645262541524927558\n  7799065325616332081271863536440504910181314864879728064836084966650248920735697536217190475720554079\n  2696638443542621309943524325188309713530823407873141549480966574879196207042981321762437810817966000\n  0362780596168645858331102483433125102935266385776539714735100522118161656726351353841367755589213883\n  3561375461669015061175377649637297641275729796185460065305881543374664637502467661873682860135938997\n  9661048870373212998988077189303455828424798632586508329716478813687836934043158699441584056073105170\n  0807409062423229834214836459375406668988799024529677503806308864246235400067920501694025766842267333\n  7762347007385086104194711069943580453445570489168572684254649000937125624761059366963889973127846586\n  2443799144139951569466810839263252231819117286400745587634104562885751255056808152522939279259781486\n  1747545269477638044769959550506070304057230748023470574234467241031229653495050651701165431324285219\n  7592232503963491802465431634661291802225697714089021233932878860417394101352631152036911145392003875\n  4109001217400800370764068065824627805087557204105425815704573154793095847220829190461794537539554705\n  5895534904623810081663731945502358481019922271929120161775202444668605900966401426557247684365331867\n  0352206558014589136521421488427956558662705933887491878639391231094985612126299412921957055098215904\n  1459138611252665621879456917858641408418466291812312771701856076429841403475924859795364139295700295\n  3996000447652417411806360908910703299357601235674502894896672436831132348273563813700784818092204544\n  4878697136394407140683810853750237906792549199074354539111875441697879774458807061279467910261059726\n  7850687549686191026642898726604155400035593706209614687774802119559012974434756190369015032298765074\n  4211659407494846421163583607742142679643983102756815554612105716791531072217779302545732287453729298\n  9194954644443021474349443399152619976461756050044687614144519713784817621178977241435546735467024250\n  7347836422189788430240648952846314388163435075296533334782074398744784424394834378621580005295941201\n  6958449975956621953145946385170657449406445413770883853227475395462267472178164107859715062639482911\n  7437331691230877947558401624524346731607652792303833610840339322785923043706961423361851512020163003\n  7106473392360159409348761413931578014737552099930571439690936141780868692008127299950126894063381545\n  9426180425248707055293695120120933850061826700896112557402629284289397798199536585334676890135251331\n  6544784862113897579395337638477043789600054374631526792261265540350013294479593320389950440369123410\n  0895651264183332718963511651306511767120225793729061014842352467437854740469612582211063998326045158\n  1254754677929322160100396891835166867336830393136298532998872877313365140099200771811594958529964781\n  8660678895687304129796819333868640365429982502489760838987278799683224799486129062153811952781175065\n  3500768127034638069985321345239607040850382203113837312467354408540035498055988976284821825502984175\n  1924213819952951835534403125784310766698198236289049859569939761472019504074153418288497163679555729\n  9811576928990294536517544152653286097253112470609774310064281021572319914392872471828409399674138326\n  9759137019206039345242446281820941620536688358917458615199461028929758611633262539363485791650895497\n  4755610887043082657833533954872060436193138168742118417529818004502462401321388921541354063163302382\n  1615654645339912191886658802828303673099471289780816548788972062587681901474865764326474554358647966\n  0505441931400783305815766575393391766014969017251101351930327641254379081724668999981078707432988286\n  0632105428729230684618965421625785755601612552340300580197329431255534421488652069980970043014298345\n  0790538092344582436794387491628148340152942878299190846211322390876235024637891877012267547630879194\n  5324149114109125348773470452902228567697375702167027235152036832281449865303019336247358246400226530\n  1781786230613182673475745562719183138593703869423224060783415856173750148103203795100191326222685916\n  2075839999284142583607550237036751437347250061084565212317820690269323271707170180717500766710702438\n  3008821349562114209666627925762947535365612231196303487297992396129561001441176843099144359806556684\n  7331837711114898251668605288243158296681577367429301750530961966351587675538641288368646401680329010\n  2098364145390136182012310600000775796607677144532374490366645381903303565964053774848637705689195214\n  3606796432870265114198205871409962188495412759055289662717437163787015463118234995808051672638789869\n  0116970574332525233066881141023090637160965393382917542474057228131824852865622014084294835890305433\n  1768669388627252990137430129882853320414925964724870842887086812156215565905552011876699209953492885\n  8695129349256205885299759459814735055255033151457349813024963566600571562129412882016229998481452915\n  8027274529433671346133989549925197261429546713411065508748687356789905052618418649467003626154556517\n  8590074743468302203353062126331982820548103883294377278480154352985423406909915122071140819165328421\n  6286828263663561083432356662184583496584243511408252713418446704388546056408915331118311239118605398\n  7811676276761370365842848180731392005624904716232823299108066060664706264035428591900796973473018870\n  5856542992129141065083105024921181152561006374229243293904732428585904369109978087368701612715657608\n  6252725630413794618685327159089484682802764387819688303469013986309935348904399396141313859646288438\n  5448545178614698948363593025023338886138660578825349382042975420534819660539437264347797913552987090\n  4409751671425654917341865740283310563786899303765618156623518204755499419434971521548912142520647079\n  2904376212845403635654004264438858799154465265045884415022083481899808252376263783493919299087741863\n  3119502333553507950955019850442946460037920770326472316538371677976322551046150834470572786498431040\n  6919552119029089819095506643754003665989157129669037382605868862209431585676214169462770034461465588\n  3709614541838367816532646717988704751624200276984105681049934797417474275556623834482187239492559872\n  4808179028869791780821130782667388227175699536815810068349441770141103531411070982796796045742155734\n  6773729313183574290098817251070700102705681610590925619773872526295496706438269748763152709963323153\n  8978021419584628370235855228029775802140619125039390009549720689692293515487099579621681865172941430\n  0236510071410275558943126234999452621742518340731495182266541367071120543595047705298405516414408231\n  6040094148593227671833561041031952334848460795236466106998696317658850281933170909277543809750296912\n  9282902871827186867656056560103883625974768993319181508684635102020444319141590772364683025539168088\n  9137742672332139947128849775979539773479229678936219309925112006630115661739065757368376763659371892\n  1142236849912021475571972230557410057254525724538555650568646053711226822679501929631039458441745580\n  6521223889346737778117487711085358563651048040070235138414083943449149587336317033745247442076903104\n  6589402807065204049010261018063071440950890118365282910010426311261217230160730391427829982605482593\n  7487197078945590863342170565376911559913371696415252912586550719274834593711307562682233144193075059\n  9400673536365037293550076798042151214351972532560562264394541411316747298778368714099675896563070199\n  6956082462801450491199124071218574805370693964038921234646978712255066960696516150681300606294107400\n  8047075701309161735077334755648772547369122521509813503319299338334382107885543833236187356907160805\n  4558098436700574350850753199409765965336872104349332228061883499200482787381125275030492088881748464\n  2831901653960063046650291562089053229473199966789104299917745341287689103090997671881480309327162698\n  1236572060433159649649342053593097499554635341599843823862049425069393201426663783689481202199761417\n  9860830589838293900673951455175735499971707538924803152941090118514926140875944737211593932892637050\n  6958329918100862084041028648992346326034564237042482425706390912938080170465965363072414492818375533\n  0479486233506336636375886561058906603353162911176597900236530121728575366201890101649815977724729054\n  0226707862683387773011170094318514035776219454816762064375319687841485184258934481405295839963849702\n  5395976212635978594566911063706013322795334191053037954042597830413766751674976878746529964917834233\n  6427000745475481949471359866806915666645853291490308232059890281205878126815767430930721017613582263\n  1899928879732309320101492321263732671517964955489689247766118431545671617574939384016165229078440894\n  2315087668705466527579323880554912666169377759895392556108040693811822480005135080937204668602003905\n  5009141165394481995941732187190340971882559072629584283719770085817941850701023924759988289613573778\n  7564358854963425611467807833405187109513125759999318051909219022665615695039282619479016017023122433\n  0575443126065446462500868662274804386674419442015394260381155782754000040402071218190131574640109342\n  7335748336101469403685451256443203470752844838931754561764631572209287810279912029021892238282470350\n  5463383094194477974691308829245720502922062498555235510565416430457629886417680620174113480892342272\n  8834745432011980726606895692588229327024544775347217655283908061743002542828159828767471359831392486\n  7754531846844608380481508156635419462565813296359550594829076330106815644966517880328377723442649573\n  4762093975759557930638671004777439340064983405507236218119894844821271727778513899568490447627008613\n  1269781577572295464760335927355634301851525659582920138209150226200880031749728538998215039065355933\n  1282828353022910424849910104096008081292273713451581458295962514381717546634167630658001246761930273\n  9397496828271609649437231135575629078101961242402981117679826186714048395466852385580727594056093297\n  3124055553730447992932564932798114831833202137311156232404092544419362171293573215519555826930703620\n  8693910309562625792884944657181752916336105084401385563679207115718885798851349629804275613855008281\n  6695303908698962080290303553800625563214036681779081802116484387794827851293781711519531292060253499\n  3978761754640800188549112650947737794033808138516582177365474212231932820826980804014905348395503964\n  3892782029247237348271696437467813541562307929349307240336751699252188922405669614699681473878851860\n  3142897635379762432426981910159665618186293922048809589153523367722568736438466816976741773574492402\n  7732442718521724582490379444028830673844564001853656074654175605371082546817925693646964418020722076\n  7950152974675083841352311356162549952917635141688384581887938427692077003633081667441340571715043076\n  4455055708620196218750902138849321558849314636118516681921933331068710415721922258451362322199002670\n  8380222348732157579711911396826803848840402814592695923283959641886626796149305159820371186283109450\n  1976913355793881589511415327250422495358886450529525188569766476775406419896461256327822597017023337\n  5585208862221826002853592814463086109070674171612612300225306229432694397803268357300881624868449638\n  0618338129063172066698253927339740049475856958735139345476951134818732264175263119057768859219802373\n  2093522988172495982321802051416465423317460267710479573856951746726028070968152504373358982055047400\n  8030133017558152271695309675197201612009205662308775428710696458634713742806675167831937351325652214\n  8383317367230811981653422398026247437655894767569216343687766915649479989449089533354826086379823253\n  9491667268994167499834770469902146408996837582495058290814533142200622637026588908567589263050621772\n  5045902749909993279197623786666529191863955876879356638777647427669516078960839316235252927832503641\n  5584678024618159880514292691440698965247194819339632313685463418650909284138271725216953836200632300\n  9210996206249425060811181486751298160865486378491683891420244074612537349911807444468004565780723476\n  2101130684460779794221320441751848161601019084311857783736923028533939927561111606255009383801593115\n  1113590785216256048538691432381224590429977294696432227371518952580297336604535600707534380412669670\n  5867914369328092183041139251793786077259043301053693860564531228257539431737223358522116815430443635\n  8497427720836342278796178301536250280185857848442597198671328342485127694810821482898998745431722097\n  7924036083261987325361585956014193841365176258823231664971366187149882091304281551016224391160452496\n  3384256540786205403968475984137295093158148777371240187179778380478989949436542977673257015705381263\n  7852227469724678742413007936423284978184783841870950009202723276546498176971856311594683012099715472\n  7353173557025264097429486253814814007859420937562638394686737163244650066947567053159947268781125617\n  0460064074445580742901999701262105369442807140922166151821307934869897283700119529308107366672854879\n  8578714822353168796747873575266193854236240007139113056755503388529014237718541648922941556716384588\n  6141110633338312041108527645828402610255558454722593759618723463643099396380123444892556529898272029\n  9003678439151041868749582442954626212615552519867450944465290221964963295540000703852105632196765824\n  8422650733125362054626026868452266096888043838047437262323316166601591279368819959405025719999329176\n  7339310271001259536094694379663859680832664319316496584963397729194414518373166757368853645182023023\n  8148263770653011391128913691346249132791260325353459199163234527758142476660279547954070433050957305\n  8571051219829120944316533594324084681380748875387297085375441682806609884935066699637289794431656792\n  6876367066059226649550352104308343571403351838775617420963086662250481525113784858825700250405158386\n  1836164507635919756645647121506198985206274610720778853409008974133378884529056064324678372378442381\n  1624539607897311433337060960525973019965093743954562466866281243275277881785764509786865491389233961\n  4539387201609954727731688759973321677118441995894848614261038915187575363531390084472167159313610565\n  9055230688227016390060464654237193404309850825077350154851993174718357373044915069497572480079084269\n  3598291438309313898554875494232274494916279219117441681762258515329230906270288626273271727137367472\n  8853638621232215215659814014346174420864122382487018421762113798480012891846115029134072351040099682\n  8163551558849625934702284245296564463145812208779641481397405213189828785428426965782243489218621245\n  3402142291873824879831283655208388110223504587132896511975297239395600114252964021960676967957581479\n  3597999314184981204111154282216513239255907098748163233710191611397919813113343628756085191368235626\n  3775811195201592830109802456170110222573672111807537839399705619783478589980103958642732946843133101\n  0946879646342978777226821944480569992455368546016753353994086181176225929427764715341240000276901027\n  4117619239922487172129321988282132145815583308103276766568215762232861023578888664955757065519767142\n  3095042057620106160092703642002340450972083564857718166824151192694485068151862935190561171280365926\n  7821369850750877498220731933486197900725897758266414280631975955986314537097065477664768007258785006\n  3099401087894554709720638038948369303697002697458292541889356827697675923286776710169803509732769360\n  2728831210398704047295073357317572232713912886823089697758812579145493793429853594473006165593150559\n  0245069290180294939653193727641307597943503018619518284940068279455659277338106214901644988342847501\n  5304083572143224589265200027521484688613520268320201235650451901911872323559167037232979034597875506\n  9469277215711471823799668074639072294512299085346532617467973382168394091646111762121075682647338261\n  4614878022120885461094160724950146164718017557452315757256491655201696462797061834737046196119470719\n  3166112753777075198944648689161124640677993406222196506865913705310362339187592819657416107839829879\n  5138647707406451422449302925240762368664335949866113933096820043150156117174402845705892934250488997\n  2302803590243885579715131545883284619046631488813005446165010619163392539632499566891885581207683296\n  1375023195402633096304694051247986849565872764528769709915657361774733919053124868449462587226912095\n  5020707217071621879679187760705580481015192295074326337820027918311553682643767887579911981167968873\n  9631778145299544256657730927567143291248470230227864752245335402514079094918254625352910143935228966\n  6482429845599342557559177758575824235233897374748446334004725931357292624483984877701765481318806697\n  0615022889309610656882030057928247768456505759164018129455869688032645811705112881260506082220110294\n  8137886762347888324825282503946688656047914724349593624085753393149412855950658025762800089063568814\n  9232095192164003188097299919802546703286321856744877047667974008052444941230192577061686079333377261\n  6679523723102256030456073494572063560313170703759627214649019425087954259668365673496784779640178627\n  7500941708392596517921137188850269605808592871546564185389115112448280957513693327438297878402591292\n  4252701523801839428277642307786599800714990011271862672569779749355858588276207844192101150122755574\n  1779763862705852706545988937833296495187701152644142164487520863294241085419318611140968276285129014\n  3784802343912480472466682815277274311548964625567080291229410470366544127961945872451600591100008959\n  9347648268573468246049695113680191131432130230724663416373425090192136199058793486103011684913670312\n  5159321122314328916323155148639038920490730467537906033384814622379047633637202231768335411432973333\n  1141893942473793198755133365951923692060556418153629274571724953820445747470974338111998252069390559\n  2573907077743606915448349546454394555065175130465938835163084824746341099051994962367971035899271356\n  2010978505616249952318905021558146844677246361554697831683248275696313571755831470789709172877833718\n  0485198954598438285966997768692505943828099531163809644381799776035011308707394485192851625490589031\n  1087233296314882559207427401434402388147125455959070011936654709673891258727027356852730777519396886\n  2038706430537341996367859408521578977244356095538320973712223499363623409298990125319603399472142957\n  8747514768554321732167127462276803323300056382327072275452949421725751941251053916721864335859445349\n  2687692208238733143003926135466300572963673315564909795980489924726693864564374620224968338000050557\n  8982685667696711428018767262177865576649157700352461100932794682563677161539624379277129483813797234\n  4729096852205312331820157895844795748404966542625020395674682354733532589667464821188622077302441641\n  3964005743958993445124070810023107666728342986005755493637474986490855563048804573498089745784926319\n  7751447359585777356307725467852982333254687020095719748961900232497446877253504533172730924230889057\n  8830620727285549856746790484861180492665365738111300318254729987787422632245052354172183013256341795\n  4396498386793829456411967522772180797079505564445083804357892004410159910087105620865457535861988133\n  7544255212730289424165307580303308079636039796066642428157932448605287249560748740903618136406243020\n  1765226239558683682892096274924609118894291902212698768197461064344788994633549049367584304851434998\n  0646095449673288773001522154402956812345344894693259234979855786079219347904248738644206792284192513\n  2730049639053883815793747911629959337347104425865737219183591342311892468121510056417553783567312752\n  7720339420845773309322939337741474629120414336423758453227800104181991754841646907988966638034903140\n  4208579751276702343697309017820412023120163323706816098096193762383531664281467808566072208949378140\n  5850826582561206415669080391330145037873747008619163420786896584131327336331436338237259869247856701\n  0819887206149431011600932643020534519436686730988893658736185274628304684865086589316628441742815813\n  4399120583431847933143825136125768653093775747737196608082413879789095686319242787821365341453517151\n  2012415632145577261257171154237575230435611185589196631444230869366705119913815340322621062159439742\n  7120765465231765198966424475262047151909698917445511843743312560411206000481062834177449518999061022\n  1341264453400653485761580063364046688273922022619214475711159414547570565243538867082174995562889089\n  0167708239731020519483887183549834328808886071103617690332310781379630557273898112912770386827993216\n  5904053146896325986391942915207644121837405335668958199426520915206072234787011150784945992637942582\n  7381004560937340373847005260432400476515103397442629158978594216190276546124371007314153313395606701\n  2099235705589355558643733246623936827338137666098856138608175608552575188182298236562059303984802684\n  6892564831572720381963427502449053813871227283653813817411890381862937066879655274018351601106777215\n  4427487631866938516652689190966932412414576525175477138616790707468769050286308364149318965595623542\n  7862455158759933740486888805936350947640464042266902373943469381319809455398305963795278500402818801\n  7151896873158310682541473547504832093766879887868201624977207965462296599869709286344427118784043263\n  4846582416724416037900486290633522739626326436896952186374585547737927708108320998006560378549786179\n  2816823801844373777396596758291322060125539286970613118307574973649821014731399951378011958363046578\n  4586218819441497849370098402756006854980263357350276903501334915999410634061547078733290603707231161\n  2403418705507883790008981769470259740812636634023320523475949462864772027962521136864483778421277547\n  0890607510255301454648072545962761137431679308322714444951825155320253068899305853194831806190976281\n  8016677230361216606781369517176487597906417672078274900447456671143903026184811709882218889166496393\n  8685131934691125989498624773419222103929318565373462824471898957875867961128151109965937010037834603\n  6699083660549953931420999423492601951720056003498594040963539910547277394697990413578702263206920254\n  5498416572677427946396129743913685217948503406180772850987428122769011413681640284675288754276648347\n  1728545123898591571606211062103861150414532497879130121380688937808878574113569402360108611727474907\n  6863458679625973610019911702986963967536056330358598505902404485705231443082279855858042106676069784\n  6685856139920532524870355545853701010773500886495196354119145399547557065526277584357657458461258415\n  6310747495367701904508846045178961035630096449832567980305263711009034833683273800925855783963976978\n  8757455040977616660990279542918858930891795098681231156305389211681423379581310829419130185387664983\n  8432666048909688018607869899694639519523554122354444951091490427932659316891653845246476121029773238\n  0494910269720631973144576872230188864547231035203360880327345189251460428378272357373813799044513964\n  6145877241578009918294527691148925644955445782081125854974629912272326464903975079642306002619452609\n  8123860389417285256976447427429289378164410225978278080809381188489828665645075046990355036823640457\n  0287861926400784608310625668967210515107875998062605331021001223580899087864525527739274544838949424\n  6097730976810328818104837755849053575436985478248720979623960285646337036722444725602653139281324322\n  6027749446017801180064353804656177241828844153793279733031656426254964457524785225151403332921802994\n  3636689200450280879301458362655927453036932085819923685824058244928679704700489293410367432496807871\n  6780528715571526979538731761613935613259300309851874585260746042807145302953344424836352786309151458\n  1116770338434981090347138086879895128909270471036033367710778140834844624686061472549883654767143507\n  8971650144527699386002279228873124616118886865145487571245875831948668196071351297809734289009348299\n  6091613721718408056889128483203073780439902980119776744595260872450178788482758220314160796646845338\n  4013730036339352239132617464228397146920127293410803224014862978907413563620435519583015124060878235\n  7990545993705598339963964272542888444321935083739604441268034988549867801424120139847994694742672513\n  4575043284161152831893433625782555576248604469892081082951581213080747248488317379714406575523709296\n  2046872292297505739043255293584811980266329093403989497358092902735650265209686282787669265416618779\n  3651464999633518918591982811237177058085129088914798950229698022775369781832643658030659460809240080\n  1768907232584144129719282424720380048659076248329843266612530268510334990265765785799633057285781580\n  4481506534147291034011865107527575914621385957555798465331746524212479703562965764849716996877845984\n  1432813641506265880323735372672051002039187208654889404916333923844805717563887250930123137906973034\n  4640283694891453218747968903689080091910769648752267931968839730831363285516442848545438955119235162\n  6705524166101161919395623212154044745884493177603326458648332699995327613115608198673031798777096885\n  4732069736111069687352300866613257328235545132889270735840381580895934095400477668633738822098999477\n  5888725251392894710257611581130581373079256950891110603633747143004818074544707123585696701876163044\n  0248592810294124481653304300197678125184887324291465465374765308407856299090453737847639163410697134\n  9483164149431772592573598987741410425852565064699225753338667022937999299024833844979636165826017703\n  7602404285435251468929382667737884010050407781498010651565529747650230253048184829022351663490708944\n  9876811196121510650807088452894029830319134369478860719723091087906545455929044269621024126508962080\n  0237754863792190058221375417994513677375502934421394783438454088249683005596980722742714752346186384\n  4963300372011058488444262822847183566951057836418070908711811976341346792304827999192942334443433745\n  2657118519582758172429556975365547653558571537158788673155823731791203581943368590246116895493584548\n  4381021820980564566711522781111528663148797912241046715034541226359174023105072675781565169079497535\n  4569546610234350635178926282007387671578418448532331264748169641045009329526393910725514026380972345\n  0742145266346791248799219504249506398350575631670024222097888845014235493326447708542073295642006479\n  9904567282882730897363424016355981512716558570876026319347603574797113673228442544954614124103144112\n  1365329590731844662678111062740199008005740851336021711329191019148172385811035976323362159445906860\n  6885817458272106636078324721105539882285311162308307722493207187603142835549723999909543867479119041\n  2064095816350306921536539525593982910836444057789476865590642695907855588927801481153129605282973963\n  7830522396568797932913415829562315501056197500574788258435068389480272013168005449241765541341553672\n  2967818672262975219357296762159745729299827845769995818570124704106527552347093167602108874620189498\n  3099905626803547323919174388035285239451968559022629912340556236681684202614065946016614268981636489\n  6322670567145452761552084031997755218112222830694640282754583090788009525538267001174808944008582442\n  2344840901443930995076045874992960929194486787284244655294260355040153663048572784575067890334206375\n  4856518026058646545350492315463660672149559792319961283892566068624538219662137909561418094819626802\n  3483737048644539098579604117131070124331472277069438162426160779174735893060403221611731902362901081\n  2414634682390910147478453481264736939378034508669020117854092269189072113908427362640084022560952795\n  3662226878036310749929518963349372478078424620773854564629746985678187794641332775595949591985874191\n  6684478301866887582598506335809530473059262795878826628135669574185663518366296779633536616256900065\n  8834528478932612307942533321209343130986170013940224515939863015330027588574482615552011632165583054\n  0110902479913174431860947888944247191765658573938336152938916463157877752069260989922377842721076226\n  7547136296772652833826045803154881842918345790562055852313846748688098747574182995143608952757114896\n  9698465913305515718249017264063469473831622484570295688213478321860050219757949327957537140194691987\n  1033919215034601174895493500576483118480038321070455100031972994606266908170328465232638024224858174\n  0354229851081369311162482037815682402670540265060927629574130039459067445279197996647299332750032387\n  8534455218203096952772541183313194929837454299674345083494569207945583308957219416697425544682533864\n  6561066514161947402732330689180554887144239701482488141302433322116028228928803159132754604063931447\n  5650451024707847827003100830623983379035059208538782367438487469071591071661383527097558515843491321\n  0350122255865928574296051076914689252902235938279127110071779878737897902060104053792712655426027857\n  2353850665444666703866631450870991655715371206920784426287258032345585653143785432590390181683860053\n  2754965792572606903799575988813473068888074744754711193224014850571325800645281485106494506217879717\n  3665367581241855617818186509256591508967858838537346006935149766940200854142411958615773819902618019\n  9575558106225483616404106207630901758560745738847326450713338575654604173253371130280137894079385793\n  6433995336278092312108397002330283646942338620299103313769745072519281930448106053614889812723727553\n  4536451517984386997375729723447961754122638543250152317808397255726878502256871216813534253902834781\n  0191915420343242593460913311364251073193994337038432388613758805682715616485493653802378509039348336\n  2248227318207409968453296642006626803726878202648670578298511928450302215815053035641756893775421063\n  1387943008169086192587428698754675509234944739615670759250191683691129303774804955199097039823363826\n  3648913505843039964819572362115740772576823369907023744639354292702053460448038310231444811459137953\n  8474923915729431278074120440608030975872966973107181984410669334082604969841515771659295519486558164\n  8675779423393689882775900357894212761604704734211672187920488769423319638405449947511159325479617623\n  9384985382401964770818520948648559242287732496687300301024626104466769085254560976052527675426097221\n  7580423153215767353290753481536411137564033449376447731570107441776235823186517003547205375940431782\n  4599133598339181781909632989815139125754319138983372544052815081545703102289680299577227508331211659\n  7704221998268965832469412245112832949898729700252886927820088561271599497751356215241446212011857260\n  1525246972290915140464075319219928173428032761859964570258021156017462090635890751861757530000424919\n  6720092148567640159697615970405736942590356827057621726980826125845805961670618866332840263385648286\n  4261038593074900732614647683459041578797930499820505904321300238863933029787387361962755332185958012\n  6622163258466407754647657936338085449649570965549194681612051155694391080796813539384605975006717950\n  6310256122479527199604657086253843127219194520031050931912369479545856122379295846744832208038385192\n  6631532382845070622235541635575201604845859578772796435664079289773151778925432460163741951653324854\n  8662125998117972463576280561784916758392325772236684392313904636250636402302831723001378553839784405\n  9603568332684279926654616067211095960638834242950430023363651087339459142466082468786791422410972599\n  5512135343919323395208857001590380446982663110695458536384642995474068040679609633400896596476123350\n  1181547182215652025938005625906215027290122242604041472615840342781626054598733857245637147779216047\n  4827443344111296731237676119862978669863080241795004730990548680786839290099752578360568423252734512\n  4938846464261174378459017654469540965159470872997650711276266611757869601903289742862638348064602583\n  5183651959147287102541609034171076266775815046516946254495799382899617866660985727357260685506695869\n  0375723054995572090626217139470396850395236312944870874152476422506065216697079552830412810868604973\n  9229536592431541725993932707486079566741459387068412327500416690860257614875887987623593673475462930\n  4596834705781824339237473999249931821377630383752990385151049213862685594862282898029098604098401166\n  5073222899953224056223484778426908827773333002520957071638789137572836111316150828240586774806128378\n  0997658812245009750709847914399252401416224053285985178406026775338192282678495278866724568933375945\n  1607319568621685606351203502463099283741850780760420477384305325483876359241255753163645229316351178\n  6522282328964448319102692474163633999280535309366592617986442495494884617481328995681373139483095949\n  9581124735554883738711252190337005154680402367783261544240656690622404363579199589191618731985304828\n  0061974222320988366936470840181232141747627673223947330600405172628593548541188246139912254599360462\n  8969714134165203093502573559361261145139647646649021062754457374977144715508058882686031359661575978\n  8880825134084175124084231421887595702639616666768421788501511665029595597861841596054792017855481164\n  6541858311314120912782845969044480818199806314389038052207497099964459268042684734454155781033449320\n  5950156320196305397621418073990862708480643032178002476090143977156423120072263543493273799157315518\n  5911006524727748519971019847797665568944919671648616867079037571706648356280803259648676734045842056\n  8650181937024269525364816955814590909365907807686812438639934256553533046505678506554865557128211838\n  1739659983633576780308871040572972063848194704823330793522090608439862801838670895297949455903398039\n  7505682344935367837444146988538880452810081360625583295193112119347517762845206651922225273866969263\n  0025665605713798746774722632191103954463938461218455857756926921127446965654071571414181979492296144\n  6403902152393652171319701682379101625390563079628676903703669998720101055197275883904902666193971648\n  3481149742391173870422714295049803918440920353535056464826470908831627172704391412142384229216009271\n  2912360067010295249048268895285813608494320353804135696451593092433827730106982907400363781910721422\n  0109190692418721602775558045932649015215059414233531352862778826912685057008770944176708211117803391\n  6132310778845476958923562860626769063681154808619448865059856349824207852248210273557171168286043742\n  7930019053242147326980760359336634855924681912023947148092123328418605006258537910855539500693514325\n  7214182173424169658289168710477383110597050998134940969399553351724534645472530194525002197042367256\n  3394199259591390300437260389765339723331018927319980366786966546139807538001500749940589639656960444\n  4634104888910187725401758136482992701898931874351475719511901643262456514200623107476545219553062209\n  4090762265639677031822328595936090281625230627976852910671388077127464190257056024461237830789026485\n  4860064900878587772245828110243449387066147744535679373207145334080832496103686003164871160455763852\n  9640009288990565903880787201538168686057845360262395376158436587641315689542018451668042531125090612\n  8057586051851261261263727019604236219016699129075528914842550002031663943368032040571141160423757980\n  3585659563124749946956984951358676171716148613421187649219985740236045258155314008760929919647446288\n  1338290732168822691315735551490184217278167785213038366037635612900768544531563881090587180694081778\n  1907895745143359593839035139959232215815478747867262033422730377952548101343348870112698825270694572\n  9704429254738586395894031625241817680103388373892597828563795133490722566439821360408060769512299054\n  7942207745586977993303444390441999735760797502802035252928636562271663753010434815414543327065339165\n  0995946735871134933382166989485670557380782200217312093915300782652612868451424290726599905709582548\n  6043035452329999651555781461768952857780536654894859263172911706262038297980160841215931881886962902\n  8287157978717936884904025766919694789119701664230794471163004796916602963366541165671412926658386416\n  7655842583466265066904169951079819904156389709616578360678034580385887549043983668110794625922809484\n  3989003473574576572212780205076636124247453027283277919753687094602692110264128505204647715113195909\n  7597847520095406773721741184399590135072729305996362535527518365125842604722808130501701636458298879\n  5296387473523944228984041274230766926575389191293792702273587158906780074048592164839630908392340398\n  8400951287322298306185307149444124552897445431895856118740001809527520962851371172568457262195438787\n  8592562737224001189285921097359177445309099137601857105133655268996097982796691301664713645669707323\n  7081484653493878889810099483298222045461002017204361275120315381165829910151186943049114475937441511\n  9921482776988466723909198092150851582445610520088718546069873013725536346329956445546387264452326955\n  7824381689553110896531340698420412186385006905379902901129655602973049646054821960184977149958716016\n  0186321879285776555148260986889146641786743554863988576721640798099307846447004158925298121200807754\n  6940444869022853477093950868213234073387381521176404447604834555293052999589302071650213184557608516\n  3782416290715979408661795263226509087062500009785294598803412110825577607201418877274907101283893632\n  4373447553276610994629820292478457279595995866906046000101825538486745656582757507158587296867716751\n  1148726521220658930514702981699114593575970624052382042720167609089719364403104714270189011229197278\n  3281602113559756325548699992243388504519858282629103818226122655992591597082919786233193166881062975\n  2541068411710862598703071440860838890816173401839452178676169102178400070572151153318183463981090485\n  5059841908065379840393196765261825490144962826381313686830190537277629022140822825320503157581449110\n  5214969340080059171842886747423281889208221098707510096094222717960611868752310865130548794073032475\n  5855158572712956851667115026585753721524970207356655428748048188381689438092947193924970783426911981\n  6210471308309570279144044887529446522288091642693221208914373532634347018941418654987580854438978375\n  4276111604821944985733991946416345105882759641507497086868706533308767468551708636722004133550690898\n  2270336380872483247736238427671272998279000472375033656913596485058948711797177358953752351727045329\n  8808976870603717168938131149261179907638681757227782503037994810530997141332106791117693908249785759\n  5017347343274863356684315499742555434287981387288858840828665550630311692303426240065192461820851294\n  0513841094383383099433732356118408341561095254744542667874415394527438085478157481718055429230172577\n  0825421551455231168981598415763033104102486785934451395633720568858890690571190839996979952133448395\n  2287592283977865693169705450275524986037593813800658952570565487153992594249997173171679762518307807\n  1800651730515295633826327932127180626959480634164969102111602364643235890477243477665172504370188262\n  1158437644226666204751278252351887021789802726728027711822773152103035872642082452898843316831579166\n  6499256821611449903424669515324639135704780768526898998489320525337210124674485594511686982516508631\n  5065590233506089461332596475857404743071645102198896466685765093083300456818727572416807670592160435\n  5468100929255939564895332950279715672189202732570815062770907173871031323842496009919676665726212488\n  7134992056972358693324073811177055732346090215798472234521382771579580347220540258966441539053412137\n  4470050890338715383493907836511458079202721014790629798992357303403249969762406078897321843108824493\n  0826619080262204999011285974929556277217464611468993929401059494209733817594382878025044409968753401\n  9038860177170124591227676884675715236965521220057724245036539737696902851785827201084335983398454456\n  8178406257490431917087743824104031867141420417203681142989503677256546071050128601831884330590267041\n  3591446899968847178334704082914681241547430930099815384258505632760473908768904927932249240953499190\n  3416211544608213898364543627345255421371578915213206037656434612877334642326527949078838192386444755\n  7705950091194441422576047487273346424607959246298170464153460651330840957147648715521286086578470735\n  2955176812758232095338163731442904741798402689359511383623361903652219368694895392929861056065435057\n  9702715511242608643085927282057320382452863375360040537159776632209913491222622982155246441341529456\n  5515770151918986924072986258052706984831289548079625435319741712858425766114028200953496918021677875\n  0906409638893891048450466408657503729405221041128000954731966004650043944216848594220901445242927222\n  5584905936638244027733283626450303053353993096987770343090712332576249414960161079242873166852638845\n  2751267060300570764109526142989664881812039606387340849855500941732198779667532749962011869772569041\n  4469020624776565535065664237591469173330727489154340583008070722148098316774819302173684537002122864\n  9151994480864391860713650673852662802901568680073865848269567625421052986411659338692482538337878752\n  1349222969889549770334204786174098071621018441516177221481911004373337116936743087732669730859901037\n  1973977949610284291618684127575699139864921142478781435310883070128710377476645242406304328370837731\n  5256119447305575523791098461773531290644241044708945166904880695091460731826894492787888493093950009\n  9507022903534353921332558947652503280710528542412429468783066310827995140399264853819433461802956014\n  3112432856484696531717017391253878974666097145394227727410114423938795895987891054566410426814789116\n  2685728035996783039870978666344440474495023780537494089169791738537209747073452739794605724927590824\n  9278258335068256908378083545693636681739559150054891171229458934250193970208963987204233608131092995\n  2781885040277128738574435470581971449057130415919250755715118568712451386170846137621994813881555082\n  9388483756914525902356397006311126012211800437038477707067215788291447250470385711950858809347550637\n  4838293531777538088558941174192632937495430008507222483922287543944226262695981911896956305252790993\n  4629461536093616354944787917503777137415907062317596724558368532599842155881031625624442765549902532\n  7501763136294312779601191643050971695953211299204527177449654633602651536565828841936387933775355221\n  0007523306249938917088603055134982454203328601498822518924449789713654388787607325839686941239838808\n  2043346266117220437998133074235136784990845864816666286201110167877285493227258973179629008389380937\n  8368862243092816036269180732135646537153505048869164778779185842773790818861314754357370438396416108\n  6684544778605185698836435455394146744883622569075822976566805177777484874297315217407172224089962520\n  2713446380289384331452516983638073117992146783653334217478880597728426160203584308289244514390795487\n  4192059946703109376776927346001157263547865330378705088255862616916954752736042627652426280382477111\n  2903565310920613755010415351635002947736028030426515606870445034565865327374888313887136360128083391\n  3126850405697305826236750606618539761570417421742759409404777662958560993046444536969357131235331390\n  1844731016702853668941803502361632619326787257731214972498245087303034204762585225658713844171927986\n  4813496990033682366359258820601075142130599354051182398221393595842421288680155694960131634265883922\n  9035170296385493143120268575172092434167716759536738545958915630415154340888500416067053346654082813\n  0700832897761488249696289240160421141615103617977793210297134762657997940215469978038778479401598816\n  0852142135353041497943485318919528301157500655585264236187716442360830789734582505232932436402643759\n  2459180056329087230507629703648435508696762133108287701771634937764001574077061929099773118327157053\n  7209205365402970776786726653277933085996580010922173623890413584279519335088822145436519113434014342\n  8094289321478884830738725770497425332464660948353516657817670744653783648028470969261013186450293122\n  9616599437355582029288202344507282771381373531087386815666846805841655395240631511573679215491126324\n  7750126529807086865320787180461286792428807755570652927825941943007588427801209591016637750414014314\n  4565160939204213995507274987872445710941355550450157228970947059287154785784237549555530688277162786\n  0681824647647199972980036733287720747522653591039754964088642547652414313788619066227139203374830355\n  5382843444764459824363406532781363195780834389918402072956331227424040632911369762268565400010623898\n  6047816686297777840312794899917073967230675221629509652878963150378284676791610967455848873593475491\n  0866919617224603794332653671753266796427575943996049976680661204001653302850494997286070427542509372\n  0773858637004154410260595244937075850036378413818607795676066806461723429500752397765145943294896719\n  0018394508535071152508262845453452737577969122483337192342761582030801462801767562825024071460250971\n  6056309317672459307604868824879005384715805207507448203052649668981999402515794942321159027841043254\n  2583533717778889923951746366574326137285181100529275734664184818518156994434040881803768753519740663\n  6304783372844055818192994312492820699574561423826653050981344664300969883579889993336482496472266767\n  8660948382182006917644779951541006483149509234023132985550207601297659765482514322142772658066657557\n  8245211435118357337237730492437142595702958551587115638880779956709924041678394507854184745979089815\n  8041308296754681520346603969878439383081839237477162789771382844434051340951168427734092176907252476\n  3108922444664789116879432513222007365153456231185501387421523354450308938853986101461106907489109566\n  3596629481504685467562292894151089237294319319561491823182561129060258364287817219492917534538823527\n  9936285889636367951806699435539473796067883863943299218278556841255867799549795461330287862146465157\n  1399165914028458734870270526106981706256806358660128164497972466681641619698798867736847470963519634\n  9675767724117193889891161841016757249065281230163968169315003082520148974579738890015268240237779830\n  9724004631085064997410591209501570775841414891805283246730618351409517491370788512597534824769265004\n  2368546235843601597072961828044309168026370057859215113722012165857223365413744447659413954964395531\n  3251616096580180992087790835257903757726750622322518588306075693231895633747331807153668699884986386\n  9143703937913796902175096258692842571691290542002081554697777269088469155248117449993657072604850439\n  5080918943285304474939896300603185187727458210524655774108122548587461398410245523154697286056159900\n  4919730133874530431602324644992651250170425989598182556523887587795429109096721908835535777249868613\n  6615280495876215441732619304117924969971423648039456363099307208351692249539620200838815119183724445\n  2275263668892099295766770956673835188966195961605375350086023233648287212672794571825927178717732484\n  3095828273573981941079466564284153735209789228890021037317202758664290118383502401038262269418554517\n  4623600553905336844479903780231493500910433515559836118650126049569602591345769365876222655770632075\n  1802591029709744929517888542021192971691266310414209140107864252386132081347634547297753174408567322\n  1032254607393016774189560202729920316247975376862780784597105213268572645373624225531925095186171876\n  0134511243376299053555461959175254804303890441737617913169627434487853115501952536997807793447126384\n  2488993435819171956729612216520534622308553410454617535160285303531706014088121363733345863747449007\n  1286834136213074664314991962645876623832479456855495264936646501737302526991190873488938380822049031\n  3999050562754439889044634722325658585987911886688740806970103202682039916459653939827631397675758675\n  6306611912485289248569949554527475825958380592669805669093152791187730205978970631378708933883220709\n  5089767335300855561529457849364066391245229601266959600962624923623543500671735657509324621100978763\n  8785940003781112255481862865919130265466121607498035325602344356367631241181589646973856150829519318\n  0065715412630622899429863180944708829996977823600837319327593124537302930803197083916792112382203775\n  9386912820570401257724448615797828970323720982431419952191356933990701376486572379409018973102677314\n  6477049154312463353149231164982846119122320443297987988654550488550281722412719641296214255244081433\n  8331848355485316489156555947284549415951832993178851797857233334982197167452209398227947038948309387\n  0068880950095001760186510756826190182122598791106735765741023718866272469935107575855314875850606889\n  2653011018387189835211172154353512759382643296902223394938045976378558090731716349568750327089865704\n  5091638820524807942352227535687082560260318281292577270037991853012635237990106194259570352197978694\n  6037934090907681690393742403294222448564906242924069041355557978176280993978467808750873788927217350\n  5415721686106252435312971752870170021713892652686261966868712382220018081998105567112872178866928665\n  1408685730731420302602941758006147543396996144541957801734713074532518466502487391866312265912601566\n  0236378626652016174160913156721283704302383185801183603595637611440219634198851777358715380279808392\n  3962306959289445028812707711326597922053836475249006386505384673526547127960139270574253357239928439\n  2566821190075920761228272723860856213827653499339217228831328929444455418559118523325131830035127913\n  7925207603882293290768317757284347671056843279974476200796878545960902303706015474437242611467397637\n  6141025089181934278782304188311556795804541243119210344135149026909550179999604207232260994274936196\n  2125944584701579942673840826916807034200373342817358824220480345776191805538441867061092786475446871\n  1090427656490961336789669320618650990481167965986055034049205961741584031837366244498788910350470616\n  5000925499423394566216562460486362752367571958462127097101035867837376285945519035694807841844204611\n  6427432686078748084405425187122732222002621434798954295282674932403815009818480465700784161918386349\n  2574776926460569176755318367548227892033180272665310931271164367933819622800959541330478706842758615\n  7839815966786353122126491074162834036375848986732387826613769035930136232429615603116634579503348069\n  6041468095999851416733156416636610638135933370291055809518610025965969335853813370266720930385742574\n  2167864290636425462777371245161425008963865385952758013222891865379060793284411531239571944333059711\n  1674626649023894326671796113079458231044119190079783881715223000670094400240063875922694362285108398\n  9082522875583396750453543274241265645394801066480187933702647796786435630154195928502562439369802444\n  0700414898101285038476125576653219679989499751165166552568035436426047314998069415767114957179087061\n  9144799725227147952932796307353587611207582906805645927075287717611731266294567603663357133534836225\n  7492316090884997339500082390802270834018442186023971562268946975901121116417635281961788002013550898\n  6069980355503955076960175235571734913676580503663480989176623747277794438892098679516938936159532508\n  1576104264980771878858319166602587545585580207124960203569014360241160676509441751163995525117604635\n  5458354558683733327378353855866576517556532384665889863983862957934979865807839120288373221654180551\n  0150451839104689209505644292618713072718897597198522462131429519367378454725128419139172808431950208\n  1487214486818091226214195079624858367872512008495905249253663525575397130128252266631931267472711708\n  7401687401981820530095690121079949369324046386341005226062833597847775099361974110216099153341241745\n  6322272914289845315460446793246316585082059900844430445292356835613059585727698497651003576373809488\n  9043789814971338944112155340478285383410251586273452209298137895801512526795905016883811079779373785\n  2314075453642383267753725911397231685879268790411956752555832558943262474631695959323793280773972152\n  3413165102332695551004256713478165687894432590102030761299318706117131114724468473809876166132982158\n  9523733673235671671545614175551623880797120001523453111994541783387246086759196531569649459754343526\n  2414717377027351623521869084588169433264954360963069032786367827217343378723421220127791453073615284\n  4291764593757545276655117361662493776258341232669470386618010995264161414469436866655412146535572510\n  8823132604443020594782957064696420840506639720639317365073513173003880445262259603654848636596942695\n  1483721919405374886648224695513800141661753441310943976696304892594972320831753099626143078452993318\n  0165084520803236358264421016274310136612985587054229184691858535800025965709361068886707408368708490\n  7612579947164130996388859772806057254383677775945949487903959265587631921103227650583873043998704354\n  1540772170815337122816972534708480460678481530339827425354606736133106255364807823517193731976382923\n  1976068793186399739397093292358465259252548784756066958736726025074964686593205347603330267022587893\n  9971559384670734638222108716543115987110832363590150691704625433514220561500233993163621226931614164\n  5163467224870089085755978428672090870503505953911028556125649913517596449387846853627188016450215023\n  4656608575440062129328084245635478066713704565685192593359224746434449681389396409572880300774156674\n  0902382614245016397148992671505880621404736388771776520916125774301134751954522037490896163122104904\n  3534651801900090993521519640471458864773560214651224794178059004235182076679650785800263851082616667\n  8848558950749158645126619309838305834826296907131706731071719728080776848480579658754441379929449107\n  0474718297280178725901703403330009230392538061041675484669889573135068038686174263992443690005077832\n  3469824069242703312234425338168695545685424131743688576721218523392455145195436629288774904004394559\n  4665507408427025138815422580127799362494827612553010957594107015575245701740197885097699952595617208\n  6894340915972589634928359294917641877073511887557335239097533861390461174419754910858237894535948817\n  3409788639450617009227355835690040585622723780649116217992575263587677173378254508192811081021590238\n  8311849529597030289045463552392776037669718046455009366389395271293756618364987721355743227583521179\n  6176974028937456777117102096019708609988891974822781834064514963240191341985954666751863043821782298\n  0536476808596413487848827651335906070316166008073856450236740863265104795655555239056932413659061767\n  3191577439406138380081622869421478366058122796601378688103642239344928990155827756047672145288752696\n  5184984097572531141269697999683583131116362301667967637406820847352207648198751988229863052801822887\n  3740084633583983983511917977005782448199586712374407288542554258820673303865935123488499797026231342\n  8093258461206187314490573933429526185556831586472346508233563111689903929807462373018589617512746201\n  1024135025301650473598739129966877316578879331468114620930068822230887206158330968583647938117175872\n  3221188044075636045626651016083443677231341484618712669394355809447299222058095400341747711692494857\n  2249761131666871509490601304242787861170021809547239131794441841677024576301402297501831938044884481\n  6047770140408137418939545475965527353961460351911339301223133299133292565079896523080905985857406951\n  0691920327933473397266149554170561661608154295217879242085018926158908427708999081541020516351796459\n  8157545596880694260180013035578554702715987600680733145181619407836722122385173317731783658569999622\n  1593848758839224899291106871277741693137472569565133430063065227379245510562669218808078118325867313\n  6960112090771466579443662883300144081586309863172641906333044044508058228112815488916198322932731818\n  7999588512737838729385096990500690958150559968623777129423176197294040813941813602724051482082073795\n  1363148433542279393342776536861035254077258399965486187460681108544159937826344218383938448584852903\n  5304569715109912504423138252492529540089600277653873866357415638827431411023599533922274661428089503\n  0235763018473899695696878579647614813385274626000172840076610353359970011074295886179093448568823861\n  4022120262810098784194778556695767060208297297284932172835947885074785626883541396045205032733900115\n  9768997592348823789600370474350944012621810109481571513305005269673475051595793024141924677188377990\n  7897096741985620620603365776260662003934751458951212313889676805215858321485875621004939827433779291\n  0008563459608478727443346055618482163033872291055643309346721926478665631468981442003818721109343897\n  3898630381721295790929911274307671977729157837674854628928521808203967143785079336373695007727664266\n  7558541999588569725888941718854732457041265453872792938355542304128413701321311631686167649503182078\n  1233528078670360575316926111114131927428779044645590745310830304595611994778892976495070646397168145\n  1462945312429436355548868636124882656124006440932704627209919380249935389605974433512849065936304283\n  0104058174606123204394459678619943758818210788705529097240315088518044697672070493219326427327474947\n  4657352706314008460022706069559676968769935816122080876142890824382822508271626545101507650711225487\n  7678312710489858125890314808011532348223548575625016361343244575548970840185256248785584116155906291\n  5706400186193826787191671454229784270131855635300759233917437150422523687143080286973897230659408747\n  2615583200288560564305436754730126975992391214093078205163473056839443576608050549539129145864564189\n  5198421266755703261404016526464718191682556178050004366263986812632605156770373757632282557237224033\n  7326563439926101072777491347627176169780024202417454219633542368342108998205098399693090096683351729\n  1556051800329123750279741383363465570545278348537476157707297860282642316989566162153641506119169118\n  6958507630088773984133144332352216108648075376275627953573261927680750591791975382208050553608592143\n  7064255882040794994568053209984521619529034874717291587880433789802719917575528412495164553897366903\n  6679774585106049237316474933485138913107670478168931509280056525080740033602625587974658733895886504\n  5549105944187115107898947642772391413200859027313482305147114710862568442443055612645731317975946690\n  8304134034969841895264128081303923795354233955145164368583297176727033879966070502753808844666613249\n  5208470595623603513288763569283104042351423073689830225761893982210451471164975086495793133102305164\n  0070274041872292552531255505075196263090141904288158378608018722688533033426032418874199474309487098\n  0900779689622152127820403638718498691155689285267885143692081119896699199175939442227659858529607316\n  1102727719303922875037352767460313649872860148590878010890276964810178419250513768363944327798589783\n  4996707510645916080799781498674621295942992949510345561239528518996648389315134166342562538722904207\n  8570031005057667238782499422930433187629331075992163341034881853078945786213043844699022597151095378\n  4248396404519561395264994091054193480278333814105054975038632521344166525325783462410543137242051343\n  6561007097502647497506018793298970049526351080384880012217081134423115923301825065523290008053296095\n  0529674761782776499033804649275642460784400622477510229840904464576088284008438396537572516330908693\n  6595011316680590317606539941304678318604500629809546411793222760643945450974640311900040461013636375\n  6652514763392205640853948811565665156414499546999798961551708519238964173504861644019602822837023105\n  3195494455715777919567588597530366609882202496886496240237376974149089622782626717164709054545896434\n  2513581072155099312787001810947933780019428811697138455978130343759117449830503972720050883851002048\n  6452766917597291317151669041458699094829963978857884712415821518191513119364659265502246995225206586\n  1237108617077752972480096285573811172643504397723991591353337279437121493974863979262479245746309268\n  8060161268332810801373076067896388530352476247957729623303632060797531311700321563157739611414172670\n  9684579198896782331749802500904092769839889486946584061970883711871716267895059803799281868790835967\n  6744386739411089537196986182976738458954392441121744326072814344156833377839658009332416265311975886\n  3863145759699162822606077903337395378068615499543343966625340413723933605837613571366314849602284656\n  7534731883339597694060242585033382282696716025148826483767031393661503046556944035909979588086530647\n  7527207618121415394106818553151735880056317978950810699820712326357146714531162758252500806200983530\n  2998598765345615877265590577677705235068007347211604498064883912344314969945662968838109923179375961\n  5151983265012059878144161793289005863320956390449673274096775615657921695125695757343065011177279446\n  7699754846396367647409519787469857405002566630430496930378286467308890740676217208162910009270841088\n  0219803664690320066048982952654419736165080870899913997268065256227964180494645415644876701280058394\n  4430038777135570780465643299132187060632208151427506224046357396332303341712920530795518615942218913\n  4174393464269860039630400508002042870415729593735309957716677615251624524092900687648409445244870829\n  6372347946634083467678892429045159840508607169534168927276857026100718961752877525160511457579234875\n  8289688272500582964348325725019488704916732932741441469386161100821207301489450942209156113531966015\n  0600951530042151879680050092567027746169752691736633588478953104875162792541522915736474184880129370\n  7600826420065741850241704070543171728758494534967559692560581068000917355323392465539765805611506266\n  8571458886231368778250270750779389298522128983767573394440612389601946254801496866953716675692027945\n  0041465728456706853099431195910398723702492709010435325525980501157121226328470745074590340596438552\n  8208729191184983955166804404872154753233912561994593028105975250334168546567651849453998885243277578\n  3503720834777412746381874054586392925447115055543227998182086818796986470104656134118680053965131346\n  7232381249441404741459647131100723335520281233852214050723861536931660894605930756758626679075053701\n  6110407034090926282674887750285975237510238545267796205530602752777436781940577953384076593719123390\n  4161229938965877540504209331657806959653412589292769002105835347234056106514555429320091707450439470\n  1995669836627702247022883042665069045512194383705684670838235730118163228543400184304949798582621768\n  4156199179199351241530949158010079374774040392763688826938414993758057175171344755815931032745774187\n  5763711877571322468922722424933777711395755848434693143205619352281759976456338446352366793269416636\n  5293829299473155416026227810434045971282582242670197609692542335680025383489465631124951701468994004\n  6400911880740870773299643030944043581834084141758018478995026247389569075478192665221993496740541728\n  8191105033252790021585459431757345887327695863977413383026542251574881272858188927328497769691108525\n  9385652172391840425825823144703106476046481450202221028653330865637440225958804713218694501443668175\n  3853073158920051906575480158234491548443177708176712520461196493945018862567637414537686456006014215\n  1261292424645967306428464885104976111918846720498664547599992680177566433790034005684703754475628782\n  4934898408714007702362965041707501045403006968311235317293403026317221317086176202960434454820954348\n  6763695249394153847667538095773551214637499080503829564670902052304673985564355823807120013405179535\n  8177592661179297460148692132026306003931799564849444447316119372536942062347563745047826759397321270\n  3372805781343126621117387222492806333639834519303680389259309688995209252035278571980992380576236122\n  8496065232769709707647903913942314021333686903948086876847433080122688699462034708237163097247047250\n  2810603314164701447412054213824030812834719100930862026974909153607225275128659774951950701446835957\n  0342661460253028153384827277644979007768898074458301080580762580282652539846712184990443942589188021\n  8806297599563142816384851120947134995242272909662562131057200278602521302716524357302013219950531711\n  2041933385624321811596853531436428098866010958543685260108529344637841188537182627216507454141542909\n  2412576342816834642480358183339986607357730940949860657066158440701673506468455108344830410340714330\n  6886135064816123133500844233624141744252203847162068581577800344074422408997737952507722722425221632\n  5270798286483423936031993600770157814548549973279149571524204777183259862557471172176000475918686134\n  6576680074791388238882526059503696145637555094836455249433184937579583447082565112029771305489059858\n  8936049041984366155680280639101693150794123984426141463145272074906342167466656220820733874054410275\n  5527732642572666260325434141645180646462013591074636904814091394881734915019090588786588657560805463\n  3191153957951992269151017526113553536548044915380523524309209568391339236641860218486574056531386585\n  8918038882901004954410539504281908521709568970985222660491497703442563415201133543595601620804833457\n  0567858284751828869432645728470941550706639004202184742841481507293211425552538487682398405964036946\n  7558558706507780528881184370543707668539402043667908794727576997674271743908241142251517023195532601\n  4929205324852331644303361410581348081211878445401680049841863719537750791225098168839594398437434905\n  0092769074304972197321668269078681894298865543260393479960279152866631674245204993576832197598296140\n  9060960027750075411611823413659519543647682659743538725034335575607603094264593717684435256584561894\n  1330436265854933396448813667814189940353781251863618098614310938046860842389417657170919837530273529\n  4605318217748498067641007278068935394877856208076607646288643497578138491675496948013336164585535923\n  4218744439048728220232748279000438097437222409055665798279254079201827191764073156868788990869823443\n  3324298461713480779415792607894378693787932181927623832088562198256262053706157053365099866604373352\n  7800430297853858257772582081434930689509974690284212321480543625214410992658451320869835695037934121\n  9278770154837668462588485148035328210057622595312384395499845597718366177469694877133736029490243201\n  4008936954352464284670390628296129253331756090545801524153362697046334156094771470387833114080455327\n  2026698516916550545808852623472270091856838115291325160755751473298310481745116901185447389050027079\n  6628135737332891521947351317150714211819622395064036066250793766101141090975719875195062790767199208\n  4156183831262327870536779495872093480853103370037079676981443339865319473005539550361373716903540441\n  2274418482508972554341132914140992101050279406078134345274545748910397870395925576771973032662920585\n  0021841243056110147117266588588758581109801362242719178360150563008450612609580351146221868970392656\n  0067677522712781150869182409312639832388951433073092080618183670533272221996712213824392494133845030\n  8553742913951006061214064015277299204721624746906019968753616129309594435319670213870262242747134252\n  9519834641150215258521719073343528760508969489859661873724647148445754004263211169130661080007590199\n  2768527723122943384537537344556192707318420770035251888198510000910588697024636141339463736403629167\n  6485024313959222610891431245843108024918533766365473795428101980063946754916567388220937206795502245\n  3974952793604321876041673712529418689041678756050715819184628397499517761898470120141728492253165997\n  6424913961553463045596737003669827139244746172240537756388452506057383117220633099522461382751543842\n  6248418305454616142397679580757579289295535823158379105998810001363558358025381930496087484840623244\n  2130196731285727975696380891589114151062682936713253390443220443935122562713425835719375807555547099\n  5280586509274891485606150149058672218630181453955271543377441157484301460454210472371065909374589455\n  6018507470655512504962079763495262962858574191061198684337435959902767513512428421627873827040736179\n  0182264211619056545235598213465009844346847498934255194190612568539471215509383577839973398535979920\n  8044091401401301969205884816241657792074385061659298842954287592676532576461278658136538693023064324\n  9514872291568341948933977325772383110186072859921382743995531670717977869463102412096562992515636907\n  0709797657462230224811183699337954003728904003552813838791669645146305017446678302677339156584851313\n  3733221345559120169428199446355869119901046702572488630391431318926902723427880765595671435508100852\n  3328736761888331433062584028544613817909164915113898688610204244109694930399461881564346922592382271\n  5423732556186576373191113839350829844737578763090888190669748750346261607736201056147649195858889526\n  1757302986600028449208833098693563896669357365831543219805114630291803035328239125122651457960451129\n  1362048141607426348368904872534774146049792896866547180431109637020693661800381564926460176322823546\n  7525772510063481083324604963974581894856250715927985140068823456587664328616964994470287617278607401\n  6278793760031340305365372001633610673119735402165742745526613772464146797016342322109483927352053992\n  1618466844316578051485787487389956117356157422927107997893783041174634233172312368706298879939563796\n  9323438140930773031667385587583365894879219229299170292532195313106313751699564895556279207732633443\n  9956069913401234556618660027238644091295776817456745562042696966397914924854631761555583478849112031\n  3298081093820200166708214261953839391351949433245587415772583694811634921404847335467048525276266990\n  9591444857090831604238663433552347995241933217431270826427571501537381144704648961477923432391883659\n  7604173276069183964760678663226749291933231611318776739191327131564491305693705855153395058229226297\n  9366928009889012737440110729913075848391948372516387525152681209356155068966128156527850437743856737\n  0659686571290407450402139678640980501628716324266422673376138215295623652204021188430916924496201670\n  3983772402290077519119901733887256549451670248842314466733016979564931389538586123981116683082572022\n  3337246985737787251767301674688527011564277582005939357098122586901258892772753477512459695452503898\n  2611668021287757380563685631564442199458187402810656801753185564565295582288616955286274200281964030\n  6143910590032153797953969302185194232688079468527914072587719484690411764169152274721106824390965834\n  9368174072439125672601413920553750443877850971869061283089542144509045453485238152261213609136327962\n  5618713641431649422139355442206005338273451530798672306688013562930131650176555377047163009150624792\n  1237391937057541387260377844094217302591125049238615493819007039732269827084459330938371631480611283\n  4117948631308461995943078968496411168708433793344057007952647802553242998827021223958907157262154491\n  8831198911796492255687257951873764372652104196188623597080763708251916019748223448209944333236500401\n  5103308033450987342082127921412004204801805010797985617232164735044013698114855410588119726087395394\n  2549086287378390374680988320817221479683074313026938154363684537845761557520199479117741233670859357\n  1769209592840288800006291720871627379774153512958050297099442419138076287230850635785570220029013432\n  7092777298737515761662474840473928515508631642153028208352650155756311959083682307340304392715181050\n  0275265003370868949842881323568496500724939884740105694734338056373384023824360725388733091113738840\n  7645000377344784709100186480455411711002561405408783699288695274139261937908513852292978958106283980\n  5904499241387273763985719482912844834765974014041432598188502453910670591768324622694839736115718148\n  9852877065023792132178926953611637930446467710253991656844314443202029811685936616659255206559795684\n  8269167629977734031737378030874820811784876725458683733424633452419941410780153692124159877833997466\n  9973954295186818200906496976103678215280989529876069957103569096028371008599789898946334872095708021\n  7923366574870714677736736097246399221575321940236988042560150000758404117573195749841674033303526039\n  4809737885653902886659099013584031964803732938986045942039868966162227548943655076000234581410708961\n  5093946926452773942351146940111277191491369254378585394835272648575521602087204812491691018527179951\n  8375607328442667718476795407111621801535398791824774981618583564645228030863239977138499283592092705\n  5530786651556452768959162186920347015645557340287669263841325770360160596459690403225512310202955997\n  0989164180907129145748986244302977071138941462836484848715767856779487814312512432935502476872684689\n  4693387893096861937217245242168739271859503264117183198135708927075601079299185145627502866219243697\n  9841781141404540319609164247843921439027833868372641711554943963041940588806752381877429108551788002\n  0788117679147787731136388027728566969401182727554750200093592740494837691964174174743764309935882811\n  4902415856717211865451819540327446308508490018672136527178874236275133685438258435726097657633985935\n  3648790620203688881027015850058083028005290525005920409954009559933828156055157808056927750376405932\n  4228538216945892473083726933480345155440890818030000971359031387603695064629525581193233191042017397\n  6968511078545102058841174742956674264086276226066772160763338326092443117163266104428145958606250699\n  8686074775429041244464632860784627920804163161718877365407205146931212143251692342945354332472824172\n  9604332479029063540574426435510165761886887575528924905830732266885794063610726347131451280390967940\n  9368497933681487571329869781321192473059949601402778186483195060983999490292484822645196907669493668\n  0918529246540254800772199089177291960931566054867802714844783766043906003147146452296723373821018725\n  0391731552458699554238861364979298934057309118689822968756922198783526788848165620121799323557181193\n  3947899729411316250382377160747601225078909139136007369816164496155077115624751848671864274187522209\n  8369926251107945876744271026054910183771414939538460173089933449360476973301928779138027031350707321\n  0981882099042177479582446759902008357116817844883047873914753449351938140117520881370598439846549557\n  0550101894746331785135447806050024532228986959561098127445372003405068433161951983630318170374789862\n  6632707244065379439277750611738437739100370156045085424417182946223230987415992613792310306397975196\n  2906214954936751493482955342557326734057366254563878208772478017012519108061380763294191048376862061\n  5503990171057754937943719814986022745743276873586654721193724736483688847386369550472304586168757789\n  9262417991924288808684663276562154894537758464269366017054904106967913965856504723142697926688920856\n  9296287842331651540087970794840446062660205914207157264149118427257725445185179225229922899892552417\n  9313295561629333876104160849199666317442308779405887350839478730728309916977398349794368477463448015\n  7906910420838749535492617591718541229359751899008922262172191445930678861976035622188127806388132245\n  6355560680694152552978974969052102555871166688039462531658155902647017179900039902483340191847418611\n  1779142508795783220037431338999438878790174932178328570913622593452398799211941358296486042387182406\n  7417098622812190185733368156857032359430919908413100327424163085607040183967645421975659821525834228\n  8679649061753328803833759251880213557889351191633363591256530761963446885955556790319313426753383306\n  6316434060769725033746120456578575427494456057731809473490446364211529985330435369838466098461376693\n  4308461700054908361012391654874021552018074383204637467839049999351856781079228972587469036774957913\n  3853503513360755073213256002919103155131072831771162507725515312573049623272208602252146484022028427\n  9859329283668879907714081923988378503562205294533615680282037531395403317643158940563253112358682394\n  7289210428147770904529570491287593524120513586876032845142582734694488545643193344560610392771958212\n  9219413108746666766592457491385391579446355239886906767996953556594034008392663094891563705155183329\n  3940005032264170884889946017449665907668684722866810183423473358074816786082569926361457941434157737\n  9697276195362514816047504644571393528525921757839527856441202769631859515199253706473854375073484198\n  0458523109952456640263945256711483053596867831113800408161923406923403260989704104568037934836010544\n  9292069273132391092894894161225287725417258807157698002902327692992653967222231259542378978187961729\n  7369231269862904132940693047792690340796085936969553082870633498853589806317037906551023455503598110\n  4722630784324378875026808665286661970123584310754871934469961351102465382307632638598946857435306560\n  5827530017359129830695156395419433781212111804407015361531438457987316667203618404665922914000728615\n  7047092318388883712590113775110154672815683126173135845444955569340401606251591221445202630400731678\n  6242123473984156636061570022957579512596067890949180714872199201151338603342012490334326901903152471\n  1111770537674903792507047710800078072437972199974867805127054386580977383660845571415922313112507699\n  4385057495720844706161764642897016734248531307265311314113296922449973258986937933620538231043046881\n  1672702967817935315147925262277150873178413472011750829199181400243851651872933219223671393302183937\n  1801828431923462068612248771248161446437262384667227387169270434322667628213359572086575925299335704\n  6930167137706293723161840281281466540339392997647994508355635293134044814997460821573143678277060209\n  0362000236561479481796166953389820330364315197605893882403131045864624539039457563768870592794191446\n  3513165656385303413805511607383011523496501602628983311752665408951427645487394364290003104649756341\n  8646706338393702640432719993444501765362119418398091405435431204661107102294914795728223004888150989\n  2880052029822219560313715553191807236758087351573949415863863465924264929827124687428737887107211779\n  6093428528221850751761203163287865050956785978469694397066857436394417334190563835044072943862175261\n  0060673994465714452565082185110811234734977092353306073156034383366681280289728355294978346861207930\n  6536662298488684458973023686950573180717092710488020936988600525942346855824214663237148360334708879\n  0508346751416318599787318213771136093379679226713048084006357127404476190169902128050362495514649375\n  6285725553472201552916273600484207174507880795076184591360695778824861874794960279482146832553636964\n  8055794751958042265961817575455372575780063850078828942880154045147286645076936364292616561464092376\n  0991944230253071776066476460974890130071283206700958344414867959642884426565334806269850089001435859\n  7934320495470073979019762402183186450225187355768195384669571307006288829263756160327876421596559312\n  5292492422161329574504065382201672623986186616485814342988831519203159057960073366305926447801768242\n  8057937751925499116138740816555196180080619144877294851166256997724515082137146328190365180877334737\n  5322139017956945546985589460995099448197662316058273897392430853104944407870847269906403178359352904\n  6138482240608140130673921194035926589229119690168304343622797153048445980731590371353990852305554135\n  8503033059942630753008447497312132922813900414937292573158103903671573439298137236609677070372399756\n  4711313836503606104054887160986190396184993610539032305603590895271652168824412076000293777205420054\n  9345059959328476579144513894804179203585085252993874450064907705032042624603929134791860529641815140\n  7354308345877036201626136356475367166760597478008590314293613337929331917500848550960438971811040988\n  7752004921222370695585812496257133144760665069336788276888731032445424398289077351072677332667843932\n  3322019262193656446632205485521963628598869821245905948414538983552431719342491299006181463959235638\n  2859406169029756476311262291466746536626582357583297221661709968921215263224954097253009276090968909\n  2981539854778104754603970480564097019438611243783216133017217352016953866778938051847299996113301753\n  0953639202007972943843344271324196298010719595118940802076078542247534707659726795708604373801337156\n  1484930232571019813287494389614948548783732970942781633625443633308269399055796881049489203758750785\n  4537640505365757571955571940241392108268760908876905226368654030187082270188354758472399922894034079\n  0795136796379635072634422455419128095770590315877255589220778969111186865369280723830240389236271049\n  8072888312875535071751133424809692876972015866751891421714342557639048959469858075006092798100439092\n  4945240817662509527417274156016145431594518522171855749552684752772716738913902901472023505989549615\n  7417316989042855399440283027838377623650108590936919201540276948681440882683921593425318596862968867\n  7073556817836034197051841911679193966183372970001938229801502724830835080109717730911105870894894672\n  3054289271511824641544091066453295323935450519305278990931728114996492725306034702159871961345650020\n  6310713361365178616544164970357368209762583749438630392248773435717559667110116693127919204620889828\n  7538871071536313688155466795901553145462365337277109419292748404169131454197001775401916619419279523\n  2601888253730337752336012196171161255538897835617670837738785260756313420586568197019298042050503450\n  9501358373027020583244706964639692236906385933110811220139677100067477245536145173982465787334364145\n  5185212468580407288018781059764871776307978933254645800932156135484194842177917559330935785967194699\n  1950561912931679934411945972942434600010285797589940496943656661909757932956680542467013837449990948\n  8656972175297862499944403863256488733167600407677690717691102171332461667136933577677517966874823798\n  1197416413893296651098321913188912306128832130617534730645943263123690219424876504426568006403723735\n  6520012431948237319111641586119940162345610705558803666260316221668784713489649977257144363570318750\n  0753298600633308289970512791458197779206078069420505494926820444046342562971575340949274355797251601\n  5720797972660701996918700986122241889692247833122306988351930268001333515823480974691137836974486763\n  2078154664881263924082841865160249149549798644272098660518203571764568949935602043071048929581586506\n  3951917305638559382217514301314348075986693326504874799038056468350956561639841602315510479659885931\n  6847452297845327115630225679638245805708738335984861594269992353031747205620220372615270897606684602\n  6088744711951867528525005617829728887196752466048954131079105130025731039262690888474237156518309916\n  3546737457239943835000925165391918101842370641827844631996490552888569939325282656262824286907604695\n  9122933888826367890525889629799260043658351292859166016816271158503859509920045023828805257871607999\n  1485779511741071458789278928594455422975748926639149060612255901846742420489830696032609924160537319\n  8039930958031845874187561196551694103025884274613267715286041675625997166890091974462057078876061938\n  2471443068200786999515821869152348094620599473367284161874380183762446843114622719971835404199085721\n  2670067522055708177908020764223877008302314596324376972484302281374748014994596782976524511116475628\n  4494882391126580223207233939672487353483796834709037217278071821993045796170874846683226075483119464\n  6363162955046142891818703440255160661099604396822797600851051090393629109199421193882665513643110459\n  3773982337547022348970989382383349606222414458818157174486985800768017680983135448890807309801045982\n  9884067101286138185559779131126585794627976344020932540464256523214487854998370452126786486295967723\n  5993867028758906282699279492148880889025975297177478906720299367123678763451986595708011874771798648\n  4510898251955339140452640402757528622015609839097436788392343368690293794902388062976992556920231250\n  4277051089435097832023702609078772210288838691730652029707426870592354303768898474913311508457272408\n  9272768529320256830382290269854983092664279816962154826437896461283683804207320924463481062482376286\n  7848195810854733788917216503370931716230082783544609535500015708732585371829606975508170435834992204\n  3478239737270858232696362370176097674845003041090604011687748131236415722492541367350659699997435146\n  8311300047904376338946838115075044798362249775689187063312159825736569343060981010581075128320284644\n  4444669225835877645410765424544616023777827884230143241483760775272286664586317686875728436203463872\n  6464703378104558038408699001847001329490672016291067320866560152720035703770087723639337084619152832\n  0488231140350582535412867184976918987401837011197112474081661540189701457760230237450381123110997102\n  6466141404185726108956369605831244662510334421769869553123069183533005618851848711467565374712842537\n  8375360270025404781526769638680028149067082684714366270449383420886829795605591530914319592305379389\n  7090912350168317523156938922081723667794771797136271924145558888086019038040749460151095181573219926\n  3163081536727786395339826503769350931962174930710360546827463851923840108589380482153796057037554136\n  3419453179102144027724400228595051052507885300563625487962039630514167505389028154839893826056184605\n  9692543092305011844820244405735333994864623246986164271525520414183945458833906450700211202816269037\n  6437236786327092384808357049285566542256570041716643467942705669316946590355900250098110204615997069\n  2226960430393134150112385202084330783492768521280232291152519737913751743284056717195786548200968348\n  3949354987063341045109115580239978965553728671671998063562188229089859713594565995658390071990841135\n  2900703212798486817378763769197501596503476210492679280029798828161442624704549931873587379611446122\n  0750417737680384233088995124892738217191170599517713453429945729725215214038343046073402932129297183\n  5990233671675519020483679889348578542813074091711212749135188966503880595036488660019305177479737720\n  0603859479443146650104107719235172244725816987613573155394736063610226081719549477487334657530769762\n  3829299706659381130355666982838308327669547610966886531811220411325508888982062797980648030112172279\n  2334181960798412999720720088418393872211390347247310851532774836698378248679654485396054673324517828\n  2183737129068488432260975031906355301794126482389535114738786399505486022460003357691360318382569522\n  3930439416276778650226367159054260821794162606278653413781787284203815659300744636406739896675492687\n  6493957184903132121136562023902615229840628730956481281693035018696850371310954723293767472224785729\n  6417081985894052169659810525337889233503198725849488937286407683296645338400341397336846566429981296\n  2074532556516610754825373816739692277169563653668258137853929592804863934624068004561289736777656499\n  2644452755616222399431748911099786814130034087861609640689091934466010685781739964966919294071519797\n  7061967355632780830374867624281895329937993501743770330412678463941074239000407519860591815646594775\n  8609699994125596896228698815789024265778977792045289457268597880151203918786449716049993622264612495\n  8687721434771817782721540331579087438333180945029353819157281454183268211248197232597214322349402628\n  9546957476210108078742584765714780160883340496255465063241474442371159678992370589827766568589771945\n  7925992692904083389327233247930254203274120827944369363547913979579720396366395782104958416314403965\n  4240938604752833259243435007813065949179499077038816705671448564759014708193628846063438708308730139\n  9925372529836689104103313594394347713254525111255211109279872778595138270891636659095207417092752512\n  9902620455410308034810322700046208199313497741033969935705200813490694208037872203790464382890249902\n  4012213804633979802421821068393468508849301679182896621304254933387996548743861093208514910533275877\n  3226902672412929662567364590687559148963120501742439452638939790244232370326490359685257821378096515\n  0454498931866068559097566323944226182229519656421572541809032099804496613813953120985347967114699342\n  6949382451496674751598529004751805276612260071977572249670815150580391434618240125218092935634426976\n  9077593665452090820250602780467149336326778720581681597025048184007645428436549500337194233565531706\n  1100284423030042053052952933086763760286456546110382753741547484910093128725956442056976109993020881\n  0403531866948926239609953565722335747574315878618459048319664295632227261052716481983985463379437083\n  6572964093948882039748696069433331514579163972074807234334427069762865685088947309498159719068311061\n  2001028675230952011106399785970418819427843873191795483746036719035569303839940154837381862624892618\n  1581754672309466283620556512169174703278872845703153454448585223696069798688922493453282096934356761\n  6792601084723826258975990526379232591641503276362559460774627417043325449345744488947721687627182772\n  7072947967992940703725682106129508999370246217199889894467876686273457941352264033498177530833993906\n  7029665213380346983727289053247600661939254582065928970141526129507274262922793246579170438371626932\n  0753650111960155752594694061918181848737771342683444424052930660057334458886905888039317748451177410\n  2397358775282284385958672028239874374352959211556243224389289630027291056872887268161611773035695272\n  3169774369592914248446211898945750116903129574251482845174419871337174865767463539747457615954160878\n  1521949380382190631719785463648068772488618103918944897507305385580490920796321483089352318480379090\n  6668134527178233532246612521949926765291427590890922621175108174670500059568093135195284008043900757\n  2617866577512574528843305355317484142917533742487750948993354373583595545788270603739739129226937030\n  1243965689712377394516731859670419317393074231020539449279372556695143497880554570330590834011304552\n  4208837745301823471483685405703839803008349014666157562782972454384494736538947399853428754328227478\n  5381373116324699293836702958321529676293169015770163764597073115455682766349019482504203271623554376\n  1606289610103177892081300713313496833865486540725269994243818874654827286727227810546989992436385383\n  8917100915927170823049066727659616237816864044108587574547936667543859698670955474999659120236471863\n  0251342342866031230832887254261484650491333914084557134897421213326279563751415885938343702328836763\n  6142721091091632643811993071180581370532052181871689034040842283314956139714100091017150993735501625\n  0498698021280775524186200458708968444383063445989495551440098765192200443482688701270198303940692242\n  8539144344376925256906037856331636359169597563628551168556316245250277545376196294289043661945896802\n  3918515806791438606554576306665385508979167196722773975207635829190576647967180388564538818866035064\n  5431683355124532052382832782772109259629794743650827334190694841174771358669416235515154189766502736\n  5243778292737501090510930825867898462418684947221879450928673056564729372657210556932497375301720300\n  3429846293990357604055326948019752126003066980384350399536224586496757173536448662296086766502211476\n  1971906683670007878619525727724960774953015827040191563034896276315535912935217020929815099957118977\n  7124690854467614485083505413333978482613439531495371915024132149252570114576270103268359197885516410\n  3614737647596250976223028811188954047134804246179115385416323284005437108464269095036218683372877564\n  4555584451321260709365088896899626104066097271490158259265168477635062365733527671953832978920009067\n  2985653235452227481654101948007407498391882302793263914494236957352889952770410995339475528270108194\n  3357336971843195081657518177313617892037222004623202250257101959975795240224447773214620837600834855\n  3877306273902091886835251019639767078418503278393034561640141876545693800041666721878598301833249780\n  4306684137087899778060970875131224537331792104776532196322692920624441186024038239395826938487694386\n  4799215827507678016075065363560192478163288489506739317047508196646271951189687925950485598142253735\n  3491882022522322545270640311004505864934019626832439967502709419772579999621126315498180662935407155\n  8361027497190651842740656593725451257474213565274061255142087368319535891534018300564376147556000590\n  1887559432489987342354418536298897724641429112985184953106090530703685290951747470466217592782127028\n  4427202763242218865003628293273448127781908247371971787331228262452933903310566123136943767215970190\n  5627862510231496508385051784954746257928633548467647505619389560487127247631535427130602573246197073\n  0588914499576286610805194016087738399359475968793420630616497610162893847437876270839809365286890936\n  2413539742230974044012337734528350622583007681949535057372712472914630242934201182055942858754096729\n  9824774332995253289388910288262385002918686066223060076954145344014154378027435465277981124805950108\n  8156886539095810551792517892616859476198901851288548533001971913658050934308651373391567144253106933\n  4558535936906805731112135220901489843226163964326307761140249595727575518017958941940131977457342289\n  2233099739196245423781531637399205324766455348061014367306832579576051667436473662023462120548832579\n  6206777946589615346666284962251255998837366356154573809942398223413977857318118526694509219333400278\n  3956605221904343907952187695286295362583451142883374188013897668334834519923543727595099724884754998\n  5348212875416021214200071674252732281865847130243740380124721275771551735438068693217817098469304772\n  1386934362393518517720943809190247679191235016341974983001943492514392273283998952752845430980061397\n  5570079141708167825793398258034505303504355997163018455281682926422796379517399826256972139310348886\n  9523650338876723534591792138831157879766244044458568626611876186607785442345782556217513915151217506\n  9970282671214823537616753390299724794386940098439803372392608257591497122524969990916251682241883027\n  7064831538112236871275612260858402325217728238991975461696687100468066683951394054683014706632437280\n  9717308526175004054058463579964387130602504665324509851371135047840666967408120622808495247082736778\n  4896750668680665695204615935906403278260228102365520837977749099988133930572493066866543878693836289\n  4312535175161385304765696084834268921637953176445418916273051752216789720804110223722838862096566304\n  3269375053812605807435715564425203015360659827372446319420027263684000729039135232160978068208980025\n  0397115413563807418433383843775594568899343275732876358995393433301321522590012083860051252010931866\n  8826735672604998799535122658646076878454488418338341366254221969714632518921172825009741219838894379\n  9647742461118287564927400801095806810716319090555440663768419924830303824453861204763918078777478409\n  5532936773126665062304634915420945503013186992838587040497769498762308681601198225060378407782933137\n  1486931955769041248096002894285901471563003599521187511349609284646438827763668164442908723542365626\n  2418491311097071158811075995684882418627659429311553264355336578107862493660680973525672832824388047\n  1495336516304463220419935623776365923546949824861222404369330506445470866983819456132717316706287211\n  2922330882782287685661129367040431097366815821566525309531927357606575536633813081141261504182742591\n  9791584686097566171115535926504724528901397973074836568456676376607503000803886827448092560195250182\n  2877867751168351851390092399073510597032706696191540732872891168466075052090920060714564638393565915\n  6554266871106258607999663404577588827698230347449917712787416589237797961170443306654990881949703719\n  9281218530920424550101018728097074432904339482702886320072929682300716061300967267295626979183862541\n  9239274660390007121099734961053233558472567594158335365038969578883612227716102099081807849942356230\n  9210965202007496819097023368204647962109385232105587621508865676768483543211634698215738765508378320\n  3733814319900742026349784281011684895754010218975450709832665427621469333908039904675311152024150248\n  3200566561580635979236181932300762882729466887837907885397404896953393147003113132449309322770532613\n  0028850543429077890063403191002285599374199590545341982948388657641910838216642991461141910541040721\n  7183757715506151351539277140087755200122840978187258166270893127396454647725980889490463874441203383\n  4039847054748264843421660150604097870387197604533296815945603974179277038661169175403060560427594749\n  2737317580608753112966079880717230218830918163103554699678999676814113223840584872150451109777541309\n  2733480856139943138919564591791374612961227432649028945058286960183976632667681848636729784429610824\n  5753273532378558101279916957607536616328445715479677570022259203947901245647188595273323538013204986\n  7071615509158782889567274613439615495902481052675789916395615629228002473414729092945654241442384279\n  7513489457306058339555466206627021001410276707945843521164890881686243697965682341977082233313015802\n  8218768411671028519113734962555044156500322013218780720836321567275832894119429300942017627734310749\n  3222163016969037110211968178145961129850803567824717557225952337646404023992449941171332270648140922\n  0890393406774165907933582247961761271957579062321607533348044259252472166376532812491737879135545453\n  1828388653870756476397340816244449879336143123185696534013864422093057439128727633815813871255067371\n  2242883009985818632101563534940227831056311703310767124990400513200129348970272130995215492391507859\n  0421402689313004609865615236140525303927254313140978670372367159813508704144415568474093424285806826\n  6918870587013314646320508191505624847600443520708075408782114949462115092792335641676736833501642284\n  2786529339283279284533215152892040943012000817086185841075044157621681026060833568283697384319713651\n  0829362124680025797679911553999076484038049928171803756534595183845950993400933926031105087975376413\n  3549052939570876599134289972977018161429476080132837284371590590628796866400470614917846595143380897\n  9790174722888221305314151452675047969517343623347261533030009304974265653945794747407885636678194708\n  7581203460486212211973268398503198398806751235560721231422483976820693357970254541142678568828685762\n  1814616682467550295237752661408949262179410234215163541177570269072944307695709089606441496588167174\n  2121668318114963709144779139340867791720363604718337590738200996909450123084402978243198983074299124\n  7475096595054024321134629833441563938684666384511304171688046800828350179909695445574285813277440301\n  4003363683787123611627532239185200931510869547854040603851429675337051449228581682317546757859933248\n  9704331947481163136568762244209211961639847807493990632550658610472649946278570911848293076400523023\n  9571694045302297748433753449693479104278804649755091689284811027335593809440469348957848319661916191\n  5687678664744209176769614601596143007118763711598184357094876341973991380856286178181951683356605131\n  9780945322585426552516534052564189836041918098775647547009333545646386374588183707193089927774747776\n  5194007121001602129242904288437751885569693798413746195948786640495288517970299440341709225712698364\n  3477923420004450897240195642776843574000469180688578829638255568576955243348105923536963237766541213\n  6136594165896489360126908303912189079669346387826994625689894323842694790019544917649079925967283332\n  0150204055056395822883229865421520127390385712551158338946014788267961307059368446271407317663585074\n  8773515360878547105994508157375037687217575866897476371420450858593475520371592894144903845551888247\n  7822488860567681794844885054248271176560204127562510816987302947899169290417780732082029453912387288\n  5057804711502794340678197206798706677346899175968570170964221498843862131723330140364840906229633661\n  3973120512678548019751401068761497867822382951553014477543880094209195811190845593172841912844754245\n  9302404344156046849603652232207039181979547390237479288943062875587989550434633272922942658198189938\n  4964339039017485919007454985194324377468897151635061784044765817263836980897975093316068670902736290\n  6796736528277031546320116423755537799298474640332327398535516109777781075212622968949860513517165602\n  4102871037724129408278075558919925350758497154770214909146833655432231086547487771386228875760810079\n  2717858979025987591886351963060456666333631921740794453033459277301240490432328916988631072549085903\n  9501306666592730117026037662981068329188801540077400682229302138595764542356841724364975303391034247\n  5954667977697080027375943580064715248683506681994620785001781035428128258352865340395212327966035363\n  2408223180898254477105204750370425226479722869915914522430007083320007429597732272579503765299376768\n  7202659189314667887983961876650840897212071621470805053296553068382337586478099701736217752518266225\n  9448897555479107900294328073777695412037888193857533624535557555386215137215790485645195524782723839\n  0439225555860854598378324204224899605866221584236888878281887503287720578409778708991012397962235928\n  1304154281462067094690729430442763735707951946382406385353975389325145532040398658131876665067180128\n  5529209290281388464944991314896215110965735382736711051946125607048321120628812596874969053325465166\n  0985515328470502072184489791513038599618270755253508309417881533073713333483247287774790518106099400\n  6506218469579141609025863337653702695033632515901240061077265518504085743720504028696419034506015434\n  1482587482135948966805169716220412921890901365194266163349101517770935418782341159443425730184584604\n  7967497734112396736746076937584906354299939745453007174309149674014521858837580790841009395282512399\n  3941887800098000852983250117971552469662980523935942605334256683484171065964689960240675931818730076\n  0771656964600274918478453928375977395610105436229722833079671242759581913381790783409621408277302609\n  4598302411681339242540210247908295842719227209123104987777436008228204047939823835763173244317194831\n  5697133001082852534017809175846522941747359197349372218733486503775663769454517348058412741929648062\n  3788474696003236329645607187500856199400629019636181432769610791010248477449948177473036975189922813\n  5576935750144684547038179643560419274820296641148426475538846160928431736673260951171414551466420877\n  5937211606640057131871831940378249303566026421145554655096381561717598832630660635415029101213817574\n  0705460347589437776573433474433136145706954995855206815968719207955264670235032289325886926552115837\n  4045717679269786983093658441605217539839796914164692130528871247348215268404863354416036667164545205\n  7287892065390396896570098833039278228312463988322593681848897300762029501913922174696391900812982244\n  7578103017840712413711813334742069153806373196342037227001353128231561282092730787333606573188224330\n  3526775361685144012848142160469279280062614904237264752955289806723868980112463526170892236094195142\n  9831850549387764220559839784235496068384308044463091873898281103232617494249024592968705429095989327\n  7188672788181490220518594249649786437220191508458725241513773308659016343738990369096183941846604804\n  7641285774857339602432888485615948165391309950784326152761242743730419813219131097138233235365219625\n  6565684132100997793465867125309809163123694545655240867099025795737378690735707957623330415204577601\n  5138834558474196237479266731639431708110461614928063588389189301292776504366428922229524865961964742\n  5015639365130455542218413698115505602264569224268844270921908249138797460468842621535222232159695297\n  2046003562844801805143092351464906483155814707337390990940330635162847636452430703990228906910322690\n  6335776036486055194090278268031593780882659283867885892833398144312107432421057444077972553048758075\n  4382718089738160582946051048302938386321120440632379853101812009680047840131210419317231158801989412\n  8999509449051823520285501747845472762059863697070096215053673678007104018661808141385962780769153033\n  0859735979222742977968064432368930843822216161344502909244442413428682045989239144100586494855598206\n  0284922716247787026995589742281427014367258362020191046924111432481136567823885316616782305910130295\n  7723739494218220628532292532966281056278942937466150517532071023254039560695420249982143153977132554\n  3297586855252724801325259204962363918642824022950565291717349820738772748645347449926663833468080472\n  8431021137809271950366939837088898079287353281533984742606450074080844329450210486602352792585313312\n  9653132245368773308954167066148363110682779419010528654438552547588213894308783875546974389267645496\n  6213807228842572393450520834542156644577393590327231975817176591609149922300536477728381273341666225\n  3384147224262994241192462240097854472979829127844039263998169698249831998810282024020189496060671263\n  6566100746939708920646894033570492380927010705105350938561179427302169798825354162801527272038979683\n  5160423690238188359887210402920190710560875100167903711110517939171375466236838325414471785938653029\n  7056462626094815960597311128207255718281113324607610421774775964548391117971361887347487868253984586\n  6897492106177035032173667065708216985559866053152727023642929621060332762951293492175214297488361749\n  8973053872979523177137651695656076009410257209652641367228047189019484536577305232471845768564345313\n  3418091260257540139039411638861092776307356147710429820371485588099882807701182076886043581805556974\n  2895134939208502703609985291365667242000409340681562664800047750369267010067187565498302678403949779\n  0284984080411286490427373187873235749233515777926654640587552701973317415255343693433358781774394766\n  7698653410903424182885600468244271735589195629962507979082737456067765384902422624243413944410514766\n  8328626098116986962995732918948031309383657877203054406356888087392173364316856301974958824077856564\n  6911005844850632217485602786987082544923435009462428781142479255709287588160371333704989444793554135\n  7861767774259300350199487881893546457069989802388428594340235293957359036387799554858018444355982316\n  9084248835355006567840024862288539779059190210100832664391404237858347141539211252119664412719679850\n  0140377737816113954694556263934396372291698397034431618022638018535077274790383583877603813757838647\n  0121363152065502850438209268547160480494467248770511152956399198461966070480199092254387591936048994\n  1776424323787824512750976245752855490091949663430056325042158247850394386565734703026506980027224965\n  3816227554125812383002246685055927019280952766320805532391360748859854952576989950792761407664345764\n  6429097181815270408434116864875195291524250698686972091219727276416639989480352938155720610365285429\n  9804227933990984630926287867918884474582281838491541379025757617305573721909891733580870609521181391\n  3922837017330476881808509917109050444013024907362722374529981247942216588118589638088129678928602717\n  3502479061364226666970965563306010179050522655425750442591979884309629281030657817347163705682133316\n  9546753852570412755704075586258683249666663999607717507142454243476380734993509255726525019287640864\n  9276184971730458976251487164885915989512553752282229553578092755157717734942544940646365328643887343\n  3421753070279721078884393578408051947775698254173932129280352819043283042266081152776150337280932222\n  1614627280225517275940258914049567804027668536835600648375121195655603792908901749705688289249537680\n  0055117044514709040276477095266126178911643527084947663336330375047626681813493831684698386036717861\n  8075709038409994416681888508857156733750859452381605828850594971914115773519469163826632910009363196\n  9376262656339971438859083062405002210685624839375451664538977952645501454384899174219683121931401372\n  9951184100975097941992374688409542501321236476707532895687164905935102896844431703315138814848447542\n  9115655149549323986047347014309945309592965732996406961790565718915571395922522237799661633492924092\n  6900212172351354308093758013216123137754512348729033561460914816427581049952002360871359854964801275\n  9693337261148782204827141654286109728738531498106973275369685591326889312465886397377860527964731457\n  7443870375512914383631014808801025549750185056343837423264942884038079814325557800163924992969085284\n  5898363913292517937062540150226681735964657598594163322441515757367266219230425695566601862213826190\n  8801925812037238815460077600385904490388617664212001571276624408763052928397860029377083531090043918\n  6588120008743195074102899806565937988870123097310069701795579926044738696361160786515983764865016794\n  3285933431962812865551608452919059142677920493990411896788778786674303929975761676465546813424735632\n  5818313412266269003748336985031872001174603213572511554875102276922014334441704147593650389209545499\n  7699002142804930356954589200600890881228980848054976146423981241706535745430437630406316824995543589\n  7677978729067940476948112679095135574378201752416467534613297580009812957790997270711903936380944971\n  3956296258726823835894718541656384732924275869509842767377721923321752765396866061772823715965708211\n  3035581036381518279132569446119309158813353194273406654288407415997081949240291838849762574831533937\n  5254667365082843965540113896630167639046301783547536947865239365547983209434681476337898406578472456\n  1420759944989774128751744945814534657383789979602559586269280739502699277569907760849202215589743467\n  3926377917530366643870530714852519470220957089282863695049358558489320909558686670233457554319254514\n  4251812880078499151418500330138018283582919167951015135063258915735687948767419183823306159137685922\n  3498332250831999552784862550590848674550469516024205215252356676382666432062440113462461848355382319\n  1903078979048915649288167569495129760602261851595750909144277224633135683572235099411255280916228242\n  4069411322325689953200039030202196968217386130987969800721311638620390327297191995557705918946517770\n  9310867334359701908675463750777494181642136624587122836257130969042522142409274144442862946764111157\n  3339026068992839959142073445918210129878938271304750373833166795787273900628348817212343279316790078\n  0179277820576279424741963951177750945739527443895863353347367966070550527012142544299479080491346447\n  3573810923689307860356623664611507441594192307991226358053752635962493588388549945357860888234906479\n  0166624557209478823103870099917210865162700174127764789314306360703172683961166817967359974052437218\n  0120623481940467735151101150135753039355361350398387654046363031729240400443934542228866504375595216\n  7963855990474148107366357622269326643306422466225136196475599479394475167428303938849538786086663136\n  5660876086740168682542438595093098390095082474146115182797151479253878236323116039101597908370532676\n  1335653050108925597369478256693522289815420801446620485501976532321021816166219530346571841288016502\n  6448317775303785757210757216727037351922240314148705332812556025237909652855171060447447911806731970\n  7100206860334909523369289943517346016999107184507049095286957774131794120530566393158259808009454159\n  4568474016733761993444644185952484585780679184671826721457933027162864842332549702086814740691585705\n  2483014262513491301317931897383824525493171754034351063059441518585179933228918463985687661286780829\n  8214112906685003925620774769600566532434851625148542827048561423339710633961326931405248211840228020\n  8764932824600707929518671187707464164573645634222261847181242843835488266056541755904987953693629595\n  6649725411837193356979846993998266970823283120991093412559948081987322038686457497615007315013080359\n  4050406734056012325709787469629188299464967009553229932888316237622770234460841617862958418100330595\n  1772290600660895813030583131395588588048276225962517551839426498063120045127181001922219497057669748\n  8445965926929976916207972664234143396980960850145452991168678452787722580150857428597643180504071622\n  5494651215268950797614098356924309417467654518171956674720444984286032696803718410825938273355849743\n  8685580513595228455287596361386027589819453100170760894427332474687242958911647821885362098458294683\n  0304075110083054667661213169494465638662336973149053630487890788328740420726733833969258348281353332\n  4626119663972767295769874440365471360016591674771423861819916453062722898155773566229226610897177977\n  1500834627946440936058431573206378347619517000016581060210092878404435682065201945270285682643221760\n  7135816017522219734672233277802743989435971155978038127627806526046703857508556025560810516667781838\n  2636916211202759547635750927356103375651797699465779495961144911621311679160046072342568134822109174\n  7041610254084248399240423509621969126368120916434903792669349222546351017403410154654375283162070610\n  5390821226693539714144670163871339195724562013513920405091861473232182936195189123645492088239049722\n  4882879142572991339778222478186521013391414371601077808100071612966209368046726337703019405918478585\n  9655730889364507857936000878628686633807976368902807806198570100232244772514039330322119572056967186\n  4238802321863347761125994354864992447475166117836031669526375416043600635663238710592793579217568711\n  9998228111108914246461015465535659621270420999440319758735153439833319560989417309386547454651409993\n  8939769355392245864303588762315761562586158746287281878133711235134587883785580421697764398525992789\n  0499624290653889621582122218978878116258382965907363248496977987612007130681883372519003703774034872\n  2504297349609934766072848640001631992960669543707142711831921409924423946958256654205419145120455361\n  4236488414816026053774866149864110283759516290999622091232981921678339239642561390727753657077363937\n  2511982297369678692468915137165264869759651344357671228268583753144012628041840462286935889735824637\n  3787848447481641210733816758775922822307915498221080479590434831933876343307339949925194243372136321\n  1915365810872552754939034970117953105652743688889440854746664727270780909808046997309405202816129582\n  4460656291655076968023561451397859995356144918568579496089902281540993189622735210747582448567245261\n  9510048267256152701723009343943029068805301926455353042977099978289188712729775673122508012156908989\n  2104620610303265419535588308434633118423243266793502469894057473910493235573872862497868075144049873\n  8143435118385255825859650848619765348305165577465354849251847062358463611289612310634756134878291962\n  0808029021541889567169547057841263606512805097004486533945692126761074648902182601513600217640420759\n  3430425154960471216560638269072668810603281420474122008886673494151799724644431487852302819566773009\n  2434525278035472371332498112111447527196051728526390932400074100850410135349534043775070868269290958\n  9645056777697550518169976547742490749871376897080542223103073699862144213444970480833388629036192462\n  0994170065952755234994560840888352771199512564117887487755426906953789016658371705059760688177908491\n  1618570218746070392004112101273866342584584512364593848810490498891712468573926962218064811341034779\n  9910285334504336352935599469991079748386073093832224185655436504976494583857095754758924181079549377\n  6431689626073436458913015274465652114578614155770992104933437132765485502078197577561301902631627312\n  4397224267414660169404353621126647620668955718147149979122203905936045317129530955540122855108112121\n  0265729697565469723178282753589325263383311106965765815561173594867954759424190295582012445750907537\n  3370460353622615497103954431129334077832390857018090461357962884855271634026996506312919099426969596\n  6225589497975628721287757198542419673475301587463470733050737845796145354542520644230878240841408078\n  4627967368738878895852044709279081010712119877987278359242339335575561937132499795938760984147798982\n  1381826503432240130638574544885493589707048625142787242965210065664978707015683883864539959036508017\n  1114364104266278696724141998326547334111284879330934395808667890754340702026793784774345535265665129\n  2901343372346289780107820115522188723937312016093709704068632553677092619190039894188411459261537011\n  6668658956367315052216330410779848867721149416004662110658605248504107954794838142514049963682497073\n  9689414424666717487367463168517045635775424231051505809864764641739106287459904737924888107274308142\n  6295248909319854957628983241719089619983841001815466443780823753328402254416041489599319087300847247\n  2855748818376975818953479390880198458062894211236113335463254004046653571731667323865207845030801661\n  9577080902713241189165462019807089554609187238543726113874966299766658252314714818800323795003806670\n  1185989421959948218404892260458854876888023375940142157915429528712356822719394165950006243911835934\n  2678164048354162384967924208087709963757338733972713857005101721639010281400619964029555551092051482\n  3727888939586225063582005762355860460670033354514888308803206990796123184492379733390033115058829483\n  8020687671024091648595888839443246563446675746335849532241416518803282548820899182410294068318220651\n  1712210563581095080526760824300375506483382815036583507743940163080243748097984829566487277021341700\n  5589113966218009352304353954888255902667090006571188533595233013070087619042828655767907621690733940\n  8560706158893619301348780259524996703159143624421997785198300437984441454865516590828204141139376731\n  8104087719596578936089006009298571878482454316218024538611683785858623451078284918216914586433097247\n  6771131495903082734618524789221595763617619415803413031319184160775944101215743941774531300010795056\n  4422525109306737523223688543242791213530557592621003112211862038297502753817842541731173375517119681\n  6524092843676630140284331236103292345231891837022303444549741418863973986508372860686169436251316559\n  8064294041596095582815279474489407960067040156066354233056608882241092462255818735880428279346966420\n  6274112459752152202761318262096736092737034186306804296209480151901121564632335461994960497408344435\n  4531421150067268251668779506672541821696486833308233724458549241292167319098180229151717027639539076\n  5960845015945874597607378223637182049117249030372172847521476818938282858524186640140709140991778837\n  1395692161707697901006019230526629784219510099218401232206291400604821781949015619479026466313128750\n  2908324448371554662484940386152485353273663548381024000726950375367248133315649581319529832958248945\n  6994701540983863588375105274450387542374163505345484390591298010160337024065091419654406408930992874\n  5635036122491584860237513287337313061777643833491141679742795635358264326565093438974387697125404890\n  9954397610309447012230170495967791613454602409207214946497104487480382550964755792337840850157046965\n  4092609937529297506575632445478640178182086899760355012046052898752372284096564154010430487466276071\n  9959290035181390822646562780069174993818897575504124552628118769537357505250127280159222927782677371\n  9461371921651640018071110326066546576457256839904111265510326989847762004945257320763366118794668546\n  8075655577881616833650598047997528938859344621827274827697573534811670385110008812060026845121931613\n  4987292279735435145251620662644675504351300995887599865911443487330276057832738606108196032567833536\n  2521398537214632713714373366852594289784092798477878664746644957883589668082045147767271907031262880\n  7710771780875944659287949105828127513178451193902192043621739992710417481747355300551496807137461376\n  6826102458229788902686407062087169184080590668402107117975507316360971232104299798331921659946411876\n  7390473835823972710206691386867582223407683714025128786024336013754569561210121118668569527576098387\n  6242013180600973001510948770418647501460347190956001644591325816011088700342409510860065966824661861\n  3700340454030565015603210896111956432794011332320624412968527189733900293043875268264132523728118187\n  3418377266831707982236681984925517311140484292263600497298366464717470320358925111903145526378203697\n  4827376444746579634703436277452109556074920999706859663108318811970526754076084185209907452641268309\n  0143476734298550655555049583671068719038492443885017162418959241597064389551791976124801051183266210\n  8395180919193168647150076228549154633210029492313843480405709777013982744519348392219713060823701654\n  6337256801393503481012122660511497687829462858623206434741211262663352782157747324524831241354286604\n  4140191905637144561933616734099663782714960097805768754169534454405994793961814891494772883934449386\n  2378544571071502666829049614037984996997990417731453498520525154680296797462648196687022861642312147\n  7629241242965831276366150132159956875563032138349578504195023669392820440838149111506865684280960304\n  4852969738253800241726769870945805588238766750880469991238113646498178032327138862753999814306474612\n  4047754171778696333861396561788596483175635190236538942860987981324310596410750202204906039359870915\n  9547794213809864179132509391514302291823591945291150294344931341236215198182158312032029486003940276\n  6901266322070662570651654600527475224010199238734690299750611631661928185097677922609310051354456493\n  6116459656602849112845526224785726874706115946260327304926038731909842727022302279363717567119268583\n  6471857815155133520340200942557325702413567497929832606616892374772379092315644836993982219062239598\n  3512927748740492188486514861800676468364747663490435468522704418150329473466880598025997045147190867\n  2697542090927146372479398724290800146596030612664416602228604050721331815082946098885070980566227981\n  5499892792431405323990348617380802149334102633155051103722338875148162043988162961449937118414730654\n  3972563580373206053741937671572155162520262879124347517695662745040518338716088598437046467204976925\n  7186263068174611117896507127338941343126400421900228426884632219249602699285376809615893194890230425\n  8339012860852902135855253522872936927725731124839805870962208930684664626363416474317898670004740615\n  6685763785710758427494742964857966762548769795941069449268116576569257910637391280917433293427660082\n  3474451226468172447913454112832897445755146507869565899052824665349909387151111696795153643282615119\n  8278986688971093101695910417845024882873523192384486242263629734975768439282263112020004713218720170\n  1783710975756685537139382475853381189805680552456175892532901241044606138626252972014495518845924861\n  0761575320195237921069318224655177285864226604778693839844215191391884947712040124803222614617113859\n  4797565685911745747244418275564366755031861737105312840615915488212497193717302126743920082041117549\n  8546836398413567746088381673386741710047033045122372699632967533503556837425593278850528484397099534\n  1517659032938402850692199642609108990684290371284529345494907934984037039501594365634463139951298245\n  8133353138964830395468537774238675823879959507312791666339121357622930082381374995088042414367706341\n  1867945790202225251977023599544884292304632875492349672208730074226185326239441584686508261531865605\n  7785769972925335180744046382897304361213124874166495577320583031985264922840033821229619829400035721\n  8896092227607689217373213756128171401278947680860184617347613358304779955557011084658991846526471602\n  9062432682309721379199995026002007677928428128010218904655036864494068516374694740097967052287174665\n  3346534766832852993058391752919256842294613330335029926614749035530997059294430175663343834322304415\n  4343703476466404927395026581091264882415178063849558473212925984863914337804053563760280606861278168\n  8892152483564543619165845905112065370194484792425462055879015583333543255865910183915327556343253047\n  9137407024665888585517326415578510827116214091911502018761617581702513117007944140863486314831905529\n  6155411318677747603095539999860807938437497622730370371697491622920021830001353391812999182960402359\n  2948162240375734996478981565262268246922466182266003346563155444069190919446133592294764761753098401\n  4456964949854178741721231360779557004623157574070164761282734096389797697740198761601941576015291091\n  0925312276183834786795185241937060797916559070575151805129542831018535917318636529202913084205780739\n  2675741156313456410600481485906597772775589233973047601761186109466683938317051367676598060864546532\n  7538441719332482103500346143870064257499982174252182121892042469834596946017145410809671735478479028\n  9649005709369565850736027996266961684643111823719819499540175555079372487801969337650451347412370232\n  7858171705272875406768086778657331919180654146507023469304107602604380764983984187762433538838135818\n  3139633229783045192735420001244347701439141020280583513761524868346540092241485555890737202921946094\n  9678309380472522542715397156446139320717562051057479473825563034044998409055189312252581517064469135\n  9945494107897660528393799502191260261204772051458836877277420393934927466174231696612724488814202863\n  9142022781241935332974216945094679545206739569773828062800915341955720929620870217816235957315398580\n  4940599130964597843674616880332762471313321871636394671809366747344033575552621977254844202499963393\n  1748616681168580024161019357181587639139371591531076342504338406774911006239888597954611355539755839\n  6530539242511338515197295715072567194931591445438867480941270092974257722117019767807775541153146444\n  1588881354640461003436754633954381365737941755202298370463378124045276311595878742915414204162066248\n  9126162385007770392863484726233343506441746226554888964328960847169212331084463333505337147173330331\n  9017211530774818159753187403206520654666303834024724044364192958515662077201957319351948859162981533\n  0055105279952540010923346567985970645405142910657105043026284793759359388054120084681207165725958968\n  2779436299311192290462874989338151616124180754183887659727170003193889665336565273596570472983705556\n  5100268027923851679503365206653091784354680053222118117845683243680044326659025462859459910385475796\n  5209123438950325105958302845145019453098923277198489280787845546749643627564616966261836486662036715\n  5784981383986825287619563857360852041933202576410865853082078346093735426744174587917981650977606748\n  0342358794378816611199895956667944648382154771584452235751309630861325983230445664681920972502934490\n  3578658988884052055288786406593898270941098662152737161752449269126472228562674431790670660513250331\n  4572067834404637951426017333495920626461812732873779400130153571573662376126852832110391120166194811\n  5587795504039408651223604194975793571897974081155637346720742742415773774044410912384855584519673648\n  3504888683099313898234421248549562023391981900603548985180440671358033140872413265815580856335529235\n  6505562434062217386358710059109166690201106008519210620615217298898708361337945882584198929728135937\n  8463864081462097321574887645854545290564856934762540928991066919225602464254529100149820094514753886\n  9058507821574990164238325826612333030842360171331330197402643659281051697460061129741349954361141507\n  7890155231616362758211607345219385511127230089600339937108736340084744585828116929172840147159292712\n  7197382253553963987645924738369326112803742994013875808176175069360473808825916076549966028549415839\n  7942913044178937413498128512994331756758244076734176951024244331173208054198122503155476482578701650\n  8657667023097852712134326096082828084722273551612798021794324863898906029251915448088529449249132385\n  7532148964128445650583365153439839435370632236908681847489163408293026856719785796604160121522883409\n  8644950300613637984752788790195341774348444672748004363482761808233991610087405112235165967744517830\n  8192167027512514354946996687266873708278491919916820259037114776598260684642971682887151964827056579\n  3794566304849953425828271002028745751425313487886988808012391825275474862935920257975002818219751009\n  9462917837851103466716091576507689424057643488232454106255171455768523557408154552326601776743209479\n  0156452054668753256510525147976320111226602675248332139550899312683263493013685192428403094260238790\n  5323204787679384881578179912075883998951182420162549243993752925029268338089129651247232814990269823\n  0237888614435318987992150720017872694765932161051852405076863648912351751671937073774216243588562940\n  6235947704312005266062569762509684217812114888298800266160440592223293316241761229087433790222878045\n  6170135772375061952160342686280629053786496887139338571256241696407932447583136988591827299927578294\n  9295751304825043666028532371402054964473380738245775558257092700759153582136224878739519806447536509\n  2283387321973789450989488122243166650106987396166729899209644205968175696192318398661917934084742578\n  6815461594145893864060229613295003812003838976745020863385578266798810656903699908156782778516378293\n  4599361943366980652979221522153666288839940268038621838784138954997920072289371169507757061724002344\n  8728986838088894693258218633782343569120740289568718856687096061273862193498732632240960659606991760\n  2005453603816589660214387177128755309837099020713308471230391797557448381005068328095118932927219123\n  1654940906640214568359874463216265575739792837308702860612939772368385814919939258415742549146335154\n  8204141285052561164143847386215794850259095916940167019222271520515924463847867368440341019760225485\n  0585962037452021034019586721608171270192646070460795992871312107480351188250682335304496981265520956\n  7080884541941022535199131368352911597222819779651917510914125749066752719879928439903727410645886716\n  9811835091012056834981767731009548469910066421703751012964027952668079262013464908265708373127308877\n  0349853816883018041591073508780278978144452516540770812748847379655033182989360261051517090092011022\n  2071001669479948606498841609925577821033292542220238243161693794552445077116612781957202899490592371\n  7876307137916207732805190043595063027837205242860716863197568319944953596546175823793319549221835571\n  4063821726217011899062436301646834987994306732489748402990062675636866393449866870295746329559276358\n  2274173904767366468327098725400825658274079373013421250157872246935933602320278802133447547116925472\n  4427882347885720204784810966824957325946506938183932899440856293295484523469547324707209576815500031\n  3628681830587359766552445629233370980039202446539708198088097516775900082945233933825387379751663668\n  4848199061917189230530293275282052288738997779857757464433066738428466834238197778223941515224363898\n  7424951701065667853026766643708546240614507510982382650823292192311694659360552162437012743002394924\n  6000846441913713453739088171054329719962592178595836890022753546934419927056354499446464846356921147\n  3954542342093035095619125962942760332314028381564195812399216843570592611552186436729390811404988429\n  9540135030458261668561511919247042480677787488387131898718967382619247397490892216965648998157671704\n  2890174496662059680086819909195664839871279960006066009833665085013172670506678073810536253324043615\n  6109801108476755494877494236585163719465279328497990577018451049091701533568613632443894879659034367\n  5903495600216642655815244439282787227173594594830789387202484734203222900521336068460531292940974975\n  9889320134905015546639978806999170087371588917595677689472706181150301964728913257678481619091938845\n  9773052888173913796341910139122828818689576669158175066401906642575911857638875482934362992117191271\n  0549773853730155778381018844418606578305924104527243196692276439468819023029366036893929143527900678\n  3454920522889611788605187540831049180891775926096257118288327086436346727818162747255714850253575093\n  5601944533705704297279316518324369707363874856092728216957075593521798282931763040398854389505725017\n  9465534119664384061183281712258058093138653669016323415504235539488039771007125070410567877416202585\n  9908400717682098941448674622992276289202550858081621731508389755388405349427919056734487660483097079\n  1086659225293101759747853825571471946452962908784519565174095947894396337685688784133633407353907274\n  3766372205280224459160534573754066183716958052421718003218602285837532259788835018804231788756894023\n  1975197437444613352597457897400554662442432497593440495376268236401505734726953980110100256582513119\n  5753891584938212512967996772536212764607639106722691844111059166671823174812066194772280535025793861\n  8987107329311431962195583590075732545492654405344858762379970486963982129062304652602371545697463982\n  1850402406160647212247386285369145422758281589303257867192003815231307030123145001620383558559708463\n  6288728568661829588038151412597924271222800658072175375995609753028168132431908826758112139786458977\n  9915670771233413006140507207378747754227133477723187913877806041160283389280732294629861094389948042\n  6877630904138282008249327643784456946668559691350972809296560296837842483190637664897589402297476523\n  3737070759029573229676410744477902854220571083318641606283483284039376713381480941530810038363462098\n  6740923141625772592601642413107683838536096774393896453881219871847087835760284657585006626430131835\n  6377598343942325631956738892178647425115391464830610561761852266148498621173529930039419626797835115\n  4324719792100999023599501018504522633621366295417587904115529116300595092988709372051119953209519197\n  6119111178565685631458237425273363487442621789437342555944388272109955258344048078153363012318172504\n  7611209858621391195038127685768422270602288085792280227899270135450268982898128670846948085869077368\n  7310488241352092533779928151782807224730432956057066223456189965692940799043010318005588385154956003\n  7101536288339329630838861183757251344292962374362569028623990818089667478407215416482153646698525111\n  8356093769538838247792682054035562293103398234617217749928761143107112618698176716510102132817484322\n  6860492899962137442648917874708005217789914597936832576908254470499557365460738332954455037605455616\n  9384629935269555982548143695227451351596350128443816576238782190283447784194348491675433220898865725\n  1072163801257455920500626138323533310017463563269678829979522312213359229559877714784256215281966009\n  5824803979607418806864814622218467350238464996209482900237216747151301761618348664856900958044527129\n  2413610774485501645401658821009469531851670949653202836855634394275525867623093990262646880252100234\n  8398810810313959156722167521036403116827698020447084682751021600765291285961812328923919989837615465\n  4015288476402389564008009111707771686632584715188865213418100963097892468142777674442490984819462072\n  0991186061783788272560602774892025077565496092241537218489819139994930435616869362159642917710952569\n  5097069900632310061085648555448231768169491892033538259383979779552017806002615045384660223480584280\n  6680800540972724248870988991814030172108374085197168446555068686682595762131761853474144377640981168\n  9746202037121131861503180534816370992805100579393958183960538157279905317356462047256467564657337523\n  2496044286662754228334119477101158614822513290574723369645459350778630281397035026933558672025420653\n  2019113645684278522271130499308474015508320553450220711151829250378245841515954238572909205590931555\n  2709371573043650713919706627072083660506535925780753879966242782962602719086367858420342617942729278\n  3872074227039258647899698885201728543732963891417985649549871231317421078111745847834714810113022006\n  6918811713906332237746391442787135013391013614654758235473132163877978594229259092873266039806170514\n  5105189352613846356490075823486329152025865510311034138140491015735161788607576439646188341017565444\n  1487477439695871259318206839292181168088355971272265371195267463913547288909010252777742990668168005\n  3198706232475569631647941994318772899895890737174479138221069168303144302108832718736937223637159824\n  8511277737658543952206649876302769812346134536976210473975484439806649685515001824287241396293002078\n  4239040770171753087400621103886981275161331107671042265609534206562796480309195917122225686050866069\n  7491958719528511720186301457223111255958058030059590451780162091560033927158135619396152450582940942\n  3830675223104876027568331931395370615940569008254671634076885187380620283937649414169522478976448274\n  1592439389073858703368311064748295916563631940759787977389368568253656567981194055582946890756209748\n  6397051586280616049553801992987901072698852640686948961003323272842034061884542128979432188689707273\n  8273627785013727011496387088466407860794265555255548566482536726238855301957008990944181411968192782\n  2521474367302375772647906302136270092943519353752024482465044502817747353031305587840428905295653616\n  6955757460304468400201302583472857878603479642966228563383909385040595996338205201313459775949549591\n  5282491367582655773708630985343103165699186477493523558769856167640256943679496508265951649361856390\n  6776134086344949610923085281595759473244692997843787506957796523406627034893439922003933142022159640\n  4753079877248547192899031903311360675387409926265876145829524546296274478253060713708610093256561091\n  0629015937032345784651094254156584863367597171410368246906821364595022593823586898034205214584241562\n  1097712594198860517418460981052180233091349159305532364021180135399382739076096018812708570022161499\n  4202352285301197851514825409266951856567653410404445485488177660629153334239355883040977080382629431\n  8944385077023904084750171040932368683097904497849323892155985002143587007713428715847006930247167663\n  1228530283911202961584833228762187312702544027509886977752418671972580398456783452867233726268194259\n  1376892237327986963699571947508280574929908016092963856488757743668130599330030106516567168643311600\n  3817843318094769824924266082639256472210856302821228584359129114203603272060182523237946293109254102\n  5124541700516649174969785017658680012863254457378725293267127745162433436012734039785930222159961775\n  1736148666793967656332219514934298376790374930825170161852849338344242504183230302641005578188318544\n  2893640874032039660088923438710023409268523884967322844566873657042343156698938113117085498055633424\n  1109039029402069878836686500964163691705281565858356477475504883191164843064598996632703398001097062\n  7143154871743704811217006209186084162459632196275818916875947150823636892761717485163145845180705435\n  6379707232789574505387584471007564558747372456716260758755826316241638301758948123727346583284264334\n  9842119906790332769950618788667306344903282783764859091686806539844039317138256966595923657348223568\n  7609504600206957367369539435373448928789454142994492422965419920687071717990820275112322883020637409\n  3324308284076802365996223074507239548291325100146231522838566996364648161993061080350119340985512877\n  3081595450154979098326100700084351632209140971316683905093077706782579384891592132099286598075166477\n  6274042102287069580316910197690665849294116301449041755241528407985584192045942224722408579545248996\n  6149963129567459931787449783413501974760024855830935569788153697313632144525114082928418128045024919\n  9295984561729788649836529671737406535027575784653418707842130980573575850987089232183386027668096878\n  6744587673937042506105294559344800003379484411869103438489819927217800456984088256180027740246971556\n  9634535370581771324966543170795487952577664211206856943407407369416521104530170777514495029664201508\n  5673418561330879369079908598888195417742618803144141748693529301286286876979634971644124217738001969\n  0974862799608946093642530679104174593571283190402983113155059303861120619275400347429960129769845672\n  8568007574786825685265588805504465028247234062122672309876509524679555116757607551897367108186648733\n  9135554730387177148259924982090655636246368887442816354759738020092703372797235756205852019488731175\n  7364152085688799839625539506720457656370866786849616739928990516639547348064688416321612696232140430\n  0430349787937658955255912612733494431374931875585152203504887715420612832321554250103695842011777060\n  5811310857406721768844739241215189067429767995284346046208510422989295590153886171777859625965902453\n  7479964480573754259033955717369017939751600199875836990940353460200600611457081297272864924415558859\n  7502427490101997527856958345334494325002578020434444086828907507743961736705538376157878638538700095\n  3573335902594668119751237389838726653687955430018415044807205276494457025799468680349949294168674710\n  4745236313650471152698278105520599626500224544073428713991949802538333850588539364994173363696431899\n  8036953211463174617170203880708663490647863404224584691355904242451402814259720943368039404264695762\n  2035197605253746691968646840574852273222141126346820073268099128359680433712489865124847133386599958\n  1557036241284311923713805206985546305223962860016932609247618752321257009959416454501759791304831585\n  2269009244055311865815319784593140513549679750197159130563640796787427438869743181215963320242453695\n  0908108540107486745322336694887417447584560189776395844902174934597104770315419794721755903104895515\n  0713033750922642894743661501146171128540489836287823217755403355815130890086002311190892831719794615\n  2733963981475579561048165472182282092824126224408661731611829531462701196213661995941087935835643209\n  3296418935628950752183416094956286605476082023394390369382944107069073784215937110084355080993495125\n  8480556142602794888117357782314109215630977556334356892809062401470430406809674541428500105312911014\n  4071931810600556195293759944098161264543744367739789284558236168065730568681889329055524837773886978\n  8338482126900338552557729632948503625724161794560688062505674398343584068858652798471320568203326801\n  5840118612253710729945929721983140398249546430136414120937944647846329673080412403157916714681071721\n  5465797595084379065463926894416436702026717333321428687279300067525680895947246054007739214366237747\n  0366937064798928068343630666235735491883630674089690534541962549218595948296352991442506812421957849\n  3976249362699766843201171783094789764534282159211054419253956738906802587429523470246253627205862445\n  2991614257874992015478349251604342385349243843410303807273770776570147437343580798451121498902138772\n  6113074931251848497128991745909500393219062568077239325454554691767350021142782515915371392247521510\n  2619575181255589919223775605562518625777871520402423564300801544064737868647177454853375685133039577\n  3050554298410274520848824563801811743244115088666941720292251387140525933292189039302348495217837323\n  5334465326269377747325041092055082762701360107626880573492834106150143211791258410932812267491152949\n  6919441405798335403820079492052726207312385833278588756477905672110416544166147076128836100062438413\n  0531050140081010798755577315225042463587242081346517078196813266473052652668700975390102354840054319\n  1030305850507328485666218923073610160979873010960457878627259697182149777459319121724208552038322309\n  7743733627260091079170854159065400695404757694645269352738958908946566093553216942712942611401893368\n  1755821233660928809368683610841295931368976682546341618079733799311434919945061976741403836739591043\n  3250837896097654632163442968447504718087753879660115946910584698569346315467151967310540189434725327\n  3510123305556649244625308979855259889634444538294144883825709671236053389198293136490349913321228421\n  9660873657571369432863633838749656941544771070613803436739395432994554889460443286211704228102975764\n  9010846130362580988520444565288925386561835543746690507579482110698111609436227278171946884422390136\n  4355582252243301409371154840113662138841082479809005429724928690877078639433835697580891344855483753\n  7677719658959365875154327502949340116362862841933060481710939239987919008842034872943437214946123970\n  1703430337079169831624576605061362459054918358805245203073129842425880187096078491816358337632141776\n  5526484660862674494777513116337460985326156771682160131478190445605770892030801852154088126888224610\n  8542068433312797584809219544443889667113144461789314741293665128198790259329194565273687344836398893\n  3899843612116806898657975674885165488863376900353752919877576930810573551739514437952727038004470490\n  0728573092526263167309907400068490459975878713209353348147998072978030685925274921540325080620629679\n  3680290963657119655454749832657557609467247229240892061371056217009793399279320665670945892120839049\n  8460475864801144552327813602814534457954387336599185402955060100187896258232064467145096398089199675\n  6614659823701412873664688038594032665222408750886052884106719799914085448700729302201722026030478638\n  0710886172631415313923748994778191781040775452555369360545903637816192863942002266964803975868226345\n  3758128535507962060646362022763410015625391199463257867883608702524372526283033010210448943262262753\n  2207366765291091628199888719161678669769861721068950090236405929175721859458476306892124704365027536\n  3283506500433461831897030508283915358506052517223442293318962943725776163152226873950058135915637995\n  0090704572007260968988373875369824262186314951213988357167356388063005629032547514519966181726778207\n  8962727991656377480299102250947244094198014686901886252851004233665906643076501671002367873518980417\n  5086476038055608827119847886391169660571257581116143322031623986195399608106448911512990383218924496\n  7115181985798502770446978518416280732953187522170737542780783674506060843688776930498302304143646891\n  3983700826939640606945628816416952916654437390847572819696146411957158066368813124848782960051923653\n  8166969144131643782128080377458223191425066537273186601585557631000545881914608634151201340660568618\n  3053991092842220972227727666420070998758231590762943912951563496720838098972472304203873278350860147\n  4116048285204200743959607793967665745457415734381437629295610953115848209200019968349222746222332034\n  9229787977209325937345893185303632200218523329226604326327773869929525440037460654804476294982724042\n  2914656005290459866149053053303411842327747134752876324177468600510351968025950489335416177387650238\n  9319108406652138046674665296435771960522892728790582333626717180104787074150978653274415552281550979\n  0153143256991410913299525027699164121847989035341734180288807859437047470037468716698072913698781051\n  9134823174319971817569732471693411240421932383237581583407505032512102423272159997622559536081716396\n  5955459215200626349383277938717450987669553428787897746644363855170650265044857714758789516639052612\n  6187671738754045938775924493697246870221984680515191826034341463515337517354398346584036650078008251\n  3376195811125396059589417188047217874636046685077559560876646149799759072572546693095018122660597563\n  3832045120846386446499477556747110488258186245181148216024173113511553376394180161986082932584828502\n  9721564124935435493701472218371490931352746516140422988403472587358480471003049710367861996903966400\n  3189027014102187471439739304796671271469674524858219615904435885750474711610835582761860115988679925\n  2327767007791348806270678430582303768443224083728557775850821627326777552157538549313918894433113709\n  7187976549309906304370838121079727316041468874104427329403072777436378288442397759487234629173289643\n  2364895042303033952547723285292251820978632941279227761069976483964461549803039103687476367007442072\n  0134868042097834465670780850085124892609127081572378968179538971471665316354179274132493745551049067\n  7088305382910466098618013354927364715788231751702295292557476729438071843235282789387873058507172169\n  8784087093608489127582967318450352330091008245008946000168372896985534781567708986066370243799181871\n  2713748359424429636432094727572711041804433460130510702217782472919884095444291559247296793147664168\n  6467990945637704603699887007961285734670508717635799267264190775864829795801509614971798643932311870\n  5902309745168343571252335874425716502513078384396781248954102878996867215558351818219767292372675088\n  2719132592890457053921699623157341359810162606343841974111595598712194855707915404099126084315344947\n  2936182597146663520940304301794361263079707780953877079498286453666763263533422068945343030626974857\n  2960188084656490209749955256673401338028230788629806818705205412520401199904304289199124015463064896\n  0755234800192945487528805570650554523548791789559874402509130074164191809399729468221035701898118676\n  7215490449502844625996837678251688727079295334993551398511723804911695566612441880493518211954231454\n  5793295497329011549763279700425725292885167605567069578881891666892649627826606842817888551356822010\n  5986486442689731040420642038862021415931334335650607977648372861174785410131819538820963263739781867\n  5015670201035161382762235549907816708176258006326519090723097311326126453948061274615763974697290381\n  9915758063074587538517334833468607608896462270121404016579559790815513643179269714327811600039509295\n  3053015664053854401446819567416891439500506012989953252062425640256999735405633568511706263129378820\n  9655763055783267561616292217039451858995939277954633373520501688984643648882073146139928560157646190\n  6088270052183882944905283501856406504336417535013934985705100635004423277553280516632501555360016855\n  8606321618016788228898592777398070823443012187649829882195076487937452732497757164679437682597865380\n  7770909315826869893218567541022181137066289150507191692405571751537297985467954771694404608728583402\n  0071682558785035025806898027943094618467258018625571769991436669256776624788825636710239050892975798\n  2489522270941846744341466441191197624863088675226917379560846434163676355883085129548653711250744903\n  7322882719925727151996600021666938956050382795190662337107102964526112535482018081623405931612383383\n  2787215450909054427198032006442253236001249893448436367593719142322778515962657684525307584855373583\n  0841651524777849983556099679145290553712899338041735803322331380434826019161910280534759866238541512\n  0389560611327005564966892813167555129799676336653554047090793988866895306857810173302660568853689560\n  2118077216225892191992431173048925224971255312282117588225282650923582291225204138370082863879599408\n  7533142292025537883192590178881759789430772711316048915678508678373881223628875585526611865733674460\n  2261173633288022556206861495846722660537793575255583609340989163829636599800730784500136994588212051\n  9742716629518893636617887245193879883914985074636701161462355909180891464878247698323775978709634559\n  3154570680055282070629464310763848171836412428448832224163453064177764928060031678970019137344145995\n  2908181300827357120244541781460612372671440187538225274535151552424500790797536879918711567102845303\n  1873265631128191873581420504230774629722540369635233574830656204856108640934273833183346343273512715\n  9264239390049127973028883783463744236046441965815843840531910829032323939150063705253777010659429219\n  0766393180810878765575969070784073173239732355063441358556746002928122819448262638691858136721604139\n  5463318790725616930815409969437600214768482366689595833864458433913973419577395445894737996499396501\n  9731801875821543881858049244015386570718876787890605894343970572439680676623307775021542477708237790\n  4412690412076066171751458329065681240190888065205921445972236876022617302455546374056207480813993774\n  6700941252221532734488417063681524435825611869662613638340292866449700660379967501793763167639180694\n  3767843386214908962356182010564061401237788509883566708473114371688891394268479485387646650984117195\n  4337028921584835072586019765152460415435606762746411781037958055110585275094244729655712945889544502\n  0468225672010620986206771821667486885596778133367304894138883039656612191893305871404778455132876728\n  0301432209927052902106177139212773759052612468035783233612231672451314301832827898769529904655069884\n  8503343483983359922741648106833596317970504048017163575811696110898875265050394554508189045782033398\n  8805527336174058906607625678876023448996558182195071306798279843747014713056703678040027908882626096\n  8751798433062161683649757733948961813441882416886502289967808162797562569227498087402088768810359436\n  9299203957265613050681288387614411959186240022364452480039479994244058253172682465135209489596658726\n  9366348840150992837598464647534240305615590651054491691242186078781176800389930760906904835067279512\n  1403003404594882920845356727163295012007112146837654494140706925962143328567874574683801853930454624\n  3136985598732642070733736209526825330022465956542110218831635555322102232583541986992666491353192963\n  1878234901491587001477499219108946501280172618658424119957747844638088817923589672365496158227535354\n  9969841302939493205679621375776989665420961561839357548510610187366314026732506199565814384095884354\n  5927104275247448553201536290028879027363715117097611575104474448575002325858148560788985128350955612\n  2124413532387816233318165611929257620999185168792428624230801705860076558534645099212221386291932006\n  2916671040534441325309940503148420160032899923191032840172480360326411739587737364393158054756344611\n  6674421959053416946656368004997460891763261639369972680056711919008111646000296009990629766649508010\n  8508005158670385819718130552317324630173528769303497898533046076126706915198052104187921693861999113\n  1368284102584387483086310227556652408281412368889519506244729375224036690315921818643234026919293237\n  6887151770807674952389899214924574176299185804334862960608936311062581001413806306012314943627930687\n  3326876877147445496118241966037173011732267211548894144715807643463644764575907033408588793793885511\n  7519467423534045394122524064570712144659046656734809242615388417502636499676403979640395064536033058\n  4671065916086949364276706384187525076396896156031731192926863383238674463351811330830743913035433722\n  7907141030795282271658841103444348578821809080282082955442812200380195266021863595246105666063149576\n  1270251582303335224947078904661050788518613260070870531252100924188140333110980343254472187535643394\n  3220404659540269285044885564614251052654795847216630572994563578827156077280214821750447870011247793\n  6570705673098921138721930592905808649783986319434663257922428340202752079620107667460469407170560953\n  5133339937607492713011765060222240784478082149383963988120054778938005665780359904311487101637277035\n  2144947284480659802102462962863743293337500534210984024858609771594603462650708927576848032018361905\n  4988522892809537682131515043558251720372860169596095876425139501382209840496122262422817340434028089\n  3997262257739330366102986819922133775791637356034537807550181325596156935501032832994238499747515243\n  3810011519501213178050138796465628491543324891943371832694701926816767596061591878897636526032086512\n  6585226424524119959018981878845082876944376766318492238487992413740076722940680731052803953540236603\n  5209984205504305921203882755655930480839116597306245017725252787907988546850842585551738383833851994\n  3442889159122536441186696441712424001358879607219106134942308330297896634430882711074670005236299743\n  2610231802714226622261875057254396907738147426352215524483240080437569669907102947264051780301516189\n  1026800926358769818418013034526647105519950731606432675504048745317728164797498493168163518881132546\n  1499640318314012084999975450565440566511483583871743810710444468199573634628689300271371764306960414\n  7832273275678903050809576914347830867035401616202818491144123200843999282131818484332288134255124888\n  6686544852708423042840098831385549010037940264844762363637536465110550081029406609915248147926317308\n  7744064207095391999167556393167624758908322427072948295443281512295290316475060981071517094932166168\n  1302220084899907335192848409001433236988693791759977923872805644858636356047169644366020445259704868\n  2215144197815912322747578772163986575276098408998893737775089374040658456115404534488982635679449628\n  6422470716132658749959558344008024494005256475311275829458245552383399388616021670954090395096229843\n  6975360579443816778281566351717190156086785010229710669378772149098891936845438672597300797493811034\n  2945358118921302910485720499673562211673336635007643262740588295448615756961432047896330591725250029\n  6559546804876536262815497576765802778755902367873481625042453157027418353906499723714308623953642833\n  3798525880936563580878758721141673582000237858579171465416121120260342725573842215518015874630577677\n  9395293678912532977700508226250081937416451141684737365725226777890874579968237345277327360629946429\n  2416996715508622928060803167877150190204161663020493507588377690661867461629647016770563441830896762\n  6618874403297051778814524340125122267941041217761721828885081597216420838479333398295669940349593790\n  7282033978008796049701378070294014570618322752960348530283719222610059395644991241509277875461366823\n  1461289469981672588247118985447614664135974724040011672646403383299904015026352712185799138187518382\n  1542253047992153889028461653792947236379633347931270846642722737043541076853791213190343311924506345\n  2076733343809168129039267109298757177148028222733070858590225913929052589740024375710216995532657613\n  3351851876638602761997003980523930527428933709016910236752074517701696404723753863828765431904302903\n  5798193044682863204543018914216075051699668512336445188313943158140465206850355976752840620968648400\n  1463298802638325495627213258275734485355830002225513318596228864977249448196664152819040702879710950\n  5677755838364707508929280129921465508984652700726965716889740132432879571982172311902810990922494210\n  6911519427044773587520266021778729973938043291783216346721288728433697903169348592455772175986332169\n  2291013129964934565694568312672848095842925093551561535868203373672201361285171957991790678887948977\n  8741557950785828040051987951437931024097351375424452291066587300786546251418820808073071926898391350\n  4925377543744202657016514854903903784915335783523919509184229410079581794626130462168818441217468062\n  2072287104625149387649178333892585359415439913580058590242985408557250448942910311306684106105252152\n  9436405894282256195150902988534967011852089646433204187932153336684750090937947458624405009441979525\n  9305808470573044171422807785657037127947580934562908770479883469716932355169605915512903946546491946\n  9769565801044772122115297178854242063014493599903647048816869639454598739566495684468008279740648593\n  9762888615420634495952047787647960222248140451871122057621282895120964242624397691077791875989150916\n  9674884969014041781462488218992047215397897010041004451916374635484937776724048963056176085749019066\n  4199208564988244166592591364114979721105709200483463562191125920531594952077285728535022771786911343\n  1709507474177404611259771054406639288875718393323600024450260387599951742135949797649404000414409398\n  6809319328642332313807310726052347022269955029753364133333637683830769912223911477705585997784287425\n  6964525973045897989161844009118754738104698043805595170062963032943375011243769165920722953015125432\n  1394054433778916278191406215516820884736345341979998879516117261028410632336985345662271408982502069\n  1286704441169025820479657650680608338935449086211438738256599464349788032327217582926945169986312673\n  5875109548455878463140759717201962433708521996779288308204170836282188671042940242600584400437735875\n  3310704188814221920924607149133502963690584664488320319474101734611287867351794220941454660418534030\n  1551815562321431657473326661079898031090681700826887321019364595617858517345054728589800787287211541\n  7256740244197902884322531541019214013509123867111032321373145940511561470672128959326381967580376907\n  2313032161582473040701388589334636633597677154707019773249548814517149561588915972704031644349512185\n  9747041467171509731132947384808502107073004895212374842154038998185951322490144185729193570943752415\n  9215545692963115014493847033948930762435538342354395078579177058758873286872636137723131795763188119\n  1749399736458295599559616847144784415189854307741455943009162727770640067845262221886063381067248472\n  6902440264267413390721935300584244062259464253948368565478450534349052967430589748649564389293525069\n  6872825573073886534797956973796373941631251221135723661242014026468319875234913753259196515806193872\n  6661939160510493592652713216922096224639699245339494168148769759450227569316017372978252259321139227\n  9726446990787079721129270100728931641413289755405112986071300454244972199825592301733559399196662588\n  6284890280161029774147281472179960743046863683943583762096637059217800358151699129476731548326243472\n  2529800380095958755554513635248529233660366613345215784920268506151949203452902146178514203242331042\n  2848635208968797421845400387349417283201176273782264796397846777136587351119302070722256003750749407\n  8103946338951998454416631432297316080844049828135430303833631635314540529914831642560125106820856569\n  0016030297291658467891832210586994891004078010769247782572806721865866449357592377066019997260659525\n  5433273364250389479833660143199307308480934516150880480764636667529086671693620624928739814887990436\n  5333871639691167273697027312653742840860973486972932552788541993019041684282321395857966024873754065\n  4392608495318634134694686789235833606803394455761856487011325964277558202631925680997158944893454073\n  5451669323844921499118554933828244577076688230525469796128224404159966892371592950939237321195478945\n  0740806774448900380624434575224611555723894226838593051527754976545431808349023872919846748693162608\n  8717921512482924761589351414914158904235105073534967969487491863344304793625203651055672156988823952\n  0349805230153122385212513261664494737046124818609901439565463727101755621611221104722479265060881879\n  2187856456477020191870817409827426388517851782319529341904819315715640400178260080474641545364258579\n  6882213147120219506870737039312153332239429647101433881763991811507421555422604821990245008205203155\n  1588031076765688121985750384512044736027969238848943985040776693919191780385131179046372645787280056\n  6499501595762530276734247490355778730320694669762067937109531408787466090719090054787150227573861562\n  2840311999793601481740181407268559346424708186513726761279734277641240894070241225057591283320448767\n  5083824823354900622431962572928264805660096775092853257303888341824250441019443837490829289077044151\n  8151343279012631862709344102805833319718393808451124787757790528799614248096853758097666763701569484\n  3487431747574899146388916335043383627398851102955909972689955904715112917945559126983594293067385743\n  0486989898559443261989642534349217117176194986881381153736011925283763481221877710943925932205737095\n  6269816464526459305254130817680476849179967094590975627099457464166873129985177713155886207655433151\n  0263023608492235320184002464426949822200938856198141742352942110120448887865176204772310072355773711\n  7569645402677378698782932384884658685482430725132245997181951763782065167701734963907291197323152110\n  4508388963690034363456497713884180568029841405323097836878788733235745843716778596231931182129965442\n  6422746033116562189958073857091407481709077707206012582553725598818255400017096790909741338551791505\n  0346241362796294337527980392121612449422857348055409299617422186755267066387154019716495925804198284\n  5727233943587273849129806250522990823041441796420186323933597564085626472114098710275684232847105442\n  0476927372279586934325516237287061306248948317683005950316273539272221555960371912609270563209001688\n  4464223997459907628360386145156011467908671952274422534153735630436368076582092944816815756244075835\n  4209445041481836940072478719937160807471437048052724122720576200148265567384258527615204225756167756\n  6344890835515904034755970552781149851302508741216556160585427292302899331654735499079156121786647178\n  1343392824994159050140923632016984086805996772364631180032309172314490659601839443357324679947213636\n  6714309332268725922769959786634219848604764038331215159824633481575389136213747050626776094939156543\n  4449665030715756019052561493434123986500863349768772582014261603587642188657530917405182417491784121\n  5303222383004188066393854558891787620068788140487669276059762638850841876717239068821513753446907420\n  5279687593862965749865441776294251870300911496135284438920514500715511087309466495949907089979305234\n  0129573493866881785927244230815215906606499607550272376081272387058512137274552888617735445449593851\n  5895687751951802687798564825202662409444861882867270542074750435367998458468021181612451191791640838\n  8220977886418275681058507677565728648482836037024932871581980604355587998037575747633172000054495984\n  9872516688565706303352876068093081590181410593721378560788103151292531750411050960975165425371030855\n  1748548992807927921650826702477524637499837850472341148722403887877968562165891841573565939687030319\n  3507502981382895299683035730430607120754662998058479510773229041914306816287029509007188141342145828\n  4156116327645897977943185244670333572201518300806773009843428145985559436573897199032628610071674691\n  1509026594642792375562493742351217445080312134998741021050402625411576311412306403373840230248447393\n  6132777143177832648722787200003132437991158454107320083254717655335778841973881119878308116128253343\n  5001379109732645804567535626928483455102531756976137831443682524778543069370631432550964076224942709\n  6972762106167981630745864773136210291691319019350539173633877209593077288021138495225308523356420091\n  4758211321508141634559373276638164620996415041814279261478485611225096974418073994012186495761708774\n  2985390839419901188858773363731131301710135777903347562044395262607677976568538504151780028622026017\n  3983153578949045444271657055964920522231883544742831119346960371194121860939647436968352163008411309\n  2122137612361931555091187753464456042937379215166896202425471680377818274638590796820735640934299433\n  4271792080288752211254331790114149116004796389603318772204714551925930589486933504992233576520706393\n  3665786108085920057759573577060563469345760388491080506695516093810694366212875882733161322864831431\n  4717672115704619235614650037740538721762741113660178235855845173100298207789993646817768759805771969\n  0442932656414928889506161743273954534823316663997917484984027478354053591200222609439905312070766019\n  6672743214667313250599196153749191206109264878195377790614253518922346613960953196062526178425715869\n  9243782660916171746497163472047738961314867194294824902919894191675830888923397311741555417268094753\n  3102737797997098175650450547360227678621069754045059261438837781516179253790106064022916738026962573\n  4343046453004211042527662303055207247573930679272639371318872288012695855490424866322830702277401555\n  2803422055731726091592927513287204433777236381546602242627227955242640479069128534664743956703901536\n  6644825118623402780402537808866611353566441069137697238823654053705720326485133071180018862177768059\n  7953218065436753210222504280004399406185181288953614073372395066311517070005713863153021329368553801\n  8489869696302851089301202179506470724877503209994836756871724700290558145698405144674694507188717376\n  3680287347355619685317530756612015693057034430987614972306895286644415640748345880898652566166437972\n  0289586844220392181943171512756411177614756371405936864000103588026389125969238170622763716762874806\n  2838160227594105114626922888091294330277664959472497384473093376327460037108435907859976671800558687\n  0287301832296672925665119592610059415810036508929062603999789107646931019522717446451994436169991555\n  6415641215108714382080886807522978508148022862341353184392056663971152460890481318445192314929106328\n  1540279224893782282515457682716245961176395668864617423953715865744626643996155478905163732521825783\n  3325356445898929059519260586597986713448274478262666789841919627360593520221496681570436556904167082\n  5752744588175728116095614818572243695464750508302844307531707792355713293487611783908130291059918355\n  2262237468671157570593774909379757938195247331632266235982695699804734334402616879654751304293461624\n  2661346074732526957031148814696916429336907194815454817908292910720694297318759719731015426199335646\n  1532836182287015155903310706146530421700668825337970132344950607141683526860988131227220540903094664\n  6066185857999914153978144847741564082258903540644906463510615433719400401386160350714559736014278623\n  4514865734796217978467570218989951333364438192919053008577399504523493495718968461271137688957597933\n  2349533208953814539846770285124109139999624094286153561549520156418899621259300512644209686597252899\n  4184350366818804807529105972336008365482357019198685509260350048765737882951629237418327132367686584\n  9464000596709506778345361003674425949188581955959269025123931107259512121156338241589606737480071832\n  4687784130780969382414829151895604275501754206517442088134014543607071355602676349959757596004103616\n  0961213773621820223563980101455924936015689714897933365854991863497304103495007905509710373294892197\n  6405886995320189664933508204310048852305942984868017855565645389715296386871398239389278862831305388\n  9870441633874853236655056254302382861317683147439934461560931076538494758464893162151583588989339195\n  6732944334790390909645002015254529742236093348737748570906018648070516991257559332518203044120573389\n  1169249497937444418172101800486952748158248607577122172413829852529767035268850421330346370320590111\n  2769270842312247374039903446761895700102591785896614704561188690554318000135741145453848091623845601\n  9398214576980154036744730933242141647275552190877396917417373506414595184607851240181377454588376298\n  5179066094251799695036587235132911540694118558004057561078043579191051543895293017860705688578117217\n  4213915509532072119708984152215425316479193046160498117600999404341319099118921551365122611550181311\n  0735194067489641860940284869283055022119924343866309661229983761658981274730669004071331315325819303\n  2028149674557028927119805023083429490724610549109579955078936602634698465662818805549010438789895744\n  0931415296414337769026050643640983268217633628709882627239743023005506385167528922648375095088613721\n  9833353460698489068556859024446788863364396043781823649316075069795253661777044807862852104682093268\n  2668289722071591098008197780192649525383047246360795893917370036932896635802205065980285338702996809\n  2228675427129133869994026633577360863754047202114992733399559638671394141599506355503816227131799287\n  6143298924595866321022805072720176632829028139513624639259879408411977424214784974887928534813292261\n  7580429695360568496416333588361246477604717663033985377267173732323243519297973342376460670072590569\n  7847782259010224718618495510870041401552763492243058506497917469994122470166700310104432762653099301\n  5284206842468595235910530969681058431185510376080853681033317095349081348831311722359377438741462183\n  9265017156090327940281899356126944963967143320782904731916666780851825519771728800627735453991592789\n  0340107862889636611570807579263712515753212564345879767582279860562178539046344387826022476983164473\n  0911677313769865439441397481344800381829810375495058853983542914632275329122606239178293199621398691\n  8817711118424419627718789923057350447245775383119433851793221285766035212168779011404776589767784356\n  9635136532915149309638039104754501169967587802799979553895585500590455332979356370264077033348112055\n  9679109660880465445819911756967335381794020297742084467140554762538001665796195719912620080781668202\n  8859158624857236155994016255477707914111600676407826080771078947343728991156761306850732249631591231\n  6341975884627647288192023676271637519476695332542049089161024916483733496591727080014711527101290890\n  2961211040472462065622820963283626670888972846484919450548524147558133923773626921276628090107039603\n  2994626272509471411769121429133539751301514317746716858402905968622217080111036660714630206206422073\n  9673674027544451115318680357371197061263214355234685554438245653255194962230924422262761618107635327\n  1218486711038748633241670789046885223329211115019790098723766740155479167534474858911628126868673604\n  2229943560768269783317351763941137568187311853109391473316134714642957480258866120984333362644789232\n  7799217189381104902575089833295752311385116384118101924499132930087784725362736588016792732391195667\n  7377346029231167147252754387732395409644074174493088103356901689944732650629356812407468591689254650\n  9211091423164339664349653553999052260304711487117501951086036214378879284074498252703324251691779534\n  3239338053753415428633449200572757968191874218427218858846662660281339159122650870329556297431210060\n  8476462382406120209740885851097134502445345626967484521749379519983660135959959804421055339305799463\n  5412156592603739545481307090026816164735807530907005794698595121857669282043359313336580210439358016\n  1079082794266448782035280157498477771875366638868714692849223359797020185921637526370647072392328071\n  1774975523653624170626315463270059026630402473980453353020409393130497397130791718151488632385160351\n  4091871517272596320603977518189877379429833548962149298830651687972617323342951860291979123542091466\n  1761858081206578509755405181262454785358714234987228245076280218555416439373557287341317707953318264\n  1069580231812678272926217247904786733132302602879014764854335809993244372349188499585994862583067600\n  0122047336344668680030217744283089567321206573109092985212685308293535203316260961238719270474910316\n  9411516483884747974567712343355744298126844614327533710603770238115873068862889693941323630060605042\n  8996520045106037486769613649172511721417104539723698376574825092862531991761037960505070047452751987\n  0692438307972081336510745808625339870452950365773947943751943255366001421055646414822436061646770791\n  7165851176561085923563460948549764477962116551131870096990291407315148390390899181591857833265027795\n  3957841825197056152467518107456330457082959442889150666715929760412803354745155100439949339911357400\n  3681082145201003716633376952121337532395906445150652333790747504285781596952756961817847042381784203\n  1599241711215728175313825528990831722270803193340184997462466150686413717867935948059327285196433573\n  6880274143158690076520872345466373639831869120209656207541348874115504351794570520219208662862157046\n  5012959513127937440724676204192266556744533344472968171487354493873384801665428264237833848317565438\n  3336174408732187921997143097193907561528997991933481684566486989431576014380286263353313618572379316\n  7236606367549438005252967139974035099407121933737585712045559496028444564046130603362226362162934122\n  4576151165419387916848132809624695244456954621250879118935398322196378999498705755174877188610510452\n  5870912001550271811121400833033945999772865870452341916673040685570047172861172633588496827107174500\n  3538903363106665809112216112279535205973563154238786279221174002792992766027230910087889644867197751\n  0644852854236760680678328702716021491220890738359867916779079846546847654432886332754592689976471361\n  1821919363719709430918976095893307419509153578998159456268174031091186213611238703266328745925123801\n  7221859237596420397178011973301354548630311562876453973330103535199368908917165821184472025394047093\n  1783306012396416727093121636937919332391842597730527614792293021230131636529561376233305284546377449\n  6678385572416305553286105327552078438940442472330870014940075648539493897085636662472351155496842637\n  0742241985340721884331711808624785109999817623225805812020490727023675155996038558466728397347325959\n  6127104496948996928070408723556135501883486098273344942119279511596389142170133713625405959158400657\n  6371033621859435409072149507971926424741687886613509620131303193981656443184231910367414205125568633\n  2809855207709323995574220458372892438309481108423300876415366308472416897637519419399848086392769531\n  7901643727802977688806162490841933764103645096126040651273694733432136475166867454187542353324904525\n  1400126199102550494220608990865348912185197785208035382979351647361636394852849756284971488562703642\n  5437615253034856791421813834154676563036293594327156888851139645341755011355523422660951773817818038\n  9386443090830539927386531988392370825144349766957951254066405582132495347608244642379595204674037169\n  1040228650601644011882128168872783923427369292606206409640919596145904314517234161617915107061776717\n  4151129700974362635716917980979131076075544400727482316585363917076912591900555112850732808167705134\n  7490741450119502481084276777357730810360845003755565026865827089490664096114629969042922698380843496\n  8138914924798862248716712812408926279700650937412914280120188192206542159389736338193225912707130384\n  8942162931911004907149225362821862035617644685446995943076419072713387818263384790269051413488524088\n  3415970409316671764584851653904600109634729323170245268608078649180077024542605338592009166331507927\n  7873248325901604421715668749405791518967711591318927501780445182499374387432993291435543746809468340\n  2608346425268170735136026784411711754768030257828432741271295550926710857402304746960026445711893018\n  0581121892575725002417910664730201129469375495333839271076783815855808875670613299964991589394990408\n  7497782355039210513630164671634086226936539403456769518652775268560312868088156891699160460136793560\n  0028878486501738703611861366168233700637624901718703548391653008880657523737679906815547888893864623\n  3804336788144738626369751444635331513645033652509877954130939941467601122228501278273455755159561984\n  4872672888621691139127864441826501071593433318160552880980931375760219544842366891814048761296983574\n  0368011755189133005722699475919228724396947107244977040473296751338485372898919851448791269339956272\n  7628630157178270573552384501936652886942503015712886490989930558977451480649740071081376020676606100\n  2833539832072435945672059494512168440253056141611504723767968712526931563193098160823297950425898166\n  7480087815264867736414493569584287953879511112090041388243506999888209156555403289250228805141696787\n  9299266268622246705254906674953625013269700318245101140735192981527091168287631615254533623132422680\n  4522288961497091739711353525544012360861881545414708532046722994693907148818860332682826172282696478\n  5169840975561328091090492994205890209975868027011829714381130616650165606940509417447084136593172946\n  0368323148867837834015846665262779381103471856527342901126469689951352204381388359254084508757429340\n  4830480525702636746819999711139249943082380948147319257601152853824735720831491052716081699222814186\n  7532991179552447748792024698247835770179058176843376667776890217764906219369958965467659969428721801\n  0978136921367446220974783004092718190513763561232548612721452226168051802932568183109314139665924531\n  0344236884339706735287266383000454195146442303262301907189759856124702358650054207598252489819907503\n  1653803249502601693723058314817314752430435942498914879189062802634091227267353344853777985327688970\n  4761672615852883514060352527088519929217133070578576387493937455594009676153752177828011626903772652\n  8989620344126159881063216825320644381640612917117212009556747383916722296235557461243901559905448832\n  2626441625687126870485003449211415757614315487883822624493825719072052822435654030668643394952786639\n  1978261966212889029317080915069335476093630695038779648380650097087712584207442114997169855615899897\n  4787651375057853627245365217806628977750732715703498547747167890295666395835111199772543088210830083\n  8719703001636037548232031811034519634199719570801626375425606969661834362972690706622306143131863618\n  1161133168418495161296479946354081551662886453122010561796238101443846201413252468510264137934116621\n  6666044355543396726083900293342498560592304772543016048596898781615324252348894799274995680405750878\n  5961584656399688277050582480803752624440992284265581071965313962147422223415350770031361866522902424\n  2427339752232201197300895968910498540544742769756380596262269087884764367655193756819519963044228090\n  2471965977981411229976113099668948406547030430616154284052898460555610527743167094547976542569994432\n  5615151270411776840247262990518468739384403174909227786713746504877565400352618233613582209691595165\n  3100302994702612137983269955154794300452825040411617899229947911176412173992693774165820202835024261\n  1557953577101928695026460543592411800668078233417498334223525119403957869035786809979573555664634818\n  4109235356638053216250587339612730165179209152696307741603539343614876508656958944166875931028197227\n  0842130060698903276812481364340882914506935350078426900283389692890036766306519621256911370825149526\n  4130730020572342600614347947841846620763374247401965234906393029662233773082064022870408809540394489\n  2602375593027578381867271119555903626438180369441026989560997022402685189290570563411576345663453530\n  9178364491270655146521452745160957092696019819351482504230830933240208569382325737324655619783805079\n  8236783914896441321211903253837193051261214351205434672138024917208445724067560783891183614420617219\n  6093241887871539065311934562423143050595975813896800145932726803699031531485898178421841408627035413\n  2340571406372423344162305201146005372433545440858047849152738356053700832984194419408785772894289429\n  8905564111848901279881742427130941732502246499897761849958444824319633387713606417005057588112062601\n  8903546125859345154561817568409731473384201495189375815899601208752575627603329500301183188095642910\n  8679299364914087426322667213868491522412990329146293202682373490956625790320642804533851675572566335\n  9643282983690679715448949144144284457366131214716525772928322838722519122781850333184575375231181388\n  9104687301120253329343303322817674447909206656325018838874991783124527795687803251857087877108213218\n  1754229913702999034634082431982200181814301695015867564772318455173516019353974118068162554986334692\n  9742793638368312286209015008476329602715420554092347219774875557737277125358437929973367550413539009\n  6260754601770478320092090000437030477206239693112361996923069451921228075128062610903396080855119939\n  3625766456058454748929845661051643776323020476293348833136645533457348047357156744499773471782198157\n  3926294356614853325635257380075373424585696273226443292539121854835008471872615376119359921175544946\n  8751722095340217149673323008543031277343008442170392235658052374699781195238474449333837385774851142\n  7462252203934675721232785066105269132797730634628873726222419584671667202215168082910005267022364151\n  2652274077600461979496685044241492903303752615324755653009315314557741560785488843720415714060087651\n  2807613311400021517609289824898629450626479863972781208733447929847854531512329334051406847255746928\n  4862631503547709257191442014221858878025727912833117798221233680779311687586547771399946239543986001\n  7821714044511587793376458252175919910881923830051663310282837236134127214072246237953912933883641879\n  3155329932894879874861538613915230746891741006626186077722679134871363221475165685084419917806948619\n  5460193408937081923214192638277533759194570326450236304347568717345295839955367097394731137451394332\n  8197791122226939725459124938379823126607096382225967019008381453286290461060658685632097801508542233\n  4848110590617385229862052817896049500732570427222020393613638247958310354325985507262140340985962778\n  6017216895598750303288281768040946852093886403363652364944285765333810979533420258752306609947377791\n  7483409964056208373304316767108759298266668435467009599704858953748415115221450224994544152838657802\n  9285301765856291013881441726693837902070500341910121386791346354652287481407153382029019192351467212\n  6838275100017394805179223575910310629411782671583818637819546488431229736302075907294961313226423551\n  0849102649984741887018127403987203067935831231548287878038686720763454984951991134450991244247310505\n  2272527668320660348538056734851263693194665299251629026264658941634139609150972187236402755002697010\n  8838683249414212571204886964565829636160986536859883788390280207060702963996208929169242011756462921\n  2717841443866094448415307132753827418051247560470084561419607860495448592558130716152717681871096104\n  1702864624451063869927990313298023938322923078600246111212562537492992069623605549739779337090550915\n  0615995807462647693070614654733657295388010846593077370926439327096173358979875513329851735335805761\n  9820375607173964951210260568242153539432206578780654333681668379183925431029629978625583138150842902\n  3460414642850633182078026674085750429654935395449486518527564708814351323195973497899171415169373256\n  8833893316283389645184887032263989305568945183919124308293251565402367538500430945522752298621936349\n  9930799560689684466187459894748823413664085188532193673114375894635657021422230371741481201272628291\n  0573318578392273347952606800413122404444690695700343265791095617342284655138302877708170928004370327\n  5264455762009029489870172647182289327617882346799595389668011402866870526336706006304261299460849499\n  5638275599060264777652197025375830641181461287543876098578289963422105950225341504398260961876098352\n  1652316543316977214412517700380390215981379748913202929277554387117033911632248075246572497296231247\n  6509351794356748381143152864133302908912377714661246904486455116492679934634155621188228175642302405\n  1694895444281683141404904380578860590107370067182984993650407494702785573862720327108426027326956900\n  6412015558094691371012984255290544957645064575600374031494587908210547355911363990672780648145919170\n  6433870697147736652477844338630255698388102589879309501971312840708918719696749394002657194057221592\n  9586883457866981031818359493810271931161525153017409040319451723832245963305267862642100074573633679\n  7264614352971498884605529190782295721345692646383479217594057805130367348879544947334464560679667691\n  2782679904942003628806990026035221665252664880972246721212946167822822474271783410535858490938180843\n  8207696712262215564925244641011600663839118183087308563542267215017218891349111443407423167201858015\n  4409683941721845529247030666331743969920320999137230793920870633268149502702418363237393557565948355\n  8643427585271530364753467460118162312180861113799324835451482289863062536933279374737264046931267375\n  6534019973009076142621228650115856894482080371428361204858316174750390771287604650336123613522431214\n  2049114096204585829225543574900902717114310056202779664273282036840883514218997367661285154174170155\n  0559669295433553384988687023249020610644580716922863343391855394434659741831033154532910259130360646\n  2266687977945573490454674882327531737599593723227310371044521133115338289304247739724195727440116541\n  8484315564894048921358055708557627558495534889191385643791638342408939602209788019587504761416457873\n  3843443198087351575166749682003791537961029734944321094760732700463633436612590711792603829657765048\n  9833996820052846423420685449469930387124964664248581160442000466693398574168555172983698292635849104\n  4717933844683250433844717587252699366862337570798586379951176474378774221029593262173881717992112564\n  9607665490503647530112846059719986422397278433919677740389582319175573259941937900854928259806607678\n  9498548433335533052044297814686422621546390705667804793891317765192204993576166388219632235722413875\n  8048818728755477834305533714162429159181440724910183373607258613130585839379636913731605046386537876\n  1619976568352789603916541221197123163706463843508750588046575531967200804810632083118215379561380098\n  3535595260936370006453170806442028883772669082680094247506157736530695369994647344426417990880723658\n  5691623899636517578076237318613662803000677595254569830359350209310340106654882387605906309667152580\n  3190270180565107741796599641778895066406027884717068077927555703510222371473067950065096075380534263\n  9820261540712721378560322743288616802417338945979050503213797484661490309530174023009549575261795889\n  6983609703142914084804583842017705933308727898829210653986085497841770226800199431723125607279669350\n  9378461673808145347108132937634521964744163193311786906499824823727616205615024443944723233791069608\n  3968856032674365944761324366862391058343526372587026552727235468109736136753799885434022478297321958\n  6473847079849851417285386752779230658409174320605010991022389298189386457216041689492340208559404805\n  9798887199075389944836245759181795872647854824368717842805118165701035999489616756458144117743599941\n  5574156405419809407770607818178732780883923516652729811729470451824894886940253978497040401257850170\n  8525229480032644855398293395410250493410544461435613045371236961682202427087546803225777224676453869\n  0691735846329099659789270857241360685294722841899888111976949257775673473149204541882499353860754485\n  3832734931602494458301840052011005971211224881899260140903390584301410505598071884441547633560933892\n  9558270335638391892072441156624136346793755416738908930918686080312637892309129166075500989808404308\n  7717386876849306238533350915041060003830601639488536879210612389410574394034606240163718548425217716\n  7545163976002550502264396115259942943086934986907462978375997016129503084380366066005892265852930563\n  7886695846678487572600253291839307185472610120143531812300826282453907565263848166284306712414091535\n  3230173735777223170545453318573303986361162909280796514000762580295868325211303562521349985400678329\n  0579810026266376780517206247540163537025216821873552872040199635961887360693473067284096081288649892\n  2816545218524083282791281849386363527220300859827544599898999583511157436878788812704855717381485740\n  3078036294204859420644334157901693839596815335852775087815743971924322779883170605463400533096961159\n  9543732039412995517719740924937281938691042471916807457558054131728168336553796527595104025829376600\n  6937948476305024368669308749861291151557902990891475114714361655097781089168915938904322861163098089\n  6160154365423970713173398762556138393349278906057471453816915692648820151026214721832503409165624542\n  9353117328396837417555069788772460439855626108533737402877099728804761149157785765104752908911381780\n  6546922207217132541594679780555957405449532558779284323247504820257296107211930542720344543111901843\n  2651599832951192425499568866292451206155443548518778433760228457318552553020385780679964233347394328\n  3255079768143174935290365355235708336227295402976036224596787022467961087290065369158110329772411271\n  9687184631712015310872022829121678513683286828899841006308305969973295124018343792808075866877889849\n  6043772754027589522929366853922675139928237161596447373298270175090837568027446669159111149779944667\n  1135691088924379199309424721308073081984262593144347965790856700825628858836114463307069019106360685\n  9951853870417106238568043241122994069976976521718948993497188045038643217598286433134023273173503448\n  7552793783486413104199496595525770669045671843550215620189672793973426821625686085922488113166647341\n  4298910138757127570483051459436636099246610627201124409872399971042075654391506863102013575984601467\n  3026511990342986506396760006966879582828924339782590587485678262692633034683723321240661577602951565\n  3722610682290383661336834150499989593428093201865424703607359076560816219599759343820172461807695817\n  8347221271503991239373308059816434946231367174959999463042117638181478301910213344735692656258805710\n  1644687984556617203758742814909984339304652393122000356442486502802002210387238150855436080610859538\n  1742785324654979231101510181266741384662946267400340729092430677564917857934277516529509846000986282\n  1986519350148631413113382340818641810195988872295935856034372242367239601514627896565485335331740074\n  1984242601360667355298407544025731777149540219275487625663663209795134838923239847309342827299390954\n  9226286852582803762571040814041407092153377982471219334648252071838785374450072385259360567659576220\n  4021945192479291241307585464859181278455595125339485377327439546532520168622505372850013045372400046\n  4744479074597825102944479047597268994937537469280893311554355051420516123636834410073498429947070865\n  3487282616826119499544459888850359607914367111963913932091120095413351288550899249339285379476656164\n  1592545275885347906803485930421014317785771172451137418462432155337224056541214942322346734100328640\n  9237227571473170380930584666114105286653492921570438437193875825489184989446589748921123980435592536\n  4919086589066917390808867500913233054266548207715736402520816248301658987303608659808379615767364117\n  7362734669761566653921348293456423991292807859979878815204292215190914169078549736187251693099991322\n  7000674997233515576579514366474702374876614964404926134860829976097836260492782317388949792246852097\n  7599508049882697239249576598722306469511876779916054956726996908515258226529522738588543930217342747\n  5574391874411376633994128594831234384848812794576013671006676165974395896325545306708168429451211409\n  1221200910866698998915001020556924848523722554213107166139198282765742981882917518337208417523869676\n  8280591023151992531280144537722164743682595086088863644346720804079957456104290101965608808393098287\n  1606160491216360458690862228973756455741357430715910893672423316644773328296824188314921716494972514\n  0119493690567095296152704329196175641010185140596083954221011253004320324477290450956867286869283797\n  8994453347325407832005428354880451308874136319369558168287460790465669459004074428841873812325676996\n  7164692679986955886052080637298383211238624681202881704348155814062949883062634593344998884038652605\n  7374223073857866400023774153128859094551257535393369408694442939407522182847100107766580951275670201\n  4775408298259436553900777906180300371040301910921852932847824116551890922870290124041600452149317093\n  5775360816342085655233201443845388958342206841713882399532270635638724261133021723608875319692482011\n  7906522275084815465360634684320835251951083321606843173343658468059130157408787018229598765822830020\n  4252835566932045019819881714582611715984000117232324846223680233784983905719584208339418833025000410\n  0260037883422114836730547496096779242970449998379947904405434971089626589676691300284990960386063046\n  2400933379790920357551625516664005711218771723903001503960954051845816999386430449804010399161286593\n  4744955827606683482489093373386292669896469705317415608922966624289143819273723567260303050110341597\n  0150390759411599156179251165622892441767557720263927108978526059947131533570045904830124535860224570\n  7716058212332185295875822030519372890200177343206194287342147523788608300702997965315568103011287992\n  5893918338779647006752027036887724058406643691909028743876338820971458010174951013464584028127801131\n  6813989780650900740767464220963899804533262076514960825977452275842390413450268461861681457953371759\n  4622683030636661453659920280300843252851498178817712725738675355028513383679230567432436869620272756\n  9049569472142242467988436041192263169155678827648422239119627403671459897414454318006168862933763562\n  3975254816109201806289442065086508865174388445174402936157089106653051819134408352417385390895294733\n  1269090022881476173592405472755741008722118602480706552734785464670810033252880494872818846476645138\n  7194846470027398366396786911087224906894452544993013613598230210096649662658249790741793302604479616\n  4678961217630473547094105905476778743627698111464819594676539533132602160451880568520123818538359935\n  2509055867304816958939312668888710724516375807869185298046443759849390149864088672912156151469350544\n  6800392775377162800284446170887283461332016027846935141710371898135928565444047388935336434225299535\n  6306714864357582266150708472242121395749058812364726080795665391821078069759191962729961376825052719\n  0168013501825936503904314892374222182997294359105047665101984354967715836390356050902744094547376200\n  0866255189537989739869552494420945283689372916225586445881857232200509734021124202427013381380975063\n  8707368786224134616266076141865890367575672804946851392949246947497670448286278503799394283278791220\n  3329713975438436447227794195248300533133083265941268165481431836724185190716453711839456188537671861\n  1463451009876355610396882403469322743163868563893669207826287866646316230586562320803446703322414896\n  5844290862011917977518360789811784708762629615319400347815464050634565985845395933678392047177816196\n  1151978159915334832397561116212221045289683087138354599880658578013548593749042639560201729578681154\n  9407988789989527859449531291247582481713710885909691407061933036180030332389191321684024237117855941\n  4793817512261537355292820484620119087835578241076795898728264838018836306051625874581323807170212707\n  0311601599319566532110559086844637230112193935288299328435695606597198930148418941924696514195047131\n  0036209138468408714367868832381248718738058221779691668726770528694917232969297574129371576503104861\n  4982649963942542515355227892655817659328122813519904998628338917695098649870938852865224641624149800\n  9133604809416167206933424250017253335902412245206966274283806079157097461019323432744228427903009219\n  7167819796597905954912721055386447240760083100058808181907244787034365745427947504666021168615328207\n  9367042283157677410978706565288995809215120790091062488938646517486033663048808838585836547541959063\n  5290169607959866719791951547267539998847762188847851073660556792237455158009612734637037295470996414\n  4895440357070050979597124970791498940575042016503073921008375739413281657808571980285113042479613451\n  4504277763666054870573901649799638800674927633569990174214247086042763368701538895425544860519661560\n  1145707431101267836061897633765408595584416739699898991714686664840902419001493111173462062958230778\n  7057948676463855675872109951364683099777160945465572016812285393776737409942830395155749453169206582\n  0371452045827753578337982711615753554754759598809028882500151326903062183753558815228008049946219926\n  3139514759007671504441201028640422323467572146522255433374645407695544296373365183294408114816553112\n  3178885685344936256510923382232508875197006402178562624050439203931155127424198127866118045752037903\n  1352263821500210772130502406624183002862477655911114130894749764170442763287774736669514152962797298\n  4736229019636223154363191418417996968962803592775061551398755785367266353781400817153183187933147980\n  3166307354183824985477461434758212203503303949134626725084373973133134613497187865221548479521132806\n  5589745100203248729792239256892753749027042598668561490405375284504662614426425991229576994984595616\n  8866129342741521686045369508582771055380684247063968607781328993106285511287995439433670099191520888\n  6144555645744227925330947510327863999828608664778246977669364695968209330630483252302728616288409185\n  4021075857505952335491745175635055894316749129117086207384696004878978263910905625739599487492495979\n  0110901916146590802074849626393582792650583647676708383011968855505051861579809721852980782027546790\n  7773528459488554864209571848095773550264183796622010560620176724101647596182317714441988100961027947\n  7760819625624682085457499375939175577255504390164427090909940333682021018189188094314468725119448839\n  7607261064289476377050838168092847287045308547161072786663101220366887582906462496532944215040426089\n  6079559602848376811583310656398188715410222918563637554680861467680606261759125475132626589633416570\n  6265117268170549301094065863026692204229894830237644323671421946364900320018910295105537319742039399\n  3038094287078665529147692881385645878149664779808233148266402166554846713406240185971412175424409787\n  1277182877853413438373825809953777455566863903097000614928407730247009172019952462062453919858592371\n  3450742399985171822495428895132343503182334483788319295955334879010992117189922536529429365336258259\n  5390946552963581374497293699746511875338537487094217708081745701742251604090438846121574124452850202\n  3798390369991138969673477880497042088863931284389157986861499535720637694821492093062812513122808049\n  9666262553224283839917352025667452522990840994632586468341113042084589880324142878241486082621057749\n  4753300377060215168255421685888255205289137193877249869082025393362940473047505009970440709469358919\n  6990053347830446358119649104831638160680743239747518873774504853932080118920921762003254128590019212\n  8507800878010809612186997215672787878360378342850502233591047386100379003368195821534795312420332192\n  3791186979738109328501036782788060812745282883103918315704414803727152691119589138273502062661678813\n  6738930058943498719262754217586783775861692911564196954978050050271744148214225317716645648976255943\n  7582676430949126055292857753556527311492956087911082159619401757024920446262077946805377695544163790\n  2384442862707600133588293722905895613531099244879237739700126380103906210362971005400902332662052868\n  5512923889365400766396639839257245082449689892624599243943845087655789090281898568343345109961963840\n  9116437670596054841952535056878723052067916205797398008695875004656119615450401629767770096547018528\n  4334977644679496028037224229231209258155238064515073175826397848971659561076294495873794568519845906\n  0936913497322702428238293584834762009727957320397390824404902652459373962572954491177296085988591097\n  9831916191923715574314777305613275865030186712879223339994092210626790946258508116928279669238172379\n  8551276299352386088317714689728571559104796911352900853677375489955124718689039574466000484795401447\n  8028822320824256701845114754583859463997760412123218294512072077908176823315161845542195987497445589\n  0151199270623605189634073539348756409531560340706935958257608166769558749209824048066652756245519232\n  2003251452941755396468271902352195763796378975941750521586754201928536559666201450456338552783571256\n  7120512822751960929539092457841885540127128286062203184030416252304573349919862033683941854919174431\n  2814170274683480533123636546408009522798679980816786143876702299176420421935770303028892406338233711\n  8831666892347256653147154261973692488185677444236830676285808035577667085249394327267591827130580282\n  0474498683109238845183965692912826914135802285087920263815575944588577839176304153824777450273630047\n  9676856895905742907753282403183887419532847250575823699898418557360973793479262107564800127606600568\n  4856289529627036503340728499245707682166060043085192144993994615927401867906702492509188084254975382\n  5000573641152765627882068316837456136116466105945296098764787617810657325699441300696040441275748480\n  5908154315252191475930781041409918043677066395667263443535624561935640751356546727167909411879488480\n  8680923093832873822500428513086155646738231344891197653033059034948850709043640855117089681596818853\n  5559683677670828759269590012226813063407905218083141753428838750131652921876633335743143710101634779\n  6658883618869883499832898116400702596550204761199068845930641188013743352809379510983052205865755190\n  2553313247393551842157260882310168318176409724179664282170553923573318235997210559146758099096015712\n  5453625914657358345108084976967080717266943718308124966413928529324205814835226274469375858569571687\n  0345022377577778359815858095456674554627297947307975693205085626405035283025567228667754448284086209\n  9813897930370925326425964038534996170546386083723031489481001371999013197012628010849698683279080599\n  5250749377542359999787837446577837123753575785267771063814356136789079473724792426181599280191554236\n  3584092241092695194986758370140080691259459445559254670473203928004701116001559541702028795035929201\n  7703968601134563044492333977435455716545727149517353452904622158776693210397256540533868239130580966\n  0021212324831138704907261634988177752506339880373528304413788504053529141957344862622148033294954488\n  8908545079248054268374194066918855516757216622110920899731852667678293526613290427617120717343300234\n  5258919537355747509268743152936342844964077178567399584381489421046285181038496434277355192443854011\n  0560036409186090659830023373684591499584014449901293693725893952889834811556455810610307945458047566\n  4650489357678527521118340799459874420567550698461628297481692743403195744811212692198913243550319837\n  0546644424960963633748486558714369342400084268306946647268678216054307605555515711301054996369421412\n  0145286056715492814503563608857935420449883125571959955870785833653305512108392849984112684790571297\n  2202465501387082052447492723419195036030393946034767708515347254338076913543021032331182709941052543\n  7316371791899608133844403673509209111063173376587401600018697304252984202448885270331725146924974753\n  9319823503525226176160943848097053512457087513186892673700507442774120709790407346312262052900063918\n  9290990331964353335337782773033800956435520237281189341422221316384124662187626562926213165374744095\n  2305454016919059121029833254873844314996900817917666244456257105500140603668001332495809064102834877\n  1641935647143040955057638038573852209871616795910485222080708395443816652953500877460681136027308248\n  8566261392866772837170303237832334671640641865105991624817670706345653146764074492658990400249294338\n  2034766548273034152265790423510131092975678304848136329763976322746732729909893927449638572144129084\n  8706448070466163067183262697301895505226175036704437656063860897547480919952639440353604654399823773\n  5619024650269312958914022210598873408816322256258686174453244115894930355509977482474151507373411947\n  5733373556527627418519164245146201049878262945368950884462321176358003511841835926759864297128139853\n  8414469096917190799516740467818935875027443503551180799677762498706284759291327261688448884939141128\n  7453205724835916236067416163446388013123511612633214157350735873789089864603319101047904951088053276\n  2436343801953205313641343554593647041984399732731928183025760085767530258321696714646834358840039142\n  0370724267082601761625339029898671526756221981306035295948446464040396885600648176610903305607906503\n  8768968446731694854343891836893537933416898764610405060241093598555326643129997593902636796969251376\n  9369261591022851172165414889215726223597736677014639845855210470747638897225490221795578347385363008\n  1933437898874815680276975999495121254415702713764902775150787799491095614895742622739879403322128257\n  5324578456195527149717737489231107175800448526108753397144093342364167000739474760533876638025429586\n  3552936913034769868990613336245908473538052999169523740650576570393490154739065565289258081944696284\n  0122139245511198760380740566099410523116436019256847220532851072587588370887878354074617797601531730\n  4950058293812475052503021700236109573670907840223511622259723813014440798479181330321054432443110271\n  9791005913738093483775863613997719436720065592456993814702761918466612118042961718665283106957766092\n  4377161598315124593617280103901636552046619370925251253631396559201177821427680194280476586534858158\n  7470311992677097913350491107205165243246231253831574487512954156035527502636796145461093444168535781\n  0273138996999546867343518103443255259516930023300505925727997815904820223589052604792034825075042171\n  7345546642531252852594784406842133378979724559983814529024913412772434245097179511864461506281528392\n  8650237212926436840813268942316931518881895385268180047631030778038992441215187198582722254498999677\n  8751458791602397076666044133305940017725196828827618138902540142141154032221880752214931387303943894\n  8386348804885872573129605440226754011944434427123955690237907150071386106419858388879568805486335172\n  8084446447248132772385956105213013091015106264293276316247222859852571026371594629994013226550518804\n  4657398980037754421846299791933040060517616187986026555760768914956796240330209203533823006419857512\n  1280549087681264999866296820216008393577425692390014509676551896830011498580395006624633861680225506\n  6870759127483197530001455406015411980784113494829465680601707418219448269420291459193117972944253523\n  5139331011218688316780023266376919519389893049565596364430499826362332222131737958633752729015980267\n  6243820849089436428312496796216250016352996689304462584580416724907109041427954474322776405586064497\n  9937748159790612922202930619833526180042611796654967580548290181068947372216120265716263043635302282\n  1293372450839435343709678543243805831288950527866356571712880369852845487149507985624665557793170507\n  9028998685971436459307797350701401522754476693419823926389892945353431902180169387585028778687970204\n  6168231973519928076697586512760646823839169601486711150096038459388200510615266462562727086373994715\n  0257718107230896204362641552557152127904583542959059101205185086051998335829520276445242512357735153\n  6145132912213357834119671870758566063500029766458721899656846809835422555679769978615295831620657432\n  0737210996844061946085275213997207746028379618294067782659809969835866089743865103656242556250842354\n  3545630151219711116732833655070583247917273565142769410984986357066618802528434536119774234900016041\n  0913598065825325104777234873758588466697858029999224197366504115511962816004732157650700516628984539\n  9637919414471961275368496384841840783539219495160760752984767084138274604403017707579996667675686125\n  3610514003917168172567805013897837186583796897615017209848060227215120876367111635529356196130402092\n  7396418528693604726513966875563040087535856868313141286860922825551242269595679930350249011366770936\n  4034990374845874198910890189457051985781247844035757867139319708554989380999706541057916902095988974\n  9873844727261372435180656164993163897351119703310393978040928094799734337726502122497143409823782365\n  1965892886279223277990394182050685698376711662377215144120227663379491737437342283179727940119374539\n  0490579714461718360256732214055219462186285914543896562340248945379811955964968707073021860780513193\n  0946785284844420212843249930715413564423079386272526585208492269484399394853053527270682335863948608\n  1705774075169738521202106289594177160792541306991346081438246328669352312659073430366809538595608450\n  1673932290965428288540978637787221825907274341956466116595934087134481202995796040005764146848563841\n  9208402583268552123795496248911586260094009876541358587061925113653719481486085710770837602097237465\n  9553114403073394942348448615252372266625317209081622694000211227591834255298281689971968761014385191\n  9012898807424280528355553325232571548587561447752011946801115509440542965731019362159591875821948220\n  7475615307833480300854994330873982134027070003112858879279673962736609207126971151381953771554641063\n  3745558491963169175525559918922408979783312427354538417960278459589864706009528418086646771109464159\n  8431500095974947022075958749369609348923513155308795226753192288751932690569926959011242800843780897\n  5802237272111281427715809215786190314382328222158431197363867972722768495813632814701827652361699870\n  3831654805714617520177978010749005200986222538671343789879848810445030271773860682106718234856661032\n  8159840918571490847707412577372152962362895142819394934492310024755294687688142282688263381992107050\n  0314822969078127068502360967952456156317625378443908683885454717662505486886145388589401906509184101\n  5885208833696129877316727526919756238642760951369458384261852183389570518641326320252293139134838082\n  1287964338813629845539042373128573855900623287197915909121817103349208828736572596006751034516917303\n  4840664773124728536498697032255058028512103145813971655005402199912584671247522962330479476204174835\n  7339651293388462598605466902068727431079892009360086299625852649556926342244349075889871207540557239\n  1778889837474006283110359893639753683143163791553508445994998151790357191664595797264053563579622852\n  2323209995625290729565968625666476118217436889365526584209735880483823563270384629174104274634032764\n  0442472179196338923330045235292002875730135630382111728971331694363722061750858152029084972463690556\n  6762892184262651781976519538524643036425620321295916089585335981540706502452521657088226438896955320\n  0330712386017719942697998742711966035304852835818441460854913450644431713086666567324744794322805473\n  3913760627581890428365658659895466488561709859023357189364711022191554480141608108632865265720250373\n  4779658698028969756875969566551715729978174149125519450833779497446698060268643181523422924316776326\n  5101550537467770920415647646247512496723011428848395397060605607246531422732188958383550139850224798\n  0616382349453661289940409355917809265868236064198494786394927392551467596218556484340287163998424165\n  6407922432049921519352709427492550972098376405547995076369623700896158531420828549780644065756946107\n  4012428301167709175408804880626657504874497001006448172817033718571687699052050431269126758942354642\n  4263219268161260713525593779984687684876663746373708483091302303187597551925243991782626402799661636\n  7094369112530086284350297886671483877355700954085095109254267237087162850872049910014666606934352543\n  9681324227750520412084311778362086425913741403701893905849130885307671803377759779815450406004508428\n  1692653954942424173439682579794296332233121321810780129321979360275038885263104587257887904993301724\n  9371699290336354529074965146405609127548752881574874850466564788157133643242701577120650882647257091\n  1545293554151064551035094710720178800179246413597213842994871045977552798427450697742656414883406830\n  0809230546462603894832672239604062464659457420252210842881282668896752789802434682655789626562663797\n  4536891092934689209248410970235713162753302389020769867314325842760948183881245857587340140970686718\n  9561813112229470021978448241581544509819889152942428906934660562607956566439433934279983588235711675\n  7511632925562149947095183522331245810913158655773591758470369414848815038632640986605244160899442142\n  3724467318576854052616459608035904616045947747232056287891088699234201957552645554915186288103709855\n  6289818492084536281760741755782246663879072604677554834517443481890496880563765032503535926271374514\n  9886240548295624736933344962330902739113708105840712372655403944406661654666981279401611743803144254\n  5836113138700180051064222504742126749539970759097152710314165536334773200549635491466719499256643771\n  1135196471224844213383344829914740191692970978273304820965702365744166216404138597571994011075505481\n  3835675097536770208621480224769057593128457961205201060652722159599745589563929274161013544777148660\n  2722228078789190310493304860642348889412653650919804680472667929079707702290502025767138443684581563\n  4829002226658722453892420758678126480742598431037231448350739349163285687087989353089830355384383950\n  0797078015089931667721215355785047682448066812060081609252490055065606882005394397529404297779977739\n  0954812182338828159978628439344893791861555638458479425929894905438450373697647333225685242402160195\n  9044724016399444925891545222094738197285735608141629442012082969234213675190569210533735923778160066\n  5668763641463665790435737824436651668510493519577657907919335490054245374836258264105168437864450295\n  9183589839644056859368882636863710502768783853127777056659956030015723582371471547219056714260143368\n  7966468436491439499957272215058042899218100989507993449442141990214468925539286769175103982467582463\n  7343805239735083028068718734460641876299320312170407048304612916426319820862850786951729018997001434\n  2896826244178078191626441719504450757666856324245674581755185913604359995857459882503553846674132820\n  4525370108050902351148404819530588806416040823552351294128140484544881037085694262600027163923010086\n  0372142424842912649571956987321905242756339490162246454625934745670300567283750846724982527983673495\n  6177089836516547827889426186105183276920850360362178003391524933714844455014157911625050689091071382\n  7580224465050986098688327677971183257939187162167678835622419886753868393157565897768652016394528273\n  8867440651787566006894982173557480744432557759069273637848180513357096270189715205890970811986200522\n  7679349913304058284567203585664724105889455308752236461838439640259601125485287660886628483076360128\n  7006667228026700036149423026125416550458296169931638437058296750705322926910916119674936127372916312\n  0586368847905250952735154380622219327300289599240793907443857366909352949258689440107342217802437077\n  1528161242531908822717327154338237401474543621843332568029599407713014983323704510969965453202745335\n  0702177037070611381910516358803074747708198082653195105524034346189080408772855887102619129910922959\n  5088225181920585188744198634862518824566545078032953634810263484330308372418113655627830193910161835\n  1740322384509791468752162387714423922323245576364107974700125539832471226019053048866664933322848632\n  9053808683517096435404402568667911688444342169402517726916720054236587952458648729193194196398370591\n  0834659556545737455427472252563872049196484680456121634675557800183911458050720291040917746197882965\n  0486123555287269755200042382038183207642553640963208933924544967598152309215189473050197853510015299\n  5735305428112836484236594743595960959569801620275302395941995334462820826497923607942188680411060241\n  5874150857519458061568880834301854125378195459697414236778741870667215842752231935277070188776280303\n  2337402862660420730505237852035421042577244255914042700874907643524826938681071637669307303727237417\n  1754245852247735758270295996649854102311510138743237047991591787902994485501682558654515388125485742\n  5414604291201232285561488953271771724012262799441082686913997298743825568158111262387326261042642491\n  9146730313932407899673786143290414208441146741535167426897337032190690287477060200884221903212516552\n  8911717385674777311366153734391751962707954921617093780054340457873789689579406584026092226706663974\n  7064746191485114465244380741520552128686202006717232636847179672315491533594924534289288748593176642\n  6993620967340749774505307056843141013326328777592130576231470087437384507626030587577497873242071406\n  6513617994956945601081928431937367328417989351895954235197022893472976977104975358649956731850469509\n  8739662801395315247336067459574653673422509659501098766962373414060683935034819838271821186844060176\n  1576560254701139537357267834526945596079177094497172723469473343678038722377574791686895552041362153\n  8014282548673776952837038414279340044001305689783556227986071360705966044685334333224708199605172761\n  5220108066710652379501907097493741821633529938651891700778898834763609236188052690600640828079713434\n  9789427595928872026107851555411239737304609759231788346880725383510590800218660449028979118967259367\n  5521396472906857973507367571821697403667069896134578745061097120350147956537516416615312164732544167\n  8927750724594362819238256233629810375653289132823923222725067941709469131856699622676300847493329492\n  3772482025168055066631619903457800502962160950971278313497549748497080750146928617797205392087735573\n  5426344654046917507878362978303712221263449953760458706825466567329277539722860367819247326075875375\n  0363960555755152470447904689279007417440809916215353523795515931682503917084115733894721483377058789\n  3695415348273160717030232024929094546655312055250126322531741427372940893582323130414035967091049257\n  1838352019535775111030301893738736672956883475900280466901502804156922062794107897682809626966101213\n  7488119556311967779804681249306478374053162747606283458684716459438243677534276082695576532344276053\n  3997129870805208989856144206593472215753513573135315096432568632699760118167688723309047847387826108\n  8300271876502608262925233194476909940416700264006555597136991814669791135677806574510572964711963826\n  4380698960233881135307214985853687086285871789268796297801608941639363012094163552302777342996301526\n  3435775125041351983411873620583345473118538074572684337206905220856255010506100937942856140474184559\n  2117933927270859725115288005694028053614114492402092462087948741836224854453701673479359020150069908\n  9471119500954771699606451569340980957608723061167985930544742494585592763754265507909850782622745241\n  4280564196195794701618141018859396702928840881750713269491264514792458713883472209570125453762871154\n  6135844710131132320149549094464014760003023763285717139536547149001355586963306925811264047920053172\n  8092117912870096788138937329594906876916230917822286435333405933967916024289327484446631559457485611\n  3204517830646491662241813246295767509185902988333230655145023629404347405492556117642216093884711734\n  1895740719985035273669869338669851702573938066023027910628085352549353166194585293885401347619818297\n  9019270269975539762709721332077521428883136382794037795481043639684621695249482298443229689692085335\n  5530853174095397100274487325283527573624794580127804455036106064558578035736262525563606477349056863\n  8324600588264572996728670647068819718804899591820953876986724126105812313371883281538730532406351716\n  0488373186348319448785524534021310596054326978736278990273623581526866772864841376321754066899897348\n  8261186018002936002236261588495903893818383478150216473108913836953738086831643699087980859301283735\n  2876220600536227587287679465791680576358143240925305502388654829492572512760977104308414241327149223\n  0145550249153801165157010725991966088910334458778020184201986872557983485892794115791654898418079655\n  9816529244002860008928330899598461251541347364124755370565807249607337289686395655103449758583001718\n  8013929340815934657740749168731401990382842771226233324460588756739838593500769513118556316845738386\n  5551229294080306842203625672459181138606350480155226167063564964286732345965669379924358729329116688\n  4983936420697970390191593194559703612592627063708371713607972229244838973659949263221859430952934455\n  1705400945927487032843519938814026708591528949635950763638073234705346230932441509575691850480891957\n  1739191653100024157142935668690970675538485026108040743406457426342832522110207103450374538340721719\n  2728609307970908786402740375603419620326095180233319446604704393480054063586910294183143819807662636\n  9229201519626745478890548730085334220881597403289253567824780457234485556638842993651785938154287147\n  3470540776250407980710868325712720965952470280931298490597903061967508059944421798850698316109638043\n  1857573493208970279214433939134282900983890292760099810349716753400553502665754851358206981718943173\n  6521873727270386652434205926968399585877165807536293049174582102753301267023622273305213709274757549\n  2754032248665363239284288788071811943447754439431574633737742190514462638401483845223060132636502788\n  4514717047905831805834894085694942499441515548386334237720406996019335803137534497602844499515410901\n  1381560664132329431053540356633498250090053413621495974752980282398461972836700621058461397781582746\n  7657982601784729657646395894187742496331695884228391191590565640228193496801758163840139429208142088\n  2045469029946376520599881978317544801271199655622131732442716080219316644607184506702451604612011797\n  6382723921134833943879896290584017968636094325530065062888973239251361632702390752395982653489399468\n  0658059487686462751410940649931153419873217299143125910097771886869455712444493582861381259764637551\n  1342798457376202343562568983122530420590214907099967416032154670753881650296586399155315134290551333\n  1653248308850347019549055674484101032187658995675839455823828688310814186283547319475525274711575402\n  5434804661774803878685983787156949134278530829472887354120431902320905952954328610661326976076266926\n  6113521146625276984127734085241913826858280955075837578751829441953816699647593380581097441970408876\n  8832525737438561825911089750196431479372572070809405896055397098285800445563078599861108297845198039\n  9882309416250986802635162822807560816507048348964416836183659463297691973326645044332702652964407332\n  6083594871297205636803629992269220555502193613130943929256168982589380953115434813289518491654287254\n  6286351978103023730034903799179307688612204532651318101381689879195678466786614433105801438125991279\n  1415887667170290675999071222928172745278544319176377518648854469055214182947546075537345606085563464\n  2039617667095752874549490120466035196463687357729297428234750549678654459273606276089892469782418907\n  1366910300926678191303055919511695693178319754079624033842110466446524045818686393260964635303347112\n  9213154369571442206723727019032161283163660683535359140279885260953147441976705764010907530604721386\n  5706766549972656139956259081850853030455592840761412465221809965435307163185074886478933137159804019\n  1058010242554171356618961206011069761203387121769536277481470240462879594479656892916665615162911773\n  6946184946177683166359452851171641400879610965586719421163816545789355943747416596019104026506996537\n  6089108849054090880766242236244525313285217856872117107507287258024370274958356646245635139772059647\n  7873476721370969778743722222285444150516258147590016001034987342164287379415209172808743852870687452\n  9967585063462361565683806568468586659128839299398749192804509759935762191530345339640241628163756457\n  3379859690128292741879627625038064030579982239393509589219952785102916463804783293620919278040771504\n  1873006891785738178253793126532269564298480575057043385936993433934560449623259372433043576671477116\n  6426205667161937773757701820493615978206551775960445574271401595850624208614320221027947003286440974\n  9853119493397220525601724380678398080630198033038714010823737020217802399919659484742081004162463139\n  9989387267812969837139653343697806394667642860024152824873785639412927935383607707608300750085468836\n  6849683447381380001948099946392793972548092617557123230722879914729499627829318121179995311913933682\n  9142170800391710839203996253246571242671148076218732388866302732632605102274855876858248299627378563\n  0375020526294883169608949012916313726348858049819248754553524887326239439367504501654768934020682145\n  8565566171050775119437380589413425696041313947581919706682302632423409024450540958834108768898805836\n  0019058008561994910332388450133139604194546882835906148062791702742550569836303868190408076986074650\n  8844236776170546226084543972221940355420265203310445526900704688277458214569663667446999428841734711\n  4807023479517943077836152757400116754238104978226516996793270179099132535969256413102120317675960263\n  6795510869259891936051529316116399937906052216218262573447363342026307505726425225525500696250372133\n  8053244844653771497170577712173855502140364109117838972141797635473176486099732370208765716623286273\n  6406666652522444844237047431260270194052932539203881245611678392260714780011957184750455611615250384\n  4822082691866745295001945479554742670311953388463367504753411924305172890558306396064273009317899033\n  9713439315840591610085863938221382022717081924757782100150391638486660170908139091359533406190146269\n  0424095680526240107056477766184073651996598312015914861912479104532820849003769623579045204928147481\n  4484658172687429160111256780098117726912220907023785148661124371445919846685763094737512094243352004\n  4650532973912516708301825542971302260674660980052603919627557983895090692431900473756401836074549348\n  5910179447557716286315055488761028672918186758647664447865962782729403999320990533549691384757430422\n  0358026682005018352485651517034209943110726037475082164349588541432104573557419801182940065163845907\n  7831309473009929939541827181805997731995522537656235226168798804828472031495890625696894424278407617\n  1974785212111708675294460367053355570333619526994064352330819095743708046560784123500619341564951004\n  9733173836204004227344378915789653495861159191813589724449560707032232278280157914855808866326700924\n  0423420313927164689630137056221855039903462294679176978329701524127573584580130897595258639855021546\n  3677050900703329079755832652569733099251994233523426743245262878343487803932099014786974131728112549\n  6445904277797369126687707533793810529597921956009451964724521456644781129408884259739950228931567320\n  4890035956531488181813352488448698694800612536474277550005042040462103442555588086621442523793246458\n  6130867091526143968878163367734969512409007739167264140941242164561853646208583805219480898873774634\n  2851400043979235067024246706670697307923553229765566845704762902563225978319618333972491546952552514\n  3514347973072505898539350344143010372769330828701075552612213237948915324248501547845700977456836739\n  5706462453231678342716059951325335038447646180452988910089257614236456892093712162335777919010169852\n  7465074331339403860558383560512529911464752510497400839238188040952466569782190675007745127340413746\n  9485989032430384217737576080925883639849428524916612397421340306639968399457315314592189561854297369\n  4163929127458660214919325606290835478894538705890991028776842634490924275819538227715445507550828207\n  8488360093885750407133806431446435106635772542001072151282148738012783255219477266669643519639951388\n  0976645324332723557684264153138097822980463213153774625235404290603580170561927446884847759849178086\n  7455498329658519534616200108125422426766724465919850037372467000945314183285138022443386726425015956\n  7592114147496245184912047206467560940593359887917979059001367488538645068696206561499083496822578568\n  1134556483957272889037685647348587027874709244378417015400337456982748232469221776707380599850755861\n  6687137871868309680967655837021661114077220785221064026826988873072896051684378352036740225003301294\n  2208799728073355203320849825187947636617429055283759128564164974137281936511433254132159665447975088\n  9663784405834138448245573385931223675087756917458077706663761431383703360433458674650157199994935709\n  2631498313539476010997460000053765814494573326745861063304932150297383939354427370993864150604817313\n  3810760582530943941987857532365723323047959249575058023465548576017407830040764894676825864095103880\n  4374399269553415069260955209966849636219609754199025668927300183039884115526354875841019186258565195\n  8949917543670137752629621235562608907598144724510634531684374203926963412512254942553244660392238541\n  4921802547488287657536406695665685449904948149152805038253528556467200442522894314635745970560541321\n  1134776183459143500680409751657893967117854851652292067783571075255139531452823122246077432648578021\n  4710696712582490549532520029801187432980385609820847498781051624257385362174946834560794401386804272\n  5973721779959761348492683692590494544728545348555476728550926269663335154395319199262090222901179165\n  0354053205354155732396286587788501001210509448364369355456565298702510427337311270368643270185393046\n  2298639018498497790852704663810074106064199346768348792149018237926231535776760045253983094883499531\n  2973156738110357671380950602689881032606604431764355029953307435121783536374226307308941189098334119\n  6386055152202496844393942530531427282384519772446016604039958354727913725799487690563099638920470629\n  3760505652182054213457997735548935383680336528207608125148943624690017425014836948910324978639419114\n  6005402306216185569908610246731548646098802027810734737377704918834398152960696061717154770915580453\n  9147213794488630702751062591007953739995139486174490302297892181523395588210157649640209459194090016\n  0611658741111198073433510338190204012029929324031443298771647219418758925676345923219909229015572393\n  3728886071369406177616450934567152280499827475092783026359931981639916855626044956799351948320384470\n  3965009899853801126586133337947755213032889161978793373276844741328316215382135050223298247951985584\n  2530644062732756704048542157953717334383013657922716976581525422725319026917215835634790655014339322\n  2118454577433731865452718559410210622948825204347308783812222983168723577837337344515599482329233926\n  9578929447998242009493926642707394323274713200971603475707441072850307963039075727028380502095916175\n  5070005016627792429318124505238672399685851931779590388404675565133255758214943153517959498790175939\n  9540186995861620669715389333257560018092077957850127158525013243702679838153216831510588027374558939\n  8225165079655680674055293358041645869285231652892506244103450725475174669695766475991206556847983177\n  8838624441646954191913411663831359509426984078970554946580729459831838654621775210631145510433633536\n  6177573050374063429208912775022362094183093820379420494301832564881514621747314953122724966519403326\n  6694654817482534172522912474970511461616005428188054035419894723457255907901419851829814814599027140\n  5143266071026229634919481259342145337898724583097604861888669585130390729173392077225689609836520912\n  7931148217974750644655976134038757592240223960347357084918337811214989258295323354443785318333610174\n  3721712707556161914380532726602449486684750343807525183922459239571783023471419022350350380794112727\n  7487289504002308047407224556001247620731599212504578861913386499033912685147243309106085594366056248\n  4867647533010336365985774896315464134652817637412615811007817367012495447965411601224900939460349933\n  0999402392749438135040080294489916879393667610867550354692386570894147039461647784558930701189503601\n  6968430078158866532913562055689169725157812754395541621519521053001313362218719381457197443546784636\n  7988318741333305512922100157473047822274735436233806082009833664536855868925633157469202431516831234\n  0672977314170507985368300211465536273578120633869732468790648595875816722867648874376546504490483805\n  6518022973211179540565437944615042021563406645608062174908344929657888829537930350472608621682320154\n  9849336065885036959606666076136341254667714265766966938253333538296866778018554763758741375614974085\n  1683629386444454372825282127596573341880697804038637562432135935333827691436403187220519444882699899\n  8678043790503172651953332428847616800651629802990750232478834434240656782881288607696374064960256307\n  1565676750520370530839136166283921641845098284467430512284442398334641301530273921750420119266145727\n  5082813903767336357639254460529716017653757738989469139770671718421230296681287204971364532552899308\n  6401233052322605408161138788925319487861723276315274802047699701084142223997929110102895691963294280\n  3327708353525389035143185882863193742926542221292762852600422545397998100595536678399989239291809150\n  3877736140092815308194078606647484238225957635285178492414744484368434252066821565966919769728805736\n  6703621563551249944361226689330580394804546277509788735672716123758257138391394108724319551951605337\n  6515555892535518269797147560668931735310531915212298359173023026758392741649314224393897443100874491\n  1962224480737158524947552758284137168733885684513971935717435137665104895239029017063092712264684066\n  9278348399886285959423967936456417355871840199018757254634606762070626278962322034805371836351794691\n  0877638519911078379366902264789614265281989949894409583646926514431656582124717920789203351405936678\n  2849401779896529798150547543580317758562255869061012302340109361295535357635843299746307928840816702\n  3366788970128145958847428199428749866143771185970104607861183122285674946913190044825643028262007248\n  7875253943979012522035179906701088644441733329427038504777629594843814990998912625348880022470112685\n  3866059437662227036508267221232223515725503765038540952531017575868733835311996936024166003965092807\n  2743807137547048484456886848919687212310981990987307479532054140103959736196967523052442164056190052\n  6742759939791372686862785354305517912575047157660184923718223934849391969295394499883801965726625036\n  5175749403311969597941172125762371383165114796260557917844027818812255383408963982704978907257430443\n  0334117910810905995054171220773737974775030368125820309958441194867999857940111713933242395262703619\n  9270637724170339781113332382715682773420147905472616543401932267144218019610533705026333742731904551\n  8794871348524986266822221111131891445576221042289834739034998125977811080901318642567088910367429803\n  0491363651421324982033989238262331145775400763163825126866684850315841111141155886426790721346040922\n  1705074598247207024552431403520119565313924583310091425363495878979074393713659709552725556666007024\n  2028391007459462466313074544675113059937775120411928055649729151234915055327810229864306084053764409\n  8917444310769987172760038151634428606521830692100917992794170931936294247745806817335335970175989328\n  6031485320156876979156521241896700403095917277570816030186945971407998244363332875431922140735996952\n  6268303856595845208956554977810132745394340864386526954140660420525015130837808664572997492569037617\n  0930028161622503187003032737144860512516407239007008823823906811473995804355590351241221823298274366\n  7778903853858623918147815883532581378931913051647239015905150073292582746204289143926675349521549429\n  2409278561294142586937295146893142705444227000932416109334447817626188849164416925608135907757944738\n  6206015924040120633749989542529116340952448531423182474586867921351026966287517052106460784704974666\n  1545188141510351673498157830888050629025247278491328835858571968770316330097553904904884566448974688\n  8824842250422741076906915478241586198518421957909459139269455393497074170826012991361372933199089961\n  2447611270277043889271701723488617631963685024672082669876084819752651511784683974330831726048785403\n  0332942786443609114897628797413020336753926893185945801618329179440100958324980587506458366412769529\n  2859826577033300623458265495553231665323056373735121952849214896392942381059559822709275997303299473\n  7505687449872812934702606624477615834666170491626975717975872429291141879750748782171533419974526805\n  5732256003141704634220318975782077302373862469785041650979758445271645852204355139759287529508954652\n  2806626969434499014880200418118642039774220404270266955446032990925495943520252796488734580054345846\n  8494529753539158379291130570376177366337579523977108739337954733211854879061926854224008395361036877\n  8991522104521065020038005180834770931615105441297268508996642282464489776423231947675602438097694631\n  0016887760572567989369280086502487446760824545957501328381000122974730565399913766112760678583451295\n  8030384050253041663117398222113792207474393966300340704960764328821987339877333802859793609821535465\n  5910072431709715706097105968688690664790679515081011519705136357516361120759637386375738584999837864\n  5305790304439430129504109743783727473215821070222676757039661418608774439690962477761429826812572551\n  8207382106291429179289825779700233074929888582353993193563942526806194864206708332451046817067040554\n  2134187651641921977618868029589218724367391297929670217002604707954075998806965382947068262947500799\n  2091780545010872131836710302140341239939886741014047291317644420908011091980352443211333653582852718\n  2843262367250370024116259482255974488083176067370154856289118665446550456305213779045057328185120197\n  9665409430270049744632546121224141128329366437940321984479276656109271707635594012205535902446730707\n  3784068108916048402263161316537882261306234764932281552291952234092518396017149557062533930191906745\n  9718990077654358539453730570858767339377522556188759086266557260714813602684304809463378108948705332\n  5334693152865228184850150399380033663878973389341128843457735233219997625754387619478290608410492317\n  0869792726685650177178453576014440687171686900952806803431893356304270972778706508863333729703100159\n  3202232479700410181494676461336968844790945361149017446298974932300375802531917695505241625006552842\n  6114373076226542082682213459467537033662184218165664434775720963001368851514596794720360121393994632\n  6114541444682752648661586756681602323921704745125701348659061643086005885568792084783360624630419584\n  6417470830336606533005342062042836863188883242668160351752140074640269007587610894794635150844959617\n  0005018277089668242632747552939134464826875600962762224250729627218837874695585396808698731268923748\n  1269813501287025948529870938537227129950556301593716628582188659160520740380572603304513197216792914\n  7718675630529355727688239029226621973058048731140117530813389217011861801173372514366353087565734208\n  9417048072193359887479736426861987941028542129529410436548061666466560953506812679860837723426852206\n  1587747745045440859724123572813629395024877213229181447460352824090500401017736626986417021816703518\n  1897467051204279605436662794521749414856486403423375959054906013609693091684106291636794689232189120\n  9127401951706180387212284307087960773113725441306054172989950548378827727046663864191137798869740632\n  7767999608103275565628709067701614858118516715255720673109259432660248555938871841243042256167746151\n  0838972883424225891485050847290517606189977758300706565252084740820884217337391076739811488077333220\n  1658891141005158542238840636728656725089712885038452940316291883714453787866130540009170501111547185\n  4363558310332072119813348586311534236019202937183043526169084401955004814506589376871523847124185820\n  7056441353048742051561451208666809688655364730701451711555839964583567800349094903932744514411779916\n  3796310338254450612672966298207689283473834827563761713839607939250893828751938890837424828395334225\n  6640130058887766579178359774040670750177108719391145784682542500121104011567813812956625725510917646\n  0365967780579961308628200115012516792484947604849884203733393954346866859023545752309540738153041167\n  5919196403395008232212122031948582192443475529337530173935181814669205300676835498326089762673603011\n  7845855487527030732200353241223910296706648167195592545322134782497402500270274805998168376214118183\n  3876083487925809813815166160414642080752020537454958013051355297538783179556066095345275028999528430\n  5259958631497799031259959268523867599757644136022576047065119871932352626491081301935915996762477542\n  0054683329136080933231845309103266426957027363688615868419863558986966216126369423462698706529516460\n  3659088977630943695328921497180259712631079198634234336833798542781592437536105952313676705884251472\n  6866925962255623338825444915338951480780353160096236272362629321093838121344292596168977607129610965\n  3285812638563528406918707269095087199084875880597680615434384983307862237329950538595446528725800917\n  3848216395247618669194284409202032528586359734273652108417792406533769948709190400653628400265799102\n  7808588169428112419867803212676611908212068769439025689831855029507358136283325881329349787561199657\n  0647703233546013593301573718699852759527884015523130446664670070445701673747302944778425837971339579\n  8102341927430114166335631047200206230346672004347363362091860740637938741083779837265910226226628166\n  8368174614508881058679402091696237070267227078556702466966215235923248906556541142321653001230668315\n  8137095011751649747417707710478671144231270308259649702806523097265225953502609376032046418104012825\n  7029715290996630179728749671607818738643460436560312600913080199055913449698243059810448121422323919\n  8832330517487617761060380242248693360782698348799053187120193656571881137988285470003661803376461641\n  8080056211065665713544573803557216270206698706659611630266928133512859723422734740435504503018436615\n  7059758602591897297176293782075851521436630058441375435301528736386393755920249401991229614783120533\n  9020402152495716237517713920740481216320695616878374406751427661181935704092622544281257244674793566\n  9902240001616279356999773793622293288995109667188147254724474423324508328161135885062617781347522637\n  7416689306796189069817385426207116834520208661722554021513152030142615363529241762488724019384328470\n  3145335685532116346032411910969004980661636537048300440101181291865610897469806955769191358515559383\n  3791589067981878573696873349166531702934832744826234967893671344072677226840840390785044733709169016\n  1948341749284476857660558238949976266570726095917281026112370882204240489674179817610597121652434189\n  8769732540518357639068967524643049459814039960198336818628217058607337201469935697285000231851541357\n  6999413002897984546387206092599165675004257455772138558216066238188184326085590864884230577290245837\n  5483327194659221890608225577193031024428450880238041182458745459540599118793898665243467776067162411\n  1861001010409073491303067136969073215943484812974545321465061611701587079237826776752243663566391919\n  6042731264289021440187347592854707425670344996917675233598478138865565705899983318601234615036475938\n  1711586038569704789249935904441279760418898209130348330214953067826196903024060825099184094962411171\n  4750193668254719668444733985153038785005110697902006497353545593857570788333676889246110793462714441\n  9802729030596670946542694668000365572482505385372657003464552984375485605766436548468959198703255509\n  0859093742098048624130992674323728635611761809716368736588525875429289986840706674091310523331169139\n  0175906117790840555041040973012675087716768600432640471731730874894457953682806516682884188097638768\n  7751677225401507003933693798837135823136755015852875240337553986870947839756157946308525991462120723\n  8560952292201024194226436550096437281621236592956492120341931085580480579252070560970733110036108725\n  7336551244363974172687751532206542256393391424987919220299243040151353261830425163982175998799403271\n  7706306529601965946603316609193225213978517420275604532822558009110705570160851977806571014316301211\n  8809125580649860309480491466761077207455026345069561581532830704419644626444019789530416738083329238\n  4654515372513331684033152563896589471100879881182953236468004613394537670149121770428219428285050662\n  2188463050880409783570115326654916255249526385096275796749475771603492347359628017615562674390623303\n  4700445381194095286975509385806797026611456848448463089914943151524881780244169740998906039084394418\n  5025304735724693730561618537934068829460142540221142337313972408574494586237761932255185568911036463\n  7684070516003606140643570811847797770405995641200104601413000890788089377595295745047655039053183599\n  1468545540757025419445358817282302171840873401560659477066982172966386591321277165192516662912421600\n  2608240455641818282420715559304141284792123814859514483996567150576460271361040734548881707227180083\n  2968140120396622375240917625930501196457437538992864618902187410750169415517307487965557943412213401\n  8619457111141451434767911050873858437954322814623925103215251780610220029850611715115229246844062336\n  7092708922645324107817862349300203648615299307013684697050663695876213038719184967362628612877313530\n  7721316622088806901178452231994936532272443177479044080521012426828275776057685207211032353363551733\n  2228465853855790725929976584978688690119345292746422752555850487824174159627743927269508630037391972\n  3243280964233209858067469745511572367038795593244575845312260023956451863424137001098615026519509650\n  1276333828196736597643559400008983705072192268375625342457964215208141538140352834232745745282188653\n  9984540277441222545229422654145010246288388525706463919904127385863747237719701816615015593065525804\n  0244909298244953501327780953256426342626343279899516866922969197876946230763821342879185340166382658\n  6138981055665067401063420828539478180020453642269679016347991779681426970196243141837017933239208206\n  9639114568653435751789370246642695952596006543260916042709032773341248793762208978545694318474194345\n  1062039746655514720561706101946122268668159690483839429043099283167735414442937221925763921777923422\n  3773397148488181910169982018278621131812845363263984386215655096776531988541783185586741582390043053\n  4511707373728672801882335457853069599677880674179643009793841325405448123808319030586540851532278542\n  3135428374235375872168823632205507065270649525135696367521210463206418432239356377952099896545472001\n  6968351074307701939884197870709476949874864200855470745726706021712740956692665431438337769024013142\n  7899977567787241795713572230606323052385635147631325572644675977337769862841750940339381216921426735\n  6386462354340206694306350751394027442889765823700307564930106573451869821269475788504119196136104609\n  3431644074153374395772435885256502313780947543195773054518785207209863861162273043345329587547485512\n  7338327972219185035047871897884249287106896182108994171586776120838015161888651454001285859716463013\n  6449651605514938227928344490837674328198921142910431061110868692165527920798201649329374581342150765\n  5118784892767382548793511783235161120855178410837621175281500785185477818607679428641484323323319109\n  7266850032934128914045858204431557610778785762577423838489931572373959838110607812467786358556899652\n  7368845240942528704596435920760579346684324145325596356248748821179120818397034784641754929142248619\n  8816983583681912923190240717129570007687463345058546053618974136529114874878826670127663175041210072\n  0315781088924376640367730911755309040928171196136210539234138733422593767876852625713512243413482449\n  2437863318852768275374310490354455242143571369313856402904000656993625368177991878558718447307705825\n  2974350574866412708465442603847274453318352984893683898897808289018623074484047084490852849403039434\n  2955463852740854759015268816000374772522811781161157423713981950740674175343184146350544342438357451\n  9248611580880039606683439401908987378192440400219832284520765154792113692550747874165836602422185462\n  1946430775152186135581519887540463551761409590543738570052501358093904859672162021606984416156907877\n  1684068127414376614091118139631085599151661481079544515324959921366825499632712373562568414745414312\n  3120604881956549350282357979943767775718356659006902041799336909172824104906231327124424941601428516\n  0962807790636038335841419927091542276842581774992219930572580325951237712012994424840701227968679444\n  7341806792582657934958914767888378915440932631656700608894731093256105619880308605486520877456454524\n  7485353154050111681242847495790437215941553943670290712577865368975422894964011618502443713140843463\n  0354358064772127114350431362548438660924361550031965108550050907158337041502556889102458400418193352\n  0252124498457167679255682218023266396231570964589079686994941373432621181495473897856248821720105582\n  7898453333313654848945088878567519040445959265319521581192448981135290221345503835659827193694931765\n  6578186760047007731691816455034194766774380181590333099302566595666806010250926530115150160622468616\n  3897193090214321417040021914577268584078652097221680980634034097430869072988223097519519831002986126\n  7048908177882768775796117833022329018460019071608747684231522405077436077933069971420826618840794046\n  9258063274247275041565742546714723309962603957286538590552888005911222577468976219282389040655521371\n  9749452232127683384515514576846611277668820788347588586006488657357631652755699941191083466144561867\n  0681274946339286427366151155891224086859707892700750339421987583653597343004106955922676103553305993\n  1059176312793511629714079606501253293619401366506307941570050211188043581494533791320858732548430463\n  6596357544534702368957640754770441557149317686793022777531198821848373019117862893069401115893599512\n  7482991205306812955192982493827214779554101294437734517564251171652621616699918583564687464935792409\n  7724551332802362936675709907697852514226641191193585434501374096079376005086552834228065726478022042\n  0613079516996395332476166228915466846940969145152525634154269767270965428923669684031925350949067384\n  5090202972431809123127018255195138346002937882176207767661470179105698709532770660030841618105920658\n  7486560051483952184824992543254856132508585197436417072553803196406928071563221322173345451876615575\n  5263903183393965684200294607011191290037403223439767010625918954941108166177756219216231211370903139\n  7199510930006010300715333345290159788935879859588478418005253796008798347110926578754895419075386106\n  6220189959789540593437873947063842367677502183369288728660527834544522024058057113629600759746651977\n  7111126309694695034238465105314336670951107606862905878290788220871334642003643903663329809885008513\n  3781496316618857710806631255804432420769864751221658236162083468148414083152527539605062706669652630\n  1902593848744034126606357473771924725215165229394066955245342248129991832656594423759120559882004728\n  6420420670742228727590740971398215723796321454991672967308028648644840683221903368490269899297102009\n  2041186578702517859183575055270334768877563858546273960750997614740057219289818296672620120311458260\n  8158553826922251013825611025429443067962436400899781005440067802134276707642549925936710102284674866\n  2259411752940516675558186269417505939971153767539966509833016157369709227005573096959556492723851825\n  7578755341788875263978855596462447492326407482162854233803633594937489952680601675414219788350902373\n  1057687503281918259052125331849318306100702202678580527851563024324195553938565711330622522462341479\n  7114479325789937362652202228457992303460117710415744094124681972950029114139867615503525998194807352\n  3915452858111822298181564944792756355332235062904962376021888577294081893514505639433389353397765545\n  6340866555282658136000816463334525449484505955566705163107708872505206626022560573629214451674721138\n  8601691629300542051242064155552724019455873595097526255337290938999075288085242342552687896232612745\n  3557578081715309102459635355394814762771969164198426111827588625890580436615487562068163743408004760\n  0164419843802937341468286777176160414285412606425641580937439615912924271363136731776124458993385917\n  7730611332988466552457482834925231194587069989123810600838202270265985625763339190336729400012642906\n  9966838423817943612746986659318961904532222329360316632960149436871828093274304915238932256255191114\n  7300753148128807206426842226981136185520154479808760107287609450269249454061487952597780986360069669\n  1013778141234900206869198389264153767225517687495152040148830312041130202278064596458948058713779967\n  6887349391870379821439167206459086965189722569169850999031020309665736330187721579107878142644572561\n  7411584185877699635635291576611517161175561912146377213801136522636271278503521453330658424042719346\n  5708056180564286269988319327273724685080806372534586774314356471343299136108458711456701768060241563\n  9874524038583363793983563393494459503071442769421392165933515161002806826001862171080275899091634546\n  2460226985867174542310977297306019504557502121786672926863366512580710505001747213369207269807192779\n  0633012919033429182201301171302068612463736153617639480556112267903595998345820736803032156050836640\n  1669154640260872605066519849075749621296331192046086424701059966275204067990852111188739395262221717\n  1839456743584366250259407567787455206883177021018226392892933319946189556214339398753777418233490776\n  3855993540087193532155781063434926469216680197306958779347172225448079118111196392639276480012351772\n  5719274788305783971136690606455254331919032228919360954971843249100904540662729238502740563383854859\n  0188268149435843645843980262611116171765842816097957652506787611795116323992635170032619534150929750\n  0553404886640965835191659794919350863488219261598144843692437545565112204194805526823075332476974088\n  4727787435452359272108804052625835368689199319844609897160844674263673591680055284786340626912717217\n  3171756061677171463475561619807884390311358477716426051047474576636143832085499367219745739979786652\n  2775035398061891408888385909321374375272033623025787795610472928563860851309157784649600087363339203\n  1048977816919904548372115769326147221016937339567708656913761110869153278354055689486050710822954248\n  0918055808095852840667352878148038653802146646757143896547580860434512955393551309586932110862993111\n  0605839939424965760106574952402644946365524442407305990365284908966648040467945517605689027631717191\n  8768727725748903365671778563823216530569212911505032641281573270750113835519789309408910748803426109\n  0882741413711940912309437167869613636072477657104623486150406068547046457718789166038214014347509730\n  5369103110844079695504562377538119827552159521365018775633970735439580120471966019512882510545033173\n  0516216341090518192260525546312264355322592957475728820016262708082360424445903581361990459604491675\n  4037553727206181988999514777161493276079799935405323179303743527584995426817187213747300025933561536\n  1921111292616389162184695669562033564970596509332371688551878420333041807503066505560625174160505262\n  3316640919252238258870955218902881295750521711655979171308253404608433079774654768816669196814476897\n  3284839179217767764271032151745244795073588076328905416731603181192610241700381775659611825654152518\n  0967987602616343017278370327961732925081347047654857656059010727673521385459827689298733297583299446\n  8536565991927202723128419689666325935947726672235001137195026467308449262860959852620522409521822359\n  2003147069826977926672250423655929192492054350354442390940880576201050465309269773134941085727997638\n  0113049279739865584198988765833201593343961046875079635201784729873173044084272669658406096180546546\n  5631930250501495988840192508559631880923328014730387912919579582510129204377653347410891807580724712\n  7240276166629686262222231660704487522921471507146159607733512382721669154552729130788761367040033447\n  7105207700594289972711773659192429913212080970648963125588439119442642483455502072746152267209925644\n  5652834679899490660341741368476155773134407346980037980421412267132037246532107321735737604919320627\n  5564676654903913028689978015277912027247510532924595527398642066245295718008680915733555397019651293\n  1004832314704135049429359651182657240498204431397567031470537098506131461559915459679080382063327112\n  7053976438946130683352466915676444805847905318562649578393545468362970975088640725578236692990650812\n  7064320767425390436885713810940745855659674181134810267297801287659770581626728457561593281266064575\n  3286983567541694373351718691544942980395328095625329671764742784192171054963853414283219862148618952\n  6791483040045423024372446249427695881885130478794805150924022184727268743260289620485985683180743752\n  1486290992133913992180695380744363471106230210202399080166428312197903931088989028681277449139877816\n  0123696349353837904833738861649739886424085640388600121735603712566302824193284413937152603550255365\n  0068469137995125330157088169317619805957660961132814536248638143747081376099733927934071387102183560\n  4437946559576321085972638056113173862779961866282810658000636060566965160500275463200064283833990047\n  0686106215897801359187080238837576895579111713270218719138612446092285094662178800912356646714252845\n  8131688323343861702634545310635732686171417326825210992719583249078323219289804851229823033793785926\n  9722693195895033354126067763684519202799011294351329008525896049061348176846124481858634526732494412\n  3950337024289552856674557637765483130391544907241744699033348963010326960851264053688782221214621521\n  9423825090781889402643536751568910448856832921283602581574800998458320548765308408242561350893597229\n  6031858838858038358185664412153867087676012483101046308447443218801447909336747468844785641481744590\n  9124539810323008859206371015635875651643095961127396401586176978131408795073714288317760436689819626\n  4134750069719405651950455051677423979401968998625278900852374458073288670697417739635725450609854234\n  5678985204250732286070942026394841828669256606166544407204577568393932312265407812478316668801803018\n  4225045200535518686848505584530852538497542612057943053533080747750826496088529445572785003441395589\n  3793350511840302252987061629150596422599960058564895723365317986913669699442786657891252568462604147\n  9811086568557173907213307893310852590333311371858772870349262790271567329168662716674908199318258316\n  6832828500157570780161193169221931514754937755159804654092839991094937420103717085608605881785449005\n  7041041360404351376424689981526806092554011234653295043491805374773561666671046929830956789203164820\n  6393173922124840551203478063211131681337322406321645541558823784609194273808850283831236226654974430\n  0558099898299574258432353764298631465635055283560477090757473282636770439630979234656297949344566413\n  9608514643713039321367742124709044527215406879215426306425972602920189946552981151426126049007638671\n  4173023572727683904155972345066669386646058829201247114417883178223482153389187605836327618181943322\n  7695553112581904847517462905620013468996440716198232054347184611020511315550930226825107491990149608\n  1785626051088590365847451503763849151340003295163991062192405572830081035217619796168322139816924083\n  5763955621165712611219290508716325525855864961663825419359148218187619592329205699550637645818268557\n  5221152787011802994335467415362762077497854054133303136335423682410108464763749063885279841490076464\n  6976485400947963589549754614481376369705916356998368119875250547930693532075707667801484477014247162\n  4190816682249007420711186488154772891718653596776539579933503342728214605416964960098470697958559264\n  3042870363664713071314782330611576419913222420646099898830762685836055527409904784676107604241784215\n  0628517557352999647862552954283674298706645794337580101407402116186144843297657442634285287047785563\n  0830963143527878304194501970294657577773281674685808745393160393725331589928057943463140873586086177\n  8826334927746151184911655130681846713677348823341085136403947939208876886336339461382358344794081569\n  6109142938773471389342377361910964605642444747790820760496602713561689541064448321365980829389097296\n  1891211834291490616389638610693752089534688398334446718982124347807238740745769755450743684674713502\n  4858818399665568196344528811941833172636825050611864900394125520574571203603557802514190435267183721\n  9213848299058032246958424323158984432510396544353505354322921674704077861468485976255744615351188003\n  1430569954927847167454497269761283933251838197222328360707522781292813010656941262948730634268837338\n  1817421706086475482763942423914027532180429519034116351704698074233515560578575624509992532017874996\n  3664047347703898558730650760387099773184312810989789882085435595509432539023718952168202334424557257\n  5307879263398550901645594237339662522335164875058955694217297244895998825089232112034795894154654603\n  0378786175915716613988693268737496847305496532937821475648105793808285300532447080506569294223400109\n  5934829461453907889066162640215013073533003319207456372637707709993999228862122432488020626348508885\n  3036010723436890136064275814252839878594917997961121963797576519245218670960880921371119775000878159\n  3043072934488393095757415924137528597779729189345385050803831986774590025186579172370808574164297153\n  8078840607130686803619824197157747638950725346840456919275953193722370222901558006560760473854735990\n  4477996748749969769427137668695533195125337764098587096683863263926164945608684140374568420719405950\n  7017430354691821509004664939985517413893851975731215682616228622318810967297476060130283311937161140\n  8747270676255856777511995666748615196491297019331808499410961813929649278936090212535443327375064260\n  6242994120327362558244174983450947309453436615907284163193683075719798068231535737155571816122156787\n  9364250138871170232755557793022667858031999308108305763076523320507400139390958079016377176292592837\n  6487479017727412567819055556218050487674699114083997791937654232062337471732470336976335792589151526\n  0315614033321272849194418437150696552087542450598956787961303311646283996346460422090106105779458151\n"
  },
  {
    "path": "Day01-15/Day11/teacher.csv",
    "content": "骆昊,38,叫兽\n狄仁杰,25,砖家\n"
  },
  {
    "path": "Day01-15/Day11/文件和异常.md",
    "content": "## 文件和异常\n\n在实际开发中，常常需要对程序中的数据进行[持久化](https://baike.baidu.com/item/%E6%95%B0%E6%8D%AE%E6%8C%81%E4%B9%85%E5%8C%96)操作，而实现数据持久化最直接简单的方式就是将数据保存到文件中。说到“文件”这个词，可能需要先科普一下关于[文件系统](https://zh.wikipedia.org/wiki/%E6%96%87%E4%BB%B6%E7%B3%BB%E7%BB%9F)的知识，对于这个概念，维基百科上给出了很好的诠释，这里不再浪费笔墨。\n\n在Python中实现文件的读写操作其实非常简单，通过Python内置的`open`函数，我们可以指定文件名、操作模式、编码信息等来获得操作文件的对象，接下来就可以对文件进行读写操作了。这里所说的操作模式是指要打开什么样的文件（字符文件还是二进制文件）以及做什么样的操作（读、写还是追加），具体的如下表所示。\n\n| 操作模式 | 具体含义                         |\n| -------- | -------------------------------- |\n| `'r'`    | 读取 （默认）                    |\n| `'w'`    | 写入（会先截断之前的内容）       |\n| `'x'`    | 写入，如果文件已经存在会产生异常 |\n| `'a'`    | 追加，将内容写入到已有文件的末尾 |\n| `'b'`    | 二进制模式                       |\n| `'t'`    | 文本模式（默认）                 |\n| `'+'`    | 更新（既可以读又可以写）         |\n\n下面这张图来自于[菜鸟教程](http://www.runoob.com)网站，它展示了如果根据应用程序的需要来设置操作模式。\n\n![](./res/file-open-mode.png)\n\n### 读写文本文件\n\n读取文本文件时，需要在使用`open`函数时指定好带路径的文件名（可以使用相对路径或绝对路径）并将文件模式设置为`'r'`（如果不指定，默认值也是`'r'`），然后通过`encoding`参数指定编码（如果不指定，默认值是None，那么在读取文件时使用的是操作系统默认的编码），如果不能保证保存文件时使用的编码方式与encoding参数指定的编码方式是一致的，那么就可能因无法解码字符而导致读取失败。下面的例子演示了如何读取一个纯文本文件。\n\n```Python\ndef main():\n\tf = open('致橡树.txt', 'r', encoding='utf-8')\n\tprint(f.read())\n\tf.close()\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n请注意上面的代码，如果`open`函数指定的文件并不存在或者无法打开，那么将引发异常状况导致程序崩溃。为了让代码有一定的健壮性和容错性，我们可以使用Python的异常机制对可能在运行时发生状况的代码进行适当的处理，如下所示。\n\n```Python\ndef main():\n    f = None\n    try:\n        f = open('致橡树.txt', 'r', encoding='utf-8')\n        print(f.read())\n    except FileNotFoundError:\n        print('无法打开指定的文件!')\n    except LookupError:\n        print('指定了未知的编码!')\n    except UnicodeDecodeError:\n        print('读取文件时解码错误!')\n    finally:\n        if f:\n            f.close()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n在Python中，我们可以将那些在运行时可能会出现状况的代码放在`try`代码块中，在`try`代码块的后面可以跟上一个或多个`except`来捕获可能出现的异常状况。例如在上面读取文件的过程中，文件找不到会引发`FileNotFoundError`，指定了未知的编码会引发`LookupError`，而如果读取文件时无法按指定方式解码会引发`UnicodeDecodeError`，我们在`try`后面跟上了三个`except`分别处理这三种不同的异常状况。最后我们使用`finally`代码块来关闭打开的文件，释放掉程序中获取的外部资源，由于`finally`块的代码不论程序正常还是异常都会执行到（甚至是调用了`sys`模块的`exit`函数退出Python环境，`finally`块都会被执行，因为`exit`函数实质上是引发了`SystemExit`异常），因此我们通常把`finally`块称为“总是执行代码块”，它最适合用来做释放外部资源的操作。如果不愿意在`finally`代码块中关闭文件对象释放资源，也可以使用上下文语法，通过`with`关键字指定文件对象的上下文环境并在离开上下文环境时自动释放文件资源，代码如下所示。\n\n```Python\ndef main():\n    try:\n        with open('致橡树.txt', 'r', encoding='utf-8') as f:\n            print(f.read())\n    except FileNotFoundError:\n        print('无法打开指定的文件!')\n    except LookupError:\n        print('指定了未知的编码!')\n    except UnicodeDecodeError:\n        print('读取文件时解码错误!')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n除了使用文件对象的`read`方法读取文件之外，还可以使用`for-in`循环逐行读取或者用`readlines`方法将文件按行读取到一个列表容器中，代码如下所示。\n\n```Python\nimport time\n\n\ndef main():\n\t# 一次性读取整个文件内容\n\twith open('致橡树.txt', 'r', encoding='utf-8') as f:\n\t\tprint(f.read())\n\n\t# 通过for-in循环逐行读取\n\twith open('致橡树.txt', mode='r') as f:\n\t\tfor line in f:\n\t\t\tprint(line, end='')\n\t\t\ttime.sleep(0.5)\n\tprint()\n\n\t# 读取文件按行读取到列表中\n\twith open('致橡树.txt') as f:\n\t\tlines = f.readlines()\n\tprint(lines)\n\t\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n要将文本信息写入文件文件也非常简单，在使用`open`函数时指定好文件名并将文件模式设置为`'w'`即可。注意如果需要对文件内容进行追加式写入，应该将模式设置为`'a'`。如果要写入的文件不存在会自动创建文件而不是引发异常。下面的例子演示了如何将1~9999直接的素数分别写入三个文件中（1~99之间的素数保存在a.txt中，100~999之间的素数保存在b.txt中，1000~9999之间的素数保存在c.txt中）。\n\n```Python\nfrom math import sqrt\n\n\ndef is_prime(n):\n    \"\"\"判断素数的函数\"\"\"\n    assert n > 0\n    for factor in range(2, int(sqrt(n)) + 1):\n        if n % factor == 0:\n            return False\n    return True if n != 1 else False\n\n\ndef main():\n    filenames = ('a.txt', 'b.txt', 'c.txt')\n    fs_list = []\n    try:\n        for filename in filenames:\n            fs_list.append(open(filename, 'w', encoding='utf-8'))\n        for number in range(1, 10000):\n            if is_prime(number):\n                if number < 100:\n                    fs_list[0].write(str(number) + '\\n')\n                elif number < 1000:\n                    fs_list[1].write(str(number) + '\\n')\n                else:\n                    fs_list[2].write(str(number) + '\\n')\n    except IOError as ex:\n        print(ex)\n        print('写文件时发生错误!')\n    finally:\n        for fs in fs_list:\n            fs.close()\n    print('操作完成!')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n### 读写二进制文件\n\n知道了如何读写文本文件要读写二进制文件也就很简单了，下面的代码实现了复制图片文件的功能。\n\n```Python\ndef main():\n    try:\n        with open('guido.jpg', 'rb') as fs1:\n            data = fs1.read()\n            print(type(data))  # <class 'bytes'>\n        with open('吉多.jpg', 'wb') as fs2:\n            fs2.write(data)\n    except FileNotFoundError as e:\n        print('指定的文件无法打开.')\n    except IOError as e:\n        print('读写文件时出现错误.')\n    print('程序执行结束.')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n### 读写JSON文件\n\n通过上面的讲解，我们已经知道如何将文本数据和二进制数据保存到文件中，那么这里还有一个问题，如果希望把一个列表或者一个字典中的数据保存到文件中又该怎么做呢？答案是将数据以JSON格式进行保存。JSON是“JavaScript Object Notation”的缩写，它本来是JavaScript语言中创建对象的一种字面量语法，现在已经被广泛的应用于跨平台跨语言的数据交换，原因很简单，因为JSON也是纯文本，任何系统任何编程语言处理纯文本都是没有问题的。目前JSON基本上已经取代了XML作为异构系统间交换数据的事实标准。关于JSON的知识，更多的可以参考[JSON的官方网站](http://json.org)，从这个网站也可以了解到每种语言处理JSON数据格式可以使用的工具或三方库，下面是一个JSON的简单例子。\n\n```JSON\n{\n    'name': '骆昊',\n    'age': 38,\n    'qq': 957658,\n    'friends': ['王大锤', '白元芳'],\n    'cars': [\n        {'brand': 'BYD', 'max_speed': 180},\n        {'brand': 'Audi', 'max_speed': 280},\n        {'brand': 'Benz', 'max_speed': 320}\n    ]\n}\n```\n\n可能大家已经注意到了，上面的JSON跟Python中的字典其实是一样一样的，事实上JSON的数据类型和Python的数据类型是很容易找到对应关系的，如下面两张表所示。\n\n| JSON                | Python       |\n| ------------------- | ------------ |\n| object              | dict         |\n| array               | list         |\n| string              | str          |\n| number (int / real) | int / float  |\n| true / false        | True / False |\n| null                | None         |\n\n| Python                                 | JSON         |\n| -------------------------------------- | ------------ |\n| dict                                   | object       |\n| list, tuple                            | array        |\n| str                                    | string       |\n| int, float, int- & float-derived Enums | number       |\n| True / False                           | true / false |\n| None                                   | null         |\n\n我们使用Python中的json模块就可以将字典或列表以JSON格式保存到文件中，代码如下所示。\n\n```Python\nimport json\n\n\ndef main():\n    mydict = {\n        'name': '骆昊',\n        'age': 38,\n        'qq': 957658,\n        'friends': ['王大锤', '白元芳'],\n        'cars': [\n            {'brand': 'BYD', 'max_speed': 180},\n            {'brand': 'Audi', 'max_speed': 280},\n            {'brand': 'Benz', 'max_speed': 320}\n        ]\n    }\n    try:\n        with open('data.json', 'w', encoding='utf-8') as fs:\n            json.dump(mydict, fs)\n    except IOError as e:\n        print(e)\n    print('保存数据完成!')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\njson模块主要有四个比较重要的函数，分别是：\n\n- dump - 将Python对象按照JSON格式序列化到文件中\n- dumps - 将Python对象处理成JSON格式的字符串\n- load - 将文件中的JSON数据反序列化成对象\n- loads - 将字符串的内容反序列化成Python对象\n\n这里出现了两个概念，一个叫序列化，一个叫反序列化。自由的百科全书[维基百科](https://zh.wikipedia.org/)上对这两个概念是这样解释的：“序列化（serialization）在计算机科学的数据处理中，是指将数据结构或对象状态转换为可以存储或传输的形式，这样在需要的时候能够恢复到原先的状态，而且通过序列化的数据重新获取字节时，可以利用这些字节来产生原始对象的副本（拷贝）。与这个过程相反的动作，即从一系列字节中提取数据结构的操作，就是反序列化（deserialization）”。\n\n目前绝大多数网络数据服务（或称之为网络API）都是基于[HTTP协议](https://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%8D%8F%E8%AE%AE)提供JSON格式的数据，关于HTTP协议的相关知识，可以看看阮一峰老师的[《HTTP协议入门》](http://www.ruanyifeng.com/blog/2016/08/http.html)，如果想了解国内的网络数据服务，可以看看[聚合数据](https://www.juhe.cn/)和[阿凡达数据](http://www.avatardata.cn/)等网站，国外的可以看看[{API}Search](http://apis.io/)网站。下面的例子演示了如何使用requests模块（封装得足够好的第三方网络访问模块）访问网络API获取国内新闻，如何通过json模块解析JSON数据并显示新闻标题，这个例子使用了[天行数据](https://www.tianapi.com/)提供的国内新闻数据接口，其中的APIKey需要自己到该网站申请。\n\n```Python\nimport requests\nimport json\n\n\ndef main():\n    resp = requests.get('http://api.tianapi.com/guonei/?key=APIKey&num=10')\n    data_model = json.loads(resp.text)\n    for news in data_model['newslist']:\n        print(news['title'])\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n在Python中要实现序列化和反序列化除了使用json模块之外，还可以使用pickle和shelve模块，但是这两个模块是使用特有的序列化协议来序列化数据，因此序列化后的数据只能被Python识别。关于这两个模块的相关知识可以自己看看网络上的资料。另外，如果要了解更多的关于Python异常机制的知识，可以看看segmentfault上面的文章[《总结：Python中的异常处理》](https://segmentfault.com/a/1190000007736783)，这篇文章不仅介绍了Python中异常机制的使用，还总结了一系列的最佳实践，很值得一读。"
  },
  {
    "path": "Day01-15/Day11/致橡树.txt",
    "content": "我如果爱你\n绝不学攀援的凌霄花\n借你的高枝炫耀自己\n\n我如果爱你\n绝不学痴情的鸟儿\n为绿荫重复单调的歌曲\n"
  },
  {
    "path": "Day01-15/Day12/str1.py",
    "content": "\"\"\"\n\n字符串常用操作\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-19\n\n\"\"\"\n\nimport pyperclip\n\n# 转义字符\nprint('My brother\\'s name is \\'007\\'')\n# 原始字符串\nprint(r'My brother\\'s name is \\'007\\'')\n\nstr = 'hello123world'\nprint('he' in str)\nprint('her' in str)\n# 字符串是否只包含字母\nprint(str.isalpha())\n# 字符串是否只包含字母和数字\nprint(str.isalnum())\n# 字符串是否只包含数字\nprint(str.isdecimal())\n\nprint(str[0:5].isalpha())\nprint(str[5:8].isdecimal())\n\nlist = ['床前明月光', '疑是地上霜', '举头望明月', '低头思故乡']\nprint('-'.join(list))\nsentence = 'You go your way I will go mine'\nwords_list = sentence.split()\nprint(words_list)\nemail = '     jackfrued@126.com          '\nprint(email)\nprint(email.strip())\nprint(email.lstrip())\n\n# 将文本放入系统剪切板中\npyperclip.copy('老虎不发猫你当我病危呀')\n# 从系统剪切板获得文本\n# print(pyperclip.paste())\n"
  },
  {
    "path": "Day01-15/Day12/str2.py",
    "content": "\"\"\"\n\n字符串常用操作 - 实现字符串倒转的方法\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-19\n\n\"\"\"\n\nfrom io import StringIO\n\n\ndef reverse_str1(str):\n\treturn str[::-1]\n\n\ndef reverse_str2(str):\n\tif len(str) <= 1:\n\t\treturn str\n\treturn reverse_str2(str[1:]) + str[0:1]\n\n\ndef reverse_str3(str):\n\t# StringIO对象是Python中的可变字符串\n\t# 不应该使用不变字符串做字符串连接操作 因为会产生很多无用字符串对象\n\trstr = StringIO()\n\tstr_len = len(str)\n\tfor index in range(str_len - 1, -1, -1):\n\t\trstr.write(str[index])\n\treturn rstr.getvalue()\n\n\ndef reverse_str4(str):\n\treturn ''.join(str[index] for index in range(len(str) - 1, -1, -1))\n\n\ndef reverse_str5(str):\n\t# 将字符串处理成列表\n\tstr_list = list(str)\n\tstr_len = len(str)\n\t# 使用zip函数将两个序列合并成一个产生元组的迭代器\n\t# 每次正好可以取到一前一后两个下标来实现元素的交换\n\tfor i, j in zip(range(str_len // 2), range(str_len - 1, str_len // 2, -1)):\n\t\tstr_list[i], str_list[j] = str_list[j], str_list[i]\n\t# 将列表元素连接成字符串\n\treturn ''.join(str_list)\n\n\nif __name__ == '__main__':\n\tstr = 'I love Python'\n\tprint(reverse_str1(str))\n\tprint(str)\n\tprint(reverse_str2(str))\n\tprint(str)\n\tprint(reverse_str3(str))\n\tprint(str)\n\tprint(reverse_str4(str))\n\tprint(str)\n\tprint(reverse_str5(str))\n\tprint(str)\n# 提醒学生注意这是一个面试题: 写出你能想到的实现字符串倒转的代码\n"
  },
  {
    "path": "Day01-15/Day12/test3.py",
    "content": "\"\"\"\n\n验证输入用户名和QQ号是否有效并给出对应的提示信息\n\n要求：\n用户名必须由字母、数字或下划线构成且长度在6~20个字符之间\nQQ号是5~12的数字且首位不能为0\n\n\"\"\"\n\nimport re\n\n\ndef main():\n    username = input('请输入用户名: ')\n    qq = input('请输入QQ号: ')\n    m1 = re.match(r'^[0-9a-zA-Z_]{6,20}$', username)\n    if not m1:\n        print('请输入有效的用户名.')\n    m2 = re.match(r'^[1-9]\\d{4,11}$', qq)\n    if not m2:\n        print('请输入有效的QQ号.')\n    if m1 and m2:\n        print('你输入的信息是有效的!')\n\n\nif __name__ == '__main__':\n    main()\n\n"
  },
  {
    "path": "Day01-15/Day12/test4.py",
    "content": "import re\n\n\ndef main():\n    # 创建正则表达式对象 使用了前瞻和回顾来保证手机号前后不应该出现数字\n    pattern = re.compile(r'(?<=\\D)(1[38]\\d{9}|14[57]\\d{8}|15[0-35-9]\\d{8}|17[678]\\d{8})(?=\\D)')\n    sentence = '''\n    重要的事情说8130123456789遍，我的手机号是13512346789这个靓号，\n    不是15600998765，也是110或119，王大锤的手机号才是15600998765。\n    '''\n    # 查找所有匹配并保存到一个列表中\n    mylist = re.findall(pattern, sentence)\n    print(mylist)\n    print('--------华丽的分隔线--------')\n    # 通过迭代器取出匹配对象并获得匹配的内容\n    for temp in pattern.finditer(sentence):\n        print(temp.group())\n    print('--------华丽的分隔线--------')\n    # 通过search函数指定搜索位置找出所有匹配\n    m = pattern.search(sentence)\n    while m:\n        print(m.group())\n        m = pattern.search(sentence, m.end())\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day12/test5.py",
    "content": "import re\n\n\ndef main():\n    sentence = '你丫是傻叉吗? 我操你大爷的. Fuck you.'\n    purified = re.sub('[操肏艹草曹]|fuck|shit|傻[比屄逼叉缺吊屌]|煞笔',\n                      '*', sentence, flags=re.IGNORECASE)\n    print(purified)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day12/字符串和正则表达式.md",
    "content": "## 使用正则表达式\n\n### 正则表达式相关知识\n\n在编写处理字符串的程序或网页时，经常会有查找符合某些复杂规则的字符串的需要，正则表达式就是用于描述这些规则的工具，换句话说正则表达式是一种工具，它定义了字符串的匹配模式（如何检查一个字符串是否有跟某种模式匹配的部分或者从一个字符串中将与模式匹配的部分提取出来或者替换掉）。如果你在Windows操作系统中使用过文件查找并且在指定文件名时使用过通配符（\\*和?），那么正则表达式也是与之类似的用来进行文本匹配的工具，只不过比起通配符正则表达式更强大，它能更精确地描述你的需求（当然你付出的代价是书写一个正则表达式比打出一个通配符要复杂得多，要知道任何给你带来好处的东西都是有代价的，就如同学习一门编程语言一样），比如你可以编写一个正则表达式，用来查找所有以0开头，后面跟着2-3个数字，然后是一个连字号“-”，最后是7或8位数字的字符串（像028-12345678或0813-7654321），这不就是国内的座机号码吗。最初计算机是为了做数学运算而诞生的，处理的信息基本上都是数值，而今天我们在日常工作中处理的信息基本上都是文本数据，我们希望计算机能够识别和处理符合某些模式的文本，正则表达式就显得非常重要了。今天几乎所有的编程语言都提供了对正则表达式操作的支持，Python通过标准库中的re模块来支持正则表达式操作。\n\n我们可以考虑下面一个问题：我们从某个地方（可能是一个文本文件，也可能是网络上的一则新闻）获得了一个字符串，希望在字符串中找出手机号和座机号。当然我们可以设定手机号是11位的数字（注意并不是随机的11位数字，因为你没有见过“25012345678”这样的手机号吧）而座机号跟上一段中描述的模式相同，如果不使用正则表达式要完成这个任务就会很麻烦。\n\n关于正则表达式的相关知识，大家可以阅读一篇非常有名的博客叫[《正则表达式30分钟入门教程》](https://deerchao.net/tutorials/regex/regex.htm)，读完这篇文章后你就可以看懂下面的表格，这是我们对正则表达式中的一些基本符号进行的扼要总结。\n\n| 符号               | 解释                                      | 示例             | 说明                                               |\n| ------------------ | ----------------------------------------- | ---------------- | -------------------------------------------------- |\n| .                  | 匹配任意字符                              | b.t              | 可以匹配bat / but / b#t / b1t等                    |\n| \\\\w                | 匹配字母/数字/下划线                      | b\\\\wt            | 可以匹配bat / b1t / b_t等<br>但不能匹配b#t         |\n| \\\\s                | 匹配空白字符（包括\\r、\\n、\\t等）          | love\\\\syou       | 可以匹配love you                                   |\n| \\\\d                | 匹配数字                                  | \\\\d\\\\d           | 可以匹配01 / 23 / 99等                             |\n| \\\\b                | 匹配单词的边界                            | \\\\bThe\\\\b        |                                                    |\n| ^                  | 匹配字符串的开始                          | ^The             | 可以匹配The开头的字符串                            |\n| $                  | 匹配字符串的结束                          | .exe$            | 可以匹配.exe结尾的字符串                           |\n| \\\\W                 | 匹配非字母/数字/下划线                    | b\\\\Wt            | 可以匹配b#t / b@t等<br>但不能匹配but / b1t / b_t等 |\n| \\\\S                 | 匹配非空白字符                            | love\\\\Syou       | 可以匹配love#you等<br>但不能匹配love you           |\n| \\\\D                 | 匹配非数字                                | \\\\d\\\\D           | 可以匹配9a / 3# / 0F等                             |\n| \\\\B                 | 匹配非单词边界                            | \\\\Bio\\\\B         |                                                    |\n| []                 | 匹配来自字符集的任意单一字符              | [aeiou]          | 可以匹配任一元音字母字符                           |\n| [^]                | 匹配不在字符集中的任意单一字符            | [^aeiou]         | 可以匹配任一非元音字母字符                         |\n| *                  | 匹配0次或多次                             | \\\\w*             |                                                    |\n| +                  | 匹配1次或多次                             | \\\\w+             |                                                    |\n| ?                  | 匹配0次或1次                              | \\\\w?             |                                                    |\n| {N}                | 匹配N次                                   | \\\\w{3}            |                                                    |\n| {M,}               | 匹配至少M次                               | \\\\w{3,}           |                                                    |\n| {M,N}              | 匹配至少M次至多N次                        | \\\\w{3,6}          |                                                    |\n| \\|                 | 分支                                      | foo\\|bar         | 可以匹配foo或者bar                                 |\n| (?#)               | 注释                                      |                  |                                                    |\n| (exp)              | 匹配exp并捕获到自动命名的组中             |                  |                                                    |\n| (?&lt;name&gt;exp) | 匹配exp并捕获到名为name的组中             |                  |                                                    |\n| (?:exp)            | 匹配exp但是不捕获匹配的文本               |                  |                                                    |\n| (?=exp)            | 匹配exp前面的位置                         | \\\\b\\\\w+(?=ing)     | 可以匹配I'm dancing中的danc                        |\n| (?<=exp)           | 匹配exp后面的位置                         | (?<=\\\\bdanc)\\\\w+\\\\b | 可以匹配I love dancing and reading中的第一个ing    |\n| (?!exp)            | 匹配后面不是exp的位置                     |                  |                                                    |\n| (?<!exp)           | 匹配前面不是exp的位置                     |                  |                                                    |\n| *?                 | 重复任意次，但尽可能少重复 | a.\\*b<br>a.\\*?b | 将正则表达式应用于aabab，前者会匹配整个字符串aabab，后者会匹配aab和ab两个字符串 |\n| +?                 | 重复1次或多次，但尽可能少重复 |                  |                                                    |\n| ??                 | 重复0次或1次，但尽可能少重复 |                  |                                                    |\n| {M,N}?             | 重复M到N次，但尽可能少重复 |                  |                                                    |\n| {M,}?              | 重复M次以上，但尽可能少重复 |                  |                                                    |\n\n> **说明：**如果需要匹配的字符是正则表达式中的特殊字符，那么可以使用\\\\进行转义处理，例如想匹配小数点可以写成\\\\.就可以了，因为直接写.会匹配任意字符；同理，想匹配圆括号必须写成\\\\(和\\\\)，否则圆括号被视为正则表达式中的分组。\n\n### Python对正则表达式的支持\n\nPython提供了re模块来支持正则表达式相关操作，下面是re模块中的核心函数。\n\n| 函数                                         | 说明                                                         |\n| -------------------------------------------- | ------------------------------------------------------------ |\n| compile(pattern, flags=0)                    | 编译正则表达式返回正则表达式对象                             |\n| match(pattern, string, flags=0)              | 用正则表达式匹配字符串 成功返回匹配对象 否则返回None         |\n| search(pattern, string, flags=0)             | 搜索字符串中第一次出现正则表达式的模式 成功返回匹配对象 否则返回None |\n| split(pattern, string, maxsplit=0, flags=0)  | 用正则表达式指定的模式分隔符拆分字符串 返回列表              |\n| sub(pattern, repl, string, count=0, flags=0) | 用指定的字符串替换原字符串中与正则表达式匹配的模式 可以用count指定替换的次数 |\n| fullmatch(pattern, string, flags=0)          | match函数的完全匹配（从字符串开头到结尾）版本                |\n| findall(pattern, string, flags=0)            | 查找字符串所有与正则表达式匹配的模式 返回字符串的列表        |\n| finditer(pattern, string, flags=0)           | 查找字符串所有与正则表达式匹配的模式 返回一个迭代器          |\n| purge()                                      | 清除隐式编译的正则表达式的缓存                               |\n| re.I / re.IGNORECASE                         | 忽略大小写匹配标记                                           |\n| re.M / re.MULTILINE                          | 多行匹配标记                                                 |\n\n> **说明：**上面提到的re模块中的这些函数，实际开发中也可以用正则表达式对象的方法替代对这些函数的使用，如果一个正则表达式需要重复的使用，那么先通过compile函数编译正则表达式并创建出正则表达式对象无疑是更为明智的选择。\n\n下面我们通过一系列的例子来告诉大家在Python中如何使用正则表达式。\n\n#### 例子1：验证输入用户名和QQ号是否有效并给出对应的提示信息。\n\n```Python\n\"\"\"\n\n验证输入用户名和QQ号是否有效并给出对应的提示信息\n\n要求：\n用户名必须由字母、数字或下划线构成且长度在6~20个字符之间\nQQ号是5~12的数字且首位不能为0\n\n\"\"\"\n\nimport re\n\n\ndef main():\n    username = input('请输入用户名: ')\n    qq = input('请输入QQ号: ')\n    # match函数的第一个参数是正则表达式字符串或正则表达式对象\n    # 第二个参数是要跟正则表达式做匹配的字符串对象\n    m1 = re.match(r'^[0-9a-zA-Z_]{6,20}$', username)\n    if not m1:\n        print('请输入有效的用户名.')\n    m2 = re.match(r'^[1-9]\\d{4,11}$', qq)\n    if not m2:\n        print('请输入有效的QQ号.')\n    if m1 and m2:\n        print('你输入的信息是有效的!')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n> **提示**：上面在书写正则表达式时使用了“原始字符串”的写法（在字符串前面加上了r），所谓“原始字符串”就是字符串中的每个字符都是它原始的意义，说得更直接一点就是字符串中没有所谓的转义字符啦。因为正则表达式中有很多元字符和需要进行转义的地方，如果不使用原始字符串就需要将反斜杠写作\\\\\\\\，例如表示数字的\\\\d得书写成\\\\\\\\d，这样不仅写起来不方便，阅读的时候也会很吃力。\n\n#### 例子2：从一段文字中提取出国内手机号码。\n\n下面这张图是截止到2017年底，国内三家运营商推出的手机号段。\n\n![](./res/tel-start-number.png)\n\n```Python\nimport re\n\n\ndef main():\n    # 创建正则表达式对象 使用了前瞻和回顾来保证手机号前后不应该出现数字\n    pattern = re.compile(r'(?<=\\D)1[34578]\\d{9}(?=\\D)')\n    sentence = '''\n    重要的事情说8130123456789遍，我的手机号是13512346789这个靓号，\n    不是15600998765，也是110或119，王大锤的手机号才是15600998765。\n    '''\n    # 查找所有匹配并保存到一个列表中\n    mylist = re.findall(pattern, sentence)\n    print(mylist)\n    print('--------华丽的分隔线--------')\n    # 通过迭代器取出匹配对象并获得匹配的内容\n    for temp in pattern.finditer(sentence):\n        print(temp.group())\n    print('--------华丽的分隔线--------')\n    # 通过search函数指定搜索位置找出所有匹配\n    m = pattern.search(sentence)\n    while m:\n        print(m.group())\n        m = pattern.search(sentence, m.end())\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n> **说明**：上面匹配国内手机号的正则表达式并不够好，因为像14开头的号码只有145或147，而上面的正则表达式并没有考虑这种情况，要匹配国内手机号，更好的正则表达式的写法是：`(?<=\\D)(1[38]\\d{9}|14[57]\\d{8}|15[0-35-9]\\d{8}|17[678]\\d{8})(?=\\D)`，国内最近好像有19和16开头的手机号了，但是这个暂时不在我们考虑之列。\n\n#### 例子3：替换字符串中的不良内容\n\n```Python\nimport re\n\n\ndef main():\n    sentence = '你丫是傻叉吗? 我操你大爷的. Fuck you.'\n    purified = re.sub('[操肏艹草曹]|fuck|shit|傻[比屄逼叉缺吊屌]|煞笔',\n                      '*', sentence, flags=re.IGNORECASE)\n    print(purified)  # 你丫是*吗? 我*你大爷的. * you.\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n> **说明**：re模块的正则表达式相关函数中都有一个flags参数，它代表了正则表达式的匹配标记，可以通过该标记来指定匹配时是否忽略大小写、是否进行多行匹配、是否显示调试信息等。如果需要为flags参数指定多个值，可以使用[按位或运算符](http://www.runoob.com/python/python-operators.html#ysf5)进行叠加，如`flags=re.I | re.M`。\n\n#### 例子4：拆分长字符串\n\n```Python\nimport re\n\n\ndef main():\n    poem = '窗前明月光，疑是地上霜。举头望明月，低头思故乡。'\n    sentence_list = re.split(r'[，。, .]', poem)\n    while '' in sentence_list:\n        sentence_list.remove('')\n    print(sentence_list)  # ['窗前明月光', '疑是地上霜', '举头望明月', '低头思故乡']\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n### 后话\n\n如果要从事爬虫类应用的开发，那么正则表达式一定是一个非常好的助手，因为它可以帮助我们迅速的从网页代码中发现某种我们指定的模式并提取出我们需要的信息，当然对于初学者来收，要编写一个正确的适当的正则表达式可能并不是一件容易的事情（当然有些常用的正则表达式可以直接在网上找找），所以实际开发爬虫应用的时候，有很多人会选择[Beautiful Soup](https://www.crummy.com/software/BeautifulSoup/)或[Lxml](http://lxml.de/)来进行匹配和信息的提取，前者简单方便但是性能较差，后者既好用性能也好，但是安装稍嫌麻烦，这些内容我们会在后期的爬虫专题中为大家介绍。"
  },
  {
    "path": "Day01-15/Day13/asyncio1.py",
    "content": "\"\"\"\n\n异步I/O操作 - asyncio模块\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-21\n\n\"\"\"\n\nimport asyncio\nimport threading\n# import time\n\n\n@asyncio.coroutine\ndef hello():\n\tprint('%s: hello, world!' % threading.current_thread())\n\t# 休眠不会阻塞主线程因为使用了异步I/O操作\n\t# 注意有yield from才会等待休眠操作执行完成\n\tyield from asyncio.sleep(2)\n\t# asyncio.sleep(1)\n\t# time.sleep(1)\n\tprint('%s: goodbye, world!' % threading.current_thread())\n\n\nloop = asyncio.get_event_loop()\ntasks = [hello(), hello()]\n# 等待两个异步I/O操作执行结束\nloop.run_until_complete(asyncio.wait(tasks))\nprint('game over!')\nloop.close()\n"
  },
  {
    "path": "Day01-15/Day13/asyncio2.py",
    "content": "\"\"\"\n\n异步I/O操作 - async和await\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-21\n\n\"\"\"\n\nimport asyncio\nimport threading\n\n\n# 通过async修饰的函数不再是普通函数而是一个协程\n# 注意async和await将在Python 3.7中作为关键字出现\nasync def hello():\n\tprint('%s: hello, world!' % threading.current_thread())\n\tawait asyncio.sleep(2)\n\tprint('%s: goodbye, world!' % threading.current_thread())\n\n\nloop = asyncio.get_event_loop()\ntasks = [hello(), hello()]\n# 等待两个异步I/O操作执行结束\nloop.run_until_complete(asyncio.wait(tasks))\nloop.close()\n"
  },
  {
    "path": "Day01-15/Day13/asyncio3.py",
    "content": "\"\"\"\n\n异步I/O操作 - asyncio模块\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-21\n\n\"\"\"\n\nimport asyncio\n\n\nasync def wget(host):\n\tprint('wget %s...' % host)\n\tconnect = asyncio.open_connection(host, 80)\n\t# 异步方式等待连接结果\n\treader, writer = await connect\n\theader = 'GET / HTTP/1.0\\r\\nHost: %s\\r\\n\\r\\n' % host\n\twriter.write(header.encode('utf-8'))\n\t# 异步I/O方式执行写操作\n\tawait writer.drain()\n\twhile True:\n\t\t# 异步I/O方式执行读操作\n\t\tline = await reader.readline()\n\t\tif line == b'\\r\\n':\n\t\t\tbreak\n\t\tprint('%s header > %s' % (host, line.decode('utf-8').rstrip()))\n\twriter.close()\n\n\nloop = asyncio.get_event_loop()\n# 通过生成式语法创建一个装了三个协程的列表\nhosts_list = ['www.sina.com.cn', 'www.sohu.com', 'www.163.com']\ntasks = [wget(host) for host in hosts_list]\n# 下面的方法将异步I/O操作放入EventLoop直到执行完毕\nloop.run_until_complete(asyncio.wait(tasks))\nloop.close()\n"
  },
  {
    "path": "Day01-15/Day13/coroutine1.py",
    "content": "\"\"\"\n\n使用协程 - 模拟快递中心派发快递\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-21\n\n\"\"\"\n\nfrom time import sleep\nfrom random import random\n\n\ndef build_deliver_man(man_id):\n\ttotal = 0\n\twhile True:\n\t\ttotal += 1\n\t\tprint('%d号快递员准备接今天的第%d单.' % (man_id, total))\n\t\tpkg = yield\n\t\tprint('%d号快递员收到编号为%s的包裹.' % (man_id, pkg))\n\t\tsleep(random() * 3)\n\n\ndef package_center(deliver_man, max_per_day):\n\tnum = 1\n\tdeliver_man.send(None)\n\t# next(deliver_man)\n\twhile num <= max_per_day:\n\t\tpackage_id = 'PKG-%d' % num\n\t\tdeliver_man.send(package_id)\n\t\tnum += 1\n\t\tsleep(0.1)\n\tdeliver_man.close()\n\tprint('今天的包裹派送完毕!')\n\n\ndm = build_deliver_man(1)\npackage_center(dm, 10)\n\n# 两个函数虽然没有调用关系但是创建快递员的函数作为一个协程协助了快递中心函数完成任务\n# 想一想如果有多个快递员的时候应该如何处理\n"
  },
  {
    "path": "Day01-15/Day13/coroutine2.py",
    "content": "\"\"\"\n\n使用协程 - 查看协程的状态\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-21\n\n\"\"\"\n\nfrom time import sleep\nfrom inspect import getgeneratorstate\n\n\ndef build_deliver_man(man_id):\n\ttotal = 0\n\twhile True:\n\t\ttotal += 1\n\t\tprint('%d号快递员准备接今天的第%d单.' % (man_id, total))\n\t\tpkg = yield\n\t\tprint('%d号快递员收到编号为%s的包裹.' % (man_id, pkg))\n\t\tsleep(0.5)\n\n\ndef package_center(deliver_man, max_per_day):\n\tnum = 1\n\t# 创建状态(GEN_CREATED) - 等待开始执行\n\tprint(getgeneratorstate(deliver_man))\n\tdeliver_man.send(None)\n\t# 挂起状态(GEN_SUSPENDED) - 在yield表达式处暂停\n\tprint(getgeneratorstate(deliver_man))\n\t# next(deliver_man)\n\twhile num <= max_per_day:\n\t\tpackage_id = 'PKG-%d' % num\n\t\tdeliver_man.send(package_id)\n\t\tnum += 1\n\tdeliver_man.close()\n\t# 结束状态(GEN_CLOSED) - 执行完毕\n\tprint(getgeneratorstate(deliver_man))\n\tprint('今天的包裹派送完毕!')\n\n\ndm = build_deliver_man(1)\npackage_center(dm, 10)\n"
  },
  {
    "path": "Day01-15/Day13/generator1.py",
    "content": "\"\"\"\n\n生成器 - 生成器语法\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-21\n\n\"\"\"\n\nseq = [x * x for x in range(10)]\nprint(seq)\n\ngen = (x * x for x in range(10))\nprint(gen)\nfor x in gen:\n\tprint(x)\n\nnum = 10\ngen = (x ** y for x, y in zip(range(1, num), range(num - 1, 0, -1)))\nprint(gen)\nn = 1\nwhile n < num:\n\tprint(next(gen))\n\tn += 1\n"
  },
  {
    "path": "Day01-15/Day13/generator2.py",
    "content": "\"\"\"\n\n生成器 - 使用yield关键字\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-21\n\n\"\"\"\n\n\ndef fib(num):\n\tn, a, b = 0, 0, 1\n\twhile n < num:\n\t\tyield b\n\t\ta, b = b, a + b\n\t\tn += 1\n\n\nfor x in fib(20):\n\tprint(x)\n"
  },
  {
    "path": "Day01-15/Day13/multiprocess1.py",
    "content": "\"\"\"\n\n使用Process类创建多个进程\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\n# 通过下面程序的执行结果可以证实 父进程在创建子进程时复制了进程及其数据结构\n# 每个进程都有自己独立的内存空间 所以进程之间共享数据只能通过IPC的方式\n\n\nfrom multiprocessing import Process, Queue\nfrom time import sleep\n\n\ndef sub_task(string, q):\n    number = q.get()\n    while number:\n        print('%d: %s' % (number, string))\n        sleep(0.001)\n        number = q.get()\n\n\ndef main():\n    q = Queue(10)\n    for number in range(1, 11):\n        q.put(number)\n    Process(target=sub_task, args=('Ping', q)).start()\n    Process(target=sub_task, args=('Pong', q)).start()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day13/multiprocess2.py",
    "content": "\"\"\"\n\n实现进程间的通信\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nimport multiprocessing\nimport os\n\n\ndef sub_task(queue):\n\tprint('子进程进程号:', os.getpid())\n\tcounter = 0\n\twhile counter < 1000:\n\t\tqueue.put('Pong')\n\t\tcounter += 1\n\n\nif __name__ == '__main__':\n\tprint('当前进程号:', os.getpid())\n\tqueue = multiprocessing.Queue()\n\tp = multiprocessing.Process(target=sub_task, args=(queue,))\n\tp.start()\n\tcounter = 0\n\twhile counter < 1000:\n\t\tqueue.put('Ping')\n\t\tcounter += 1\n\tp.join()\n\tprint('子任务已经完成.')\n\tfor _ in range(2000):\n\t\tprint(queue.get(), end='')\n"
  },
  {
    "path": "Day01-15/Day13/multiprocess3.py",
    "content": "\"\"\"\n\n创建进程调用其他程序\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nimport subprocess\nimport sys\n\ndef main():\n\t# 通过sys.argv获取命令行参数\n\tif len(sys.argv) > 1:\n\t\t# 第一个命令行参数是程序本身所以从第二个开始取\n\t\tfor index in range(1, len(sys.argv)):\n\t\t\ttry:\n\t\t\t\t# 通过subprocess模块的call函数启动子进程\n\t\t\t\tstatus = subprocess.call(sys.argv[index])\n\t\t\texcept FileNotFoundError:\n\t\t\t\tprint('不能执行%s命令' % sys.argv[index])\n\telse:\n\t\tprint('请使用命令行参数指定要执行的进程')\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day13/multiprocess4.py",
    "content": "from time import time\n\n\ndef main():\n    total = 0\n    number_list = [x for x in range(1, 100000001)]\n    start = time()\n    for number in number_list:\n        total += number\n    print(total)\n    end = time()\n    print('Execution time: %.3fs' % (end - start))\n\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "Day01-15/Day13/multithread1.py",
    "content": "\"\"\"\n\n使用多线程的情况 - 模拟多个下载任务\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nfrom random import randint\nfrom time import time, sleep\nimport atexit\nimport _thread\n\n\ndef download_task(filename):\n\tprint('开始下载%s...' % filename)\n\ttime_to_download = randint(5, 10)\n\tprint('剩余时间%d秒.' % time_to_download)\n\tsleep(time_to_download)\n\tprint('%s下载完成!' % filename)\n\n\ndef shutdown_hook(start):\n\tend = time()\n\tprint('总共耗费了%.3f秒.' % (end - start))\n\n\ndef main():\n\tstart = time()\n\t# 将多个下载任务放到多个线程中执行\n\tthread1 = _thread.start_new_thread(download_task, ('Python从入门到住院.pdf',))\n\tthread2 = _thread.start_new_thread(download_task, ('Peking Hot.avi',))\n\t# 注册关机钩子在程序执行结束前计算执行时间\n\tatexit.register(shutdown_hook, start)\n\n\nif __name__ == '__main__':\n\tmain()\n\n# 执行这里的代码会引发致命错误(不要被这个词吓到) 因为主线程结束后下载线程再想执行就会出问题\n# 需要说明一下 由于_thread模块属于比较底层的线程操作而且不支持守护线程的概念\n# 在实际开发中会有诸多不便 因此我们推荐使用threading模块提供的高级操作进行多线程编程\n"
  },
  {
    "path": "Day01-15/Day13/multithread2.py",
    "content": "\"\"\"\n\n使用多线程的情况 - 模拟多个下载任务\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nfrom random import randint\nfrom threading import Thread\nfrom time import time, sleep\n\n\ndef download_task(filename):\n\tprint('开始下载%s...' % filename)\n\ttime_to_download = randint(5, 10)\n\tsleep(time_to_download)\n\tprint('%s下载完成! 耗费了%d秒' % (filename, time_to_download))\n\n\ndef main():\n\tstart = time()\n\tthread1 = Thread(target=download_task, args=('Python从入门到住院.pdf',))\n\tthread1.start()\n\tthread2 = Thread(target=download_task, args=('Peking Hot.avi',))\n\tthread2.start()\n\tthread1.join()\n\tthread2.join()\n\tend = time()\n\tprint('总共耗费了%.3f秒' % (end - start))\n\n\nif __name__ == '__main__':\n\tmain()\n"
  },
  {
    "path": "Day01-15/Day13/multithread3.py",
    "content": "\"\"\"\n\n使用多线程的情况 - 模拟多个下载任务\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nfrom random import randint\nfrom time import time, sleep\nimport threading\n\n\nclass DownloadTask(threading.Thread):\n\n\tdef __init__(self, filename):\n\t\tsuper().__init__()\n\t\tself._filename = filename\n\n\tdef run(self):\n\t\tprint('开始下载%s...' % self._filename)\n\t\ttime_to_download = randint(5, 10)\n\t\tprint('剩余时间%d秒.' % time_to_download)\n\t\tsleep(time_to_download)\n\t\tprint('%s下载完成!' % self._filename)\n\n\ndef main():\n\tstart = time()\n\t# 将多个下载任务放到多个线程中执行\n\t# 通过自定义的线程类创建线程对象 线程启动后会回调执行run方法\n\tthread1 = DownloadTask('Python从入门到住院.pdf')\n\tthread1.start()\n\tthread2 = DownloadTask('Peking Hot.avi')\n\tthread2.start()\n\tthread1.join()\n\tthread2.join()\n\tend = time()\n\tprint('总共耗费了%.3f秒' % (end - start))\n\n\nif __name__ == '__main__':\n\tmain()\n\n# 请注意通过threading.Thread创建的线程默认是非守护线程\n"
  },
  {
    "path": "Day01-15/Day13/multithread4.py",
    "content": "\"\"\"\n\n使用多线程的情况 - 耗时间的任务在独立的线程中执行\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nimport time\nimport tkinter\nimport tkinter.messagebox\nfrom threading import Thread\n\n\ndef main():\n\n    class DownloadTaskHandler(Thread):\n\n        def run(self):\n            # 模拟下载任务需要花费10秒钟时间\n            time.sleep(10)\n            tkinter.messagebox.showinfo('提示', '下载完成!')\n            # 启用下载按钮\n            button1.config(state=tkinter.NORMAL)\n\n    def download():\n        # 禁用下载按钮\n        button1.config(state=tkinter.DISABLED)\n        # 通过daemon参数将线程设置为守护线程(主程序退出就不再保留执行)\n        DownloadTaskHandler(daemon=True).start()\n\n    def show_about():\n        tkinter.messagebox.showinfo('关于', '作者: 骆昊(v1.0)')\n\n    top = tkinter.Tk()\n    top.title('单线程')\n    top.geometry('200x150')\n    top.wm_attributes('-topmost', 1)\n\n    panel = tkinter.Frame(top)\n    button1 = tkinter.Button(panel, text='下载', command=download)\n    button1.pack(side='left')\n    button2 = tkinter.Button(panel, text='关于', command=show_about)\n    button2.pack(side='right')\n    panel.pack(side='bottom')\n\n    tkinter.mainloop()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day13/multithread5.py",
    "content": "\"\"\"\n\n多个线程共享数据 - 没有锁的情况\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nfrom time import sleep\nfrom threading import Thread, Lock\n\n\nclass Account(object):\n\n    def __init__(self):\n        self._balance = 0\n        self._lock = Lock()\n\n    def deposit(self, money):\n        # 先获取锁才能执行后续的代码\n        self._lock.acquire()\n        try:\n            new_balance = self._balance + money\n            sleep(0.01)\n            self._balance = new_balance\n        finally:\n            # 这段代码放在finally中保证释放锁的操作一定要执行\n            self._lock.release()\n\n    @property\n    def balance(self):\n        return self._balance\n\n\nclass AddMoneyThread(Thread):\n\n    def __init__(self, account, money):\n        super().__init__()\n        self._account = account\n        self._money = money\n\n    def run(self):\n        self._account.deposit(self._money)\n\n\ndef main():\n    account = Account()\n    threads = []\n    # 创建100个存款的线程向同一个账户中存钱\n    for _ in range(100):\n        t = AddMoneyThread(account, 1)\n        threads.append(t)\n        t.start()\n    # 等所有存款的线程都执行完毕∫\n    for t in threads:\n        t.join()\n    print('账户余额为: ￥%d元' % account.balance)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day13/multithread6.py",
    "content": "\"\"\"\n\n多个线程共享数据 - 有锁的情况\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nimport time\nimport threading\n\n\nclass Account(object):\n\n\tdef __init__(self):\n\t\tself._balance = 0\n\t\tself._lock = threading.Lock()\n\n\tdef deposit(self, money):\n\t\t# 获得锁后代码才能继续执行\n\t\tself._lock.acquire()\n\t\ttry:\n\t\t\tnew_balance = self._balance + money\n\t\t\ttime.sleep(0.01)\n\t\t\tself._balance = new_balance\n\t\tfinally:\n\t\t\t# 操作完成后一定要记着释放锁\n\t\t\tself._lock.release()\n\n\t@property\n\tdef balance(self):\n\t\treturn self._balance\n\n\nif __name__ == '__main__':\n\taccount = Account()\n\t# 创建100个存款的线程向同一个账户中存钱\n\tfor _ in range(100):\n\t\tthreading.Thread(target=account.deposit, args=(1,)).start()\n\t# 等所有存款的线程都执行完毕\n\ttime.sleep(2)\n\tprint('账户余额为: ￥%d元' % account.balance)\n\n# 想一想结果为什么不是我们期望的100元\n"
  },
  {
    "path": "Day01-15/Day13/singlethread1.py",
    "content": "\"\"\"\n\n不使用多线程的情况 - 模拟多个下载任务\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nfrom random import randint\nfrom time import time, sleep\n\n\ndef download_task(filename):\n    print('开始下载%s...' % filename)\n    time_to_download = randint(5, 10)\n    sleep(time_to_download)\n    print('下载完成! 耗费了%d秒' % time_to_download)\n\n\ndef main():\n    start = time()\n    download_task('Python从入门到住院.pdf')\n    download_task('Peking Hot.avi')\n    end = time()\n    print('总共耗费了%.2f秒.' % (end - start))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day13/singlethread2.py",
    "content": "\"\"\"\n\n不使用多线程的情况 - 耗时间的任务阻塞主事件循环\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-20\n\n\"\"\"\n\nimport time\nimport tkinter\nimport tkinter.messagebox\n\n\ndef download():\n    # 模拟下载任务需要花费10秒钟时间\n    time.sleep(10)\n    tkinter.messagebox.showinfo('提示', '下载完成!')\n\n\ndef show_about():\n    tkinter.messagebox.showinfo('关于', '作者: 骆昊(v1.0)')\n\n\ndef main():\n    top = tkinter.Tk()\n    top.title('单线程')\n    top.geometry('200x150')\n    top.wm_attributes('-topmost', True)\n\n    panel = tkinter.Frame(top)\n    button1 = tkinter.Button(panel, text='下载', command=download)\n    button1.pack(side='left')\n    button2 = tkinter.Button(panel, text='关于', command=show_about)\n    button2.pack(side='right')\n    panel.pack(side='bottom')\n\n    tkinter.mainloop()\n\n\nif __name__ == '__main__':\n    main()\n\n\n# 在不使用多线程的情况下 一旦点击下载按钮 由于该操作需要花费10秒中的时间\n# 整个主消息循环也会被阻塞10秒钟无法响应其他的事件\n# 事实上 对于没有因果关系的子任务 这种顺序执行的方式并不合理\n"
  },
  {
    "path": "Day01-15/Day13/test2.py",
    "content": "import time\nfrom threading import Thread, Lock\n\n\nclass Account(object):\n\n    def __init__(self, balance=0):\n        self._balance = balance\n        self._lock = Lock()\n\n    @property\n    def balance(self):\n        return self._balance\n\n    def deposit(self, money):\n        # 当多个线程同时访问一个资源的时候 就有可能因为竞争资源导致资源的状态错误\n        # 被多个线程访问的资源我们通常称之为临界资源 对临界资源的访问需要加上保护\n        if money > 0:\n            self._lock.acquire()\n            try:\n                new_balance = self._balance + money\n                time.sleep(0.01)\n                self._balance = new_balance\n            finally:\n                self._lock.release()\n\n\nclass AddMoneyThread(Thread):\n\n    def __init__(self, account):\n        super().__init__()\n        self._account = account\n\n    def run(self):\n        self._account.deposit(1)\n\n\ndef main():\n    account = Account(1000)\n    tlist = []\n    for _ in range(100):\n        t = AddMoneyThread(account)\n        tlist.append(t)\n        t.start()\n    for t in tlist:\n        t.join()\n    print('账户余额: %d元' % account.balance)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day13/test3.py",
    "content": "from random import randint\nfrom threading import Thread\nfrom time import sleep\n\nimport pygame\n\n\nclass Color(object):\n    BLACK = (0, 0, 0)\n    WHITE = (255, 255, 255)\n    GRAY = (242, 242, 242)\n\n    @staticmethod\n    def random_color():\n        r = randint(0, 255)\n        g = randint(0, 255)\n        b = randint(0, 255)\n        return r, g, b\n\n\nclass Car(object):\n\n    def __init__(self, x, y, color):\n        self._x = x\n        self._y = y\n        self._color = color\n\n    def move(self):\n        if self._x + 80 < 950:\n            self._x += randint(1, 10)\n\n    def draw(self, screen):\n        pygame.draw.rect(screen, self._color,\n                         (self._x, self._y, 80, 40), 0)\n\n\ndef main():\n\n    class BackgroundTask(Thread):\n\n        def run(self):\n            while True:\n                screen.fill(Color.GRAY)\n                pygame.draw.line(screen, Color.BLACK, (130, 0), (130, 600), 4)\n                pygame.draw.line(screen, Color.BLACK, (950, 0), (950, 600), 4)\n                for car in cars:\n                    car.draw(screen)\n                pygame.display.flip()\n                sleep(0.05)\n                for car in cars:\n                    car.move()\n\n    cars = []\n    for index in range(5):\n        temp = Car(50, 50 + 120 * index, Color.random_color())\n        cars.append(temp)\n    pygame.init()\n    screen = pygame.display.set_mode((1000, 600))\n    BackgroundTask(daemon=True).start()\n    running = True\n    while running:\n        for event in pygame.event.get():\n            if event.type == pygame.QUIT:\n                running = False\n    pygame.quit()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day13/进程和线程.md",
    "content": "## 进程和线程\n\n今天我们使用的计算机早已进入多CPU或多核时代，而我们使用的操作系统都是支持“多任务”的操作系统，这使得我们可以同时运行多个程序，也可以将一个程序分解为若干个相对独立的子任务，让多个子任务并发的执行，从而缩短程序的执行时间，同时也让用户获得更好的体验。因此在当下不管是用什么编程语言进行开发，实现让程序同时执行多个任务也就是常说的“并发编程”，应该是程序员必备技能之一。为此，我们需要先讨论两个概念，一个叫进程，一个叫线程。\n\n### 概念\n\n进程就是操作系统中执行的一个程序，操作系统以进程为单位分配存储空间，每个进程都有自己的地址空间、数据栈以及其他用于跟踪进程执行的辅助数据，操作系统管理所有进程的执行，为它们合理的分配资源。进程可以通过fork或spawn的方式来创建新的进程来执行其他的任务，不过新的进程也有自己独立的内存空间，因此必须通过进程间通信机制（IPC，Inter-Process Communication）来实现数据共享，具体的方式包括管道、信号、套接字、共享内存区等。\n\n一个进程还可以拥有多个并发的执行线索，简单的说就是拥有多个可以获得CPU调度的执行单元，这就是所谓的线程。由于线程在同一个进程下，它们可以共享相同的上下文，因此相对于进程而言，线程间的信息共享和通信更加容易。当然在单核CPU系统中，真正的并发是不可能的，因为在某个时刻能够获得CPU的只有唯一的一个线程，多个线程共享了CPU的执行时间。使用多线程实现并发编程为程序带来的好处是不言而喻的，最主要的体现在提升程序的性能和改善用户体验，今天我们使用的软件几乎都用到了多线程技术，这一点可以利用系统自带的进程监控工具（如macOS中的“活动监视器”、Windows中的“任务管理器”）来证实，如下图所示。\n\n![](./res/macos-monitor.png)\n\n当然多线程也并不是没有坏处，站在其他进程的角度，多线程的程序对其他程序并不友好，因为它占用了更多的CPU执行时间，导致其他程序无法获得足够的CPU执行时间；另一方面，站在开发者的角度，编写和调试多线程的程序都对开发者有较高的要求，对于初学者来说更加困难。\n\nPython既支持多进程又支持多线程，因此使用Python实现并发编程主要有3种方式：多进程、多线程、多进程+多线程。\n\n### Python中的多进程\n\nUnix和Linux操作系统上提供了`fork()`系统调用来创建进程，调用`fork()`函数的是父进程，创建出的是子进程，子进程是父进程的一个拷贝，但是子进程拥有自己的PID。`fork()`函数非常特殊它会返回两次，父进程中可以通过`fork()`函数的返回值得到子进程的PID，而子进程中的返回值永远都是0。Python的os模块提供了`fork()`函数。由于Windows系统没有`fork()`调用，因此要实现跨平台的多进程编程，可以使用multiprocessing模块的`Process`类来创建子进程，而且该模块还提供了更高级的封装，例如批量启动进程的进程池（`Pool`）、用于进程间通信的队列（`Queue`）和管道（`Pipe`）等。\n\n下面用一个下载文件的例子来说明使用多进程和不使用多进程到底有什么差别，先看看下面的代码。\n\n```Python\nfrom random import randint\nfrom time import time, sleep\n\n\ndef download_task(filename):\n    print('开始下载%s...' % filename)\n    time_to_download = randint(5, 10)\n    sleep(time_to_download)\n    print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))\n\n\ndef main():\n    start = time()\n    download_task('Python从入门到住院.pdf')\n    download_task('Peking Hot.avi')\n    end = time()\n    print('总共耗费了%.2f秒.' % (end - start))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n下面是运行程序得到的一次运行结果。\n\n```Shell\n开始下载Python从入门到住院.pdf...\nPython从入门到住院.pdf下载完成! 耗费了6秒\n开始下载Peking Hot.avi...\nPeking Hot.avi下载完成! 耗费了7秒\n总共耗费了13.01秒.\n```\n\n从上面的例子可以看出，如果程序中的代码只能按顺序一点点的往下执行，那么即使执行两个毫不相关的下载任务，也需要先等待一个文件下载完成后才能开始下一个下载任务，很显然这并不合理也没有效率。接下来我们使用多进程的方式将两个下载任务放到不同的进程中，代码如下所示。\n\n```Python\nfrom multiprocessing import Process\nfrom os import getpid\nfrom random import randint\nfrom time import time, sleep\n\n\ndef download_task(filename):\n    print('启动下载进程，进程号[%d].' % getpid())\n    print('开始下载%s...' % filename)\n    time_to_download = randint(5, 10)\n    sleep(time_to_download)\n    print('%s下载完成! 耗费了%d秒' % (filename, time_to_download))\n\n\ndef main():\n    start = time()\n    p1 = Process(target=download_task, args=('Python从入门到住院.pdf', ))\n    p1.start()\n    p2 = Process(target=download_task, args=('Peking Hot.avi', ))\n    p2.start()\n    p1.join()\n    p2.join()\n    end = time()\n    print('总共耗费了%.2f秒.' % (end - start))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n在上面的代码中，我们通过`Process`类创建了进程对象，通过`target`参数我们传入一个函数来表示进程启动后要执行的代码，后面的`args`是一个元组，它代表了传递给函数的参数。`Process`对象的`start`方法用来启动进程，而`join`方法表示等待进程执行结束。运行上面的代码可以明显发现两个下载任务“同时”启动了，而且程序的执行时间将大大缩短，不再是两个任务的时间总和。下面是程序的一次执行结果。\n\n```Shell\n启动下载进程，进程号[1530].\n开始下载Python从入门到住院.pdf...\n启动下载进程，进程号[1531].\n开始下载Peking Hot.avi...\nPeking Hot.avi下载完成! 耗费了7秒\nPython从入门到住院.pdf下载完成! 耗费了10秒\n总共耗费了10.01秒.\n```\n\n我们也可以使用subprocess模块中的类和函数来创建和启动子进程，然后通过管道来和子进程通信，这些内容我们不在此进行讲解，有兴趣的读者可以自己了解这些知识。接下来我们将重点放在如何实现两个进程间的通信。我们启动两个进程，一个输出Ping，一个输出Pong，两个进程输出的Ping和Pong加起来一共10个。听起来很简单吧，但是如果这样写可是错的哦。\n\n```Python\nfrom multiprocessing import Process\nfrom time import sleep\n\ncounter = 0\n\n\ndef sub_task(string):\n    global counter\n    while counter < 10:\n        print(string, end='', flush=True)\n        counter += 1\n        sleep(0.01)\n\n        \ndef main():\n    Process(target=sub_task, args=('Ping', )).start()\n    Process(target=sub_task, args=('Pong', )).start()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n看起来没毛病，但是最后的结果是Ping和Pong各输出了10个，Why？当我们在程序中创建进程的时候，子进程复制了父进程及其所有的数据结构，每个子进程有自己独立的内存空间，这也就意味着两个子进程中各有一个`counter`变量，所以结果也就可想而知了。要解决这个问题比较简单的办法是使用multiprocessing模块中的`Queue`类，它是可以被多个进程共享的队列，底层是通过管道和[信号量（semaphore）]()机制来实现的，有兴趣的读者可以自己尝试一下。\n\n\n### Python中的多线程\n\n在Python早期的版本中就引入了thread模块（现在名为_thread）来实现多线程编程，然而该模块过于底层，而且很多功能都没有提供，因此目前的多线程开发我们推荐使用threading模块，该模块对多线程编程提供了更好的面向对象的封装。我们把刚才下载文件的例子用多线程的方式来实现一遍。\n\n```Python\nfrom random import randint\nfrom threading import Thread\nfrom time import time, sleep\n\n\ndef download(filename):\n\tprint('开始下载%s...' % filename)\n\ttime_to_download = randint(5, 10)\n\tsleep(time_to_download)\n\tprint('%s下载完成! 耗费了%d秒' % (filename, time_to_download))\n\n\ndef main():\n\tstart = time()\n\tt1 = Thread(target=download, args=('Python从入门到住院.pdf',))\n\tt1.start()\n\tt2 = Thread(target=download, args=('Peking Hot.avi',))\n\tt2.start()\n\tt1.join()\n\tt2.join()\n\tend = time()\n\tprint('总共耗费了%.3f秒' % (end - start))\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n我们可以直接使用threading模块的`Thread`类来创建线程，但是我们之前讲过一个非常重要的概念叫“继承”，我们可以从已有的类创建新类，因此也可以通过继承`Thread`类的方式来创建自定义的线程类，然后再创建线程对象并启动线程。代码如下所示。\n\n```Python\nfrom random import randint\nfrom threading import Thread\nfrom time import time, sleep\n\n\nclass DownloadTask(Thread):\n\n    def __init__(self, filename):\n        super().__init__()\n        self._filename = filename\n\n    def run(self):\n        print('开始下载%s...' % self._filename)\n        time_to_download = randint(5, 10)\n        sleep(time_to_download)\n        print('%s下载完成! 耗费了%d秒' % (self._filename, time_to_download))\n\n\ndef main():\n    start = time()\n    t1 = DownloadTask('Python从入门到住院.pdf')\n    t1.start()\n    t2 = DownloadTask('Peking Hot.avi')\n    t2.start()\n    t1.join()\n    t2.join()\n    end = time()\n    print('总共耗费了%.2f秒.' % (end - start))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n因为多个线程可以共享进程的内存空间，因此要实现多个线程间的通信相对简单，大家能想到的最直接的办法就是设置一个全局变量，多个线程共享这个全局变量即可。但是当多个线程共享同一个变量（我们通常称之为“资源”）的时候，很有可能产生不可控的结果从而导致程序失效甚至崩溃。如果一个资源被多个线程竞争使用，那么我们通常称之为“临界资源”，对“临界资源”的访问需要加上保护，否则资源会处于“混乱”的状态。下面的例子演示了100个线程向同一个银行账户转账（转入1元钱）的场景，在这个例子中，银行账户就是一个临界资源，在没有保护的情况下我们很有可能会得到错误的结果。\n\n```Python\nfrom time import sleep\nfrom threading import Thread\n\n\nclass Account(object):\n\n    def __init__(self):\n        self._balance = 0\n\n    def deposit(self, money):\n        # 计算存款后的余额\n        new_balance = self._balance + money\n        # 模拟受理存款业务需要0.01秒的时间\n        sleep(0.01)\n        # 修改账户余额\n        self._balance = new_balance\n\n    @property\n    def balance(self):\n        return self._balance\n\n\nclass AddMoneyThread(Thread):\n\n    def __init__(self, account, money):\n        super().__init__()\n        self._account = account\n        self._money = money\n\n    def run(self):\n        self._account.deposit(self._money)\n\n\ndef main():\n    account = Account()\n    threads = []\n    # 创建100个存款的线程向同一个账户中存钱\n    for _ in range(100):\n        t = AddMoneyThread(account, 1)\n        threads.append(t)\n        t.start()\n    # 等所有存款的线程都执行完毕\n    for t in threads:\n        t.join()\n    print('账户余额为: ￥%d元' % account.balance)\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n运行上面的程序，结果让人大跌眼镜，100个线程分别向账户中转入1元钱，结果居然远远小于100元。之所以出现这种情况是因为我们没有对银行账户这个“临界资源”加以保护，多个线程同时向账户中存钱时，会一起执行到`new_balance = self._balance + money`这行代码，多个线程得到的账户余额都是初始状态下的`0`，所以都是`0`上面做了+1的操作，因此得到了错误的结果。在这种情况下，“锁”就可以派上用场了。我们可以通过“锁”来保护“临界资源”，只有获得“锁”的线程才能访问“临界资源”，而其他没有得到“锁”的线程只能被阻塞起来，直到获得“锁”的线程释放了“锁”，其他线程才有机会获得“锁”，进而访问被保护的“临界资源”。下面的代码演示了如何使用“锁”来保护对银行账户的操作，从而获得正确的结果。\n\n```Python\nfrom time import sleep\nfrom threading import Thread, Lock\n\n\nclass Account(object):\n\n    def __init__(self):\n        self._balance = 0\n        self._lock = Lock()\n\n    def deposit(self, money):\n        # 先获取锁才能执行后续的代码\n        self._lock.acquire()\n        try:\n            new_balance = self._balance + money\n            sleep(0.01)\n            self._balance = new_balance\n        finally:\n            # 在finally中执行释放锁的操作保证正常异常锁都能释放\n            self._lock.release()\n\n    @property\n    def balance(self):\n        return self._balance\n\n\nclass AddMoneyThread(Thread):\n\n    def __init__(self, account, money):\n        super().__init__()\n        self._account = account\n        self._money = money\n\n    def run(self):\n        self._account.deposit(self._money)\n\n\ndef main():\n    account = Account()\n    threads = []\n    for _ in range(100):\n        t = AddMoneyThread(account, 1)\n        threads.append(t)\n        t.start()\n    for t in threads:\n        t.join()\n    print('账户余额为: ￥%d元' % account.balance)\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n比较遗憾的一件事情是Python的多线程并不能发挥CPU的多核特性，这一点只要启动几个执行死循环的线程就可以得到证实了。之所以如此，是因为Python的解释器有一个“全局解释器锁”（GIL）的东西，任何线程执行前必须先获得GIL锁，然后每执行100条字节码，解释器就自动释放GIL锁，让别的线程有机会执行，这是一个历史遗留问题，但是即便如此，就如我们之前举的例子，使用多线程在提升执行效率和改善用户体验方面仍然是有积极意义的。\n\n### 多进程还是多线程\n\n无论是多进程还是多线程，只要数量一多，效率肯定上不去，为什么呢？我们打个比方，假设你不幸正在准备中考，每天晚上需要做语文、数学、英语、物理、化学这5科的作业，每项作业耗时1小时。如果你先花1小时做语文作业，做完了，再花1小时做数学作业，这样，依次全部做完，一共花5小时，这种方式称为单任务模型。如果你打算切换到多任务模型，可以先做1分钟语文，再切换到数学作业，做1分钟，再切换到英语，以此类推，只要切换速度足够快，这种方式就和单核CPU执行多任务是一样的了，以旁观者的角度来看，你就正在同时写5科作业。\n\n但是，切换作业是有代价的，比如从语文切到数学，要先收拾桌子上的语文书本、钢笔（这叫保存现场），然后，打开数学课本、找出圆规直尺（这叫准备新环境），才能开始做数学作业。操作系统在切换进程或者线程时也是一样的，它需要先保存当前执行的现场环境（CPU寄存器状态、内存页等），然后，把新任务的执行环境准备好（恢复上次的寄存器状态，切换内存页等），才能开始执行。这个切换过程虽然很快，但是也需要耗费时间。如果有几千个任务同时进行，操作系统可能就主要忙着切换任务，根本没有多少时间去执行任务了，这种情况最常见的就是硬盘狂响，点窗口无反应，系统处于假死状态。所以，多任务一旦多到一个限度，反而会使得系统性能急剧下降，最终导致所有任务都做不好。\n\n是否采用多任务的第二个考虑是任务的类型，可以把任务分为计算密集型和I/O密集型。计算密集型任务的特点是要进行大量的计算，消耗CPU资源，比如对视频进行编码解码或者格式转换等等，这种任务全靠CPU的运算能力，虽然也可以用多任务完成，但是任务越多，花在任务切换的时间就越多，CPU执行任务的效率就越低。计算密集型任务由于主要消耗CPU资源，这类任务用Python这样的脚本语言去执行效率通常很低，最能胜任这类任务的是C语言，我们之前提到了Python中有嵌入C/C++代码的机制。\n\n除了计算密集型任务，其他的涉及到网络、存储介质I/O的任务都可以视为I/O密集型任务，这类任务的特点是CPU消耗很少，任务的大部分时间都在等待I/O操作完成（因为I/O的速度远远低于CPU和内存的速度）。对于I/O密集型任务，如果启动多任务，就可以减少I/O等待时间从而让CPU高效率的运转。有一大类的任务都属于I/O密集型任务，这其中包括了我们很快会涉及到的网络应用和Web应用。\n\n> **说明：**上面的内容和例子来自于[廖雪峰官方网站的《Python教程》](https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000)，因为对作者文中的某些观点持有不同的看法，对原文的文字描述做了适当的调整。\n\n### 单线程+异步I/O\n\n现代操作系统对I/O操作的改进中最为重要的就是支持异步I/O。如果充分利用操作系统提供的异步I/O支持，就可以用单进程单线程模型来执行多任务，这种全新的模型称为事件驱动模型。Nginx就是支持异步I/O的Web服务器，它在单核CPU上采用单进程模型就可以高效地支持多任务。在多核CPU上，可以运行多个进程（数量与CPU核心数相同），充分利用多核CPU。用Node.js开发的服务器端程序也使用了这种工作模式，这也是当下实现多任务编程的一种趋势。\n\n在Python语言中，单线程+异步I/O的编程模型称为协程，有了协程的支持，就可以基于事件驱动编写高效的多任务程序。协程最大的优势就是极高的执行效率，因为子程序切换不是线程切换，而是由程序自身控制，因此，没有线程切换的开销。协程的第二个优势就是不需要多线程的锁机制，因为只有一个线程，也不存在同时写变量冲突，在协程中控制共享资源不用加锁，只需要判断状态就好了，所以执行效率比多线程高很多。如果想要充分利用CPU的多核特性，最简单的方法是多进程+协程，既充分利用多核，又充分发挥协程的高效率，可获得极高的性能。关于这方面的内容，我稍后会做一个专题来进行讲解。\n\n### 应用案例\n\n#### 例子1：将耗时间的任务放到线程中以获得更好的用户体验。\n\n如下所示的界面中，有“下载”和“关于”两个按钮，用休眠的方式模拟点击“下载”按钮会联网下载文件需要耗费10秒的时间，如果不使用“多线程”，我们会发现，当点击“下载”按钮后整个程序的其他部分都被这个耗时间的任务阻塞而无法执行了，这显然是非常糟糕的用户体验，代码如下所示。\n\n```Python\nimport time\nimport tkinter\nimport tkinter.messagebox\n\n\ndef download():\n    # 模拟下载任务需要花费10秒钟时间\n    time.sleep(10)\n    tkinter.messagebox.showinfo('提示', '下载完成!')\n\n\ndef show_about():\n    tkinter.messagebox.showinfo('关于', '作者: 骆昊(v1.0)')\n\n\ndef main():\n    top = tkinter.Tk()\n    top.title('单线程')\n    top.geometry('200x150')\n    top.wm_attributes('-topmost', True)\n\n    panel = tkinter.Frame(top)\n    button1 = tkinter.Button(panel, text='下载', command=download)\n    button1.pack(side='left')\n    button2 = tkinter.Button(panel, text='关于', command=show_about)\n    button2.pack(side='right')\n    panel.pack(side='bottom')\n\n    tkinter.mainloop()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n如果使用多线程将耗时间的任务放到一个独立的线程中执行，这样就不会因为执行耗时间的任务而阻塞了主线程，修改后的代码如下所示。\n\n```Python\nimport time\nimport tkinter\nimport tkinter.messagebox\nfrom threading import Thread\n\n\ndef main():\n\n    class DownloadTaskHandler(Thread):\n\n        def run(self):\n            time.sleep(10)\n            tkinter.messagebox.showinfo('提示', '下载完成!')\n            # 启用下载按钮\n            button1.config(state=tkinter.NORMAL)\n\n    def download():\n        # 禁用下载按钮\n        button1.config(state=tkinter.DISABLED)\n        # 通过daemon参数将线程设置为守护线程(主程序退出就不再保留执行)\n        # 在线程中处理耗时间的下载任务\n        DownloadTaskHandler(daemon=True).start()\n\n    def show_about():\n        tkinter.messagebox.showinfo('关于', '作者: 骆昊(v1.0)')\n\n    top = tkinter.Tk()\n    top.title('单线程')\n    top.geometry('200x150')\n    top.wm_attributes('-topmost', 1)\n\n    panel = tkinter.Frame(top)\n    button1 = tkinter.Button(panel, text='下载', command=download)\n    button1.pack(side='left')\n    button2 = tkinter.Button(panel, text='关于', command=show_about)\n    button2.pack(side='right')\n    panel.pack(side='bottom')\n\n    tkinter.mainloop()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n#### 例子2：使用多进程对复杂任务进行“分而治之”。\n\n我们来完成1~100000000求和的计算密集型任务，这个问题本身非常简单，有点循环的知识就能解决，代码如下所示。\n\n```Python\nfrom time import time\n\n\ndef main():\n    total = 0\n    number_list = [x for x in range(1, 100000001)]\n    start = time()\n    for number in number_list:\n        total += number\n    print(total)\n    end = time()\n    print('Execution time: %.3fs' % (end - start))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n在上面的代码中，我故意先去创建了一个列表容器然后填入了100000000个数，这一步其实是比较耗时间的，所以为了公平起见，当我们将这个任务分解到8个进程中去执行的时候，我们暂时也不考虑列表切片操作花费的时间，只是把做运算和合并运算结果的时间统计出来，代码如下所示。\n\n```Python\nfrom multiprocessing import Process, Queue\nfrom random import randint\nfrom time import time\n\n\ndef task_handler(curr_list, result_queue):\n    total = 0\n    for number in curr_list:\n        total += number\n    result_queue.put(total)\n\n\ndef main():\n    processes = []\n    number_list = [x for x in range(1, 100000001)]\n    result_queue = Queue()\n    index = 0\n    # 启动8个进程将数据切片后进行运算\n    for _ in range(8):\n        p = Process(target=task_handler,\n                    args=(number_list[index:index + 12500000], result_queue))\n        index += 12500000\n        processes.append(p)\n        p.start()\n    # 开始记录所有进程执行完成花费的时间\n    start = time()\n    for p in processes:\n        p.join()\n    # 合并执行结果\n    total = 0\n    while not result_queue.empty():\n        total += result_queue.get()\n    print(total)\n    end = time()\n    print('Execution time: ', (end - start), 's', sep='')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n比较两段代码的执行结果（在我目前使用的MacBook上，上面的代码需要大概6秒左右的时间，而下面的代码只需要不到1秒的时间，再强调一次我们只是比较了运算的时间，不考虑列表创建及切片操作花费的时间），使用多进程后由于获得了更多的CPU执行时间以及更好的利用了CPU的多核特性，明显的减少了程序的执行时间，而且计算量越大效果越明显。当然，如果愿意还可以将多个进程部署在不同的计算机上，做成分布式进程，具体的做法就是通过multiprocessing.managers模块中提供的管理器将`Queue`对象通过网络共享出来（注册到网络上让其他计算机可以访问），这部分内容也留到爬虫的专题再进行讲解。"
  },
  {
    "path": "Day01-15/Day14/chatclient.py",
    "content": "from socket import socket\nfrom threading import Thread\n\n\ndef main():\n\n    class RefreshScreenThread(Thread):\n\n        def __init__(self, client):\n            super().__init__()\n            self._client = client\n\n        def run(self):\n            while running:\n                data = self._client.recv(1024)\n                print(data.decode('utf-8'))\n\n    nickname = input('请输入你的昵称: ')\n    myclient = socket()\n    myclient.connect(('10.7.189.118', 12345))\n    running = True\n    RefreshScreenThread(myclient).start()\n    while running:\n        content = input('请发言: ')\n        if content == 'byebye':\n            myclient.send(content.encode('utf-8'))\n            running = False\n        else:\n            msg = nickname + ': ' + content\n            myclient.send(msg.encode('utf-8'))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day14/chatserver.py",
    "content": "from socket import socket\nfrom threading import Thread\n\n\ndef main():\n\n    class ClientHandler(Thread):\n\n        def __init__(self, client):\n            super().__init__()\n            self._client = client\n\n        def run(self):\n            try:\n                while True:\n                    try:\n                        data = self._client.recv(1024)\n                        if data.decode('utf-8') == 'byebye':\n                            clients.remove(self._client)\n                            self._client.close()\n                            break\n                        else:\n                            for client in clients:\n                                client.send(data)\n                    except Exception as e:\n                        print(e)\n                        clients.remove(self._client)\n                        break\n            except Exception as e:\n                print(e)\n\n    server = socket()\n    server.bind(('10.7.189.118', 12345))\n    server.listen(512)\n    clients = []\n    while True:\n        curr_client, addr = server.accept()\n        print(addr[0], '连接到服务器.')\n        clients.append(curr_client)\n        ClientHandler(curr_client).start()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day14/fileclient.py",
    "content": "from socket import socket\nfrom json import loads\nfrom base64 import b64decode\n\n\ndef main():\n    client = socket()\n    client.connect(('192.168.1.2', 5566))\n    # 定义一个保存二进制数据的对象\n    in_data = bytes()\n    # 由于不知道服务器发送的数据有多大每次接收1024字节\n    data = client.recv(1024)\n    while data:\n        # 将收到的数据拼接起来\n        in_data += data\n        data = client.recv(1024)\n    # 将收到的二进制数据解码成JSON字符串并转换成字典\n    # loads函数的作用就是将JSON字符串转成字典对象\n    my_dict = loads(in_data.decode('utf-8'))\n    filename = my_dict['filename']\n    filedata = my_dict['filedata'].encode('utf-8')\n    with open('/Users/Hao/' + filename, 'wb') as f:\n        # 将base64格式的数据解码成二进制数据并写入文件\n        f.write(b64decode(filedata))\n    print('图片已保存.')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day14/fileserver.py",
    "content": "from socket import socket, SOCK_STREAM, AF_INET\nfrom base64 import b64encode\nfrom json import dumps\nfrom threading import Thread\n\n\ndef main():\n\n    # 自定义线程类\n    class FileTransferHandler(Thread):\n\n        def __init__(self, cclient):\n            super().__init__()\n            self.cclient = cclient\n\n        def run(self):\n            my_dict = {}\n            my_dict['filename'] = 'guido.jpg'\n            # JSON是纯文本不能携带二进制数据\n            # 所以图片的二进制数据要处理成base64编码\n            my_dict['filedata'] = data\n            # 通过dumps函数将字典处理成JSON字符串\n            json_str = dumps(my_dict)\n            # 发送JSON字符串\n            self.cclient.send(json_str.encode('utf-8'))\n            self.cclient.close()\n\n    # 1.创建套接字对象并指定使用哪种传输服务\n    server = socket()\n    # 2.绑定IP地址和端口(区分不同的服务)\n    server.bind(('192.168.1.2', 5566))\n    # 3.开启监听 - 监听客户端连接到服务器\n    server.listen(512)\n    print('服务器启动开始监听...')\n    with open('guido.jpg', 'rb') as f:\n        # 将二进制数据处理成base64再解码成字符串\n        data = b64encode(f.read()).decode('utf-8')\n    while True:\n        client, addr = server.accept()\n        # 用一个字典(键值对)来保存要发送的各种数据\n        # 待会可以将字典处理成JSON格式在网络上传递\n        FileTransferHandler(client).start()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day14/mmdownloader.py",
    "content": "from time import time\nfrom threading import Thread\n\nimport requests\n\n\nclass DownloadHanlder(Thread):\n\n    def __init__(self, url):\n        super().__init__()\n        self.url = url\n\n    def run(self):\n        filename = self.url[self.url.rfind('/') + 1:]\n        resp = requests.get(self.url)\n        with open('/Users/Hao/Downloads/' + filename, 'wb') as f:\n            f.write(resp.content)\n\n\ndef main():\n    # 通过requests模块的get函数获取网络资源\n    resp = requests.get(\n        'http://api.tianapi.com/meinv/?key=772a81a51ae5c780251b1f98ea431b84&num=10')\n    # 将服务器返回的JSON格式的数据解析为字典\n    data_model = resp.json()\n    for mm_dict in data_model['newslist']:\n        url = mm_dict['picUrl']\n        # 通过多线程的方式实现图片下载\n        DownloadHanlder(url).start()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day14/socket1.py",
    "content": "\"\"\"\n\n套接字 - 基于TCP协议创建时间服务器\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-22\n\n\"\"\"\n\nfrom socket import *\nfrom time import *\n\nserver = socket(AF_INET, SOCK_STREAM)\nserver.bind(('localhost', 6789))\nserver.listen()\nprint('服务器已经启动正在监听客户端连接.')\nwhile True:\n\tclient, addr = server.accept()\n\tprint('客户端%s:%d连接成功.' % (addr[0], addr[1]))\n\tcurrtime = localtime(time())\n\ttimestr = strftime('%Y-%m-%d %H:%M:%S', currtime)\n\tclient.send(timestr.encode('utf-8'))\n\tclient.close()\nserver.close()\n"
  },
  {
    "path": "Day01-15/Day14/socket2.py",
    "content": "\"\"\"\n\n套接字 - 基于TCP协议创建时间客户端\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-22\n\n\"\"\"\n\nfrom socket import *\n\nclient = socket(AF_INET, SOCK_STREAM)\nclient.connect(('localhost', 6789))\nwhile True:\n\tdata = client.recv(1024)\n\tif not data:\n\t\tbreak\n\tprint(data.decode('utf-8'))\nclient.close()\n"
  },
  {
    "path": "Day01-15/Day14/socket3.py",
    "content": "\"\"\"\n\n套接字 - 基于UDP协议Echo服务器\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-22\n\n\"\"\"\n\nfrom socket import *\nfrom time import *\n\nserver = socket(AF_INET, SOCK_DGRAM)\nserver.bind(('localhost', 6789))\nwhile True:\n\tdata, addr = server.recvfrom(1024)\n\tserver.sendto(data, addr)\nserver.close()\n"
  },
  {
    "path": "Day01-15/Day14/socket4.py",
    "content": "\"\"\"\n\n套接字 - 基于UDP协议创建Echo客户端\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-22\n\n\"\"\"\n\nfrom socket import *\n\nclient = socket(AF_INET, SOCK_DGRAM)\nwhile True:\n\tdata_str = input('请输入: ')\n\tclient.sendto(data_str.encode('utf-8'), ('localhost', 6789))\n\tdata, addr = client.recvfrom(1024)\n\tdata_str = data.decode('utf-8')\n\tprint('服务器回应:', data_str)\n\tif data_str == 'bye':\n\t\tbreak\nclient.close()\n"
  },
  {
    "path": "Day01-15/Day14/socket5.py",
    "content": "\"\"\"\n\n使用socketserver模块创建时间服务器\n\nVersion: 0.1\nAuthor: 骆昊\nDate: 2018-03-22\n\n\"\"\"\n\nfrom socketserver import TCPServer, StreamRequestHandler\nfrom time import *\n\n\nclass EchoRequestHandler(StreamRequestHandler):\n\n\tdef handle(self):\n\t\tcurrtime = localtime(time())\n\t\ttimestr = strftime('%Y-%m-%d %H:%M:%S', currtime)\n\t\tself.wfile.write(timestr.encode('utf-8'))\n\n\nserver = TCPServer(('localhost', 6789), EchoRequestHandler)\nserver.serve_forever()\n"
  },
  {
    "path": "Day01-15/Day14/timeclient.py",
    "content": "from socket import socket\n\n\ndef main():\n    client = socket()\n    client.connect(('10.7.152.69', 6789))\n    print(client.recv(1024).decode('utf-8'))\n    client.close()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day14/timeserver.py",
    "content": "from socket import socket, SOCK_STREAM, AF_INET\nfrom datetime import datetime\n\n\ndef main():\n    # 1.创建套接字对象并指定使用哪种传输服务\n    # family=AF_INET - IPv4地址\n    # family=AF_INET6 - IPv6地址\n    # type=SOCK_STREAM - TCP套接字\n    # type=SOCK_DGRAM - UDP套接字\n    # type=SOCK_RAW - 原始套接字\n    server = socket(family=AF_INET, type=SOCK_STREAM)\n    # 2.绑定IP地址和端口(区分不同的服务)\n    server.bind(('192.168.1.2', 6789))\n    # 3.开启监听 - 监听客户端连接到服务器\n    server.listen(512)\n    print('服务器启动开始监听...')\n    # 4.通过循环接收客户端的连接并作出相应的处理(提供服务)\n    while True:\n        # accept方法是一个阻塞方法如果没有客户端连接到服务器\n        # 这个方法就会阻塞代码不会向下执行\n        # accept方法返回元组其中的第一个元素是客户端对象\n        # 第二个元素是客户端的地址(由IP和端口两部分构成)\n        client, addr = server.accept()\n        print(str(addr) + '连接到了服务器.')\n        # 5.发送数据\n        client.send(str(datetime.now()).encode('utf-8'))\n        # 6.断开连接\n        client.close()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day01-15/Day14/网络编程入门.md",
    "content": "## 网络编程入门\n\n### 计算机网络基础\n\n计算机网络是独立自主的计算机互联而成的系统的总称，组建计算机网络最主要的目的是实现多台计算机之间的通信和资源共享。今天计算机网络中的设备和计算机网络的用户已经多得不可计数，而计算机网络也可以称得上是一个“复杂巨系统”，对于这样的系统，我们不可能用一两篇文章把它讲清楚，有兴趣的读者可以自行阅读Andrew S.Tanenbaum老师的经典之作《计算机网络》或Kurose和Ross老师合著的《计算机网络:自顶向下方法》来了解计算机网络的相关知识。\n\n#### 计算机网络发展史\n\n1. 1960s - 美国国防部ARPANET项目问世，奠定了分组交换网络的基础。\n\n   ![](./res/arpanet.png)\n\n2. 1980s - 国际标准化组织（ISO）发布OSI/RM，奠定了网络技术标准化的基础。\n\n   ![](./res/osimodel.png)\n\n3. 1990s - 英国人[蒂姆·伯纳斯-李](https://zh.wikipedia.org/wiki/%E6%8F%90%E5%A7%86%C2%B7%E6%9F%8F%E5%85%A7%E8%8C%B2-%E6%9D%8E)发明了图形化的浏览器，浏览器的简单易用性使得计算机网络迅速被普及。\n\n   在没有浏览器的年代，上网是这样的。\n\n   ![](./res/before-browser.jpg)\n\n   有了浏览器以后，上网是这样的。\n\n   ![](./res/after-browser.jpg)\n\n#### TCP/IP模型\n\n实现网络通信的基础是网络通信协议，这些协议通常是由[互联网工程任务组](https://zh.wikipedia.org/wiki/%E4%BA%92%E8%81%94%E7%BD%91%E5%B7%A5%E7%A8%8B%E4%BB%BB%E5%8A%A1%E7%BB%84) （IETF）制定的。所谓“协议”就是通信计算机双方必须共同遵从的一组约定，例如怎样建立连接、怎样互相识别等，网络协议的三要素是：语法、语义和时序。构成我们今天使用的Internet的基础的是TCP/IP协议族，所谓协议族就是一系列的协议及其构成的通信模型，我们通常也把这套东西称为TCP/IP模型。与国际标准化组织发布的OSI/RM这个七层模型不同，TCP/IP是一个四层模型，也就是说，该模型将我们使用的网络从逻辑上分解为四个层次，自底向上依次是：网络接口层、网络层、传输层和应用层，如下图所示。\n\n![](./res/TCP-IP-model.png)\n\nIP通常被翻译为网际协议，它服务于网络层，主要实现了寻址和路由的功能。接入网络的每一台主机都需要有自己的IP地址，IP地址就是主机在计算机网络上的身份标识。当然由于IPv4地址的匮乏，我们平常在家里、办公室以及其他可以接入网络的公共区域上网时获得的IP地址并不是全球唯一的IP地址，而是一个[局域网（LAN）](https://zh.wikipedia.org/zh-hans/%E5%B1%80%E5%9F%9F%E7%BD%91)中的内部IP地址，通过[网络地址转换（NAT）服务](https://zh.wikipedia.org/wiki/%E7%BD%91%E7%BB%9C%E5%9C%B0%E5%9D%80%E8%BD%AC%E6%8D%A2)我们也可以实现对网络的访问。计算机网络上有大量的被我们称为“[路由器](https://zh.wikipedia.org/wiki/%E8%B7%AF%E7%94%B1%E5%99%A8)”的网络中继设备，它们会存储转发我们发送到网络上的数据分组，让从源头发出的数据最终能够找到传送到目的地通路，这项功能就是所谓的路由。\n\nTCP全称传输控制协议，它是基于IP提供的寻址和路由服务而建立起来的负责实现端到端可靠传输的协议，之所以将TCP称为可靠的传输协议是因为TCP向调用者承诺了三件事情：\n\n1. 数据不传丢不传错（利用握手、校验和重传机制可以实现）。\n2. 流量控制（通过滑动窗口匹配数据发送者和接收者之间的传输速度）。\n3. 拥塞控制（通过RTT时间以及对滑动窗口的控制缓解网络拥堵）。\n\n\n\n#### 网络应用模式\n\n1. C/S模式和B/S模式。这里的C指的是Client（客户端），通常是一个需要安装到某个宿主操作系统上的应用程序；而B指的是Browser（浏览器），它几乎是所有图形化操作系统都默认安装了的一个应用软件；通过C或B都可以实现对S（服务器）的访问。关于二者的比较和讨论在网络上有一大堆的文章，在此我们就不再浪费笔墨了。\n2. 去中心化的网络应用模式。不管是B/S还是C/S都需要服务器的存在，服务器就是整个应用模式的中心，而去中心化的网络应用通常没有固定的服务器或者固定的客户端，所有应用的使用者既可以作为资源的提供者也可以作为资源的访问者。\n\n### 基于HTTP协议的网络资源访问\n\n#### HTTP（超文本传输协议）\n\nHTTP是超文本传输协议（Hyper-Text Transfer Proctol）的简称，维基百科上对HTTP的解释是：超文本传输协议是一种用于分布式、协作式和超媒体信息系统的应用层协议，它是[万维网](https://zh.wikipedia.org/wiki/%E5%85%A8%E7%90%83%E8%B3%87%E8%A8%8A%E7%B6%B2)数据通信的基础，设计HTTP最初的目的是为了提供一种发布和接收[HTML](https://zh.wikipedia.org/wiki/HTML)页面的方法，通过HTTP或者[HTTPS](https://zh.wikipedia.org/wiki/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%AE%89%E5%85%A8%E5%8D%8F%E8%AE%AE)（超文本传输安全协议）请求的资源由URI（[统一资源标识符](https://zh.wikipedia.org/wiki/%E7%B5%B1%E4%B8%80%E8%B3%87%E6%BA%90%E6%A8%99%E8%AD%98%E7%AC%A6)）来标识。关于HTTP的更多内容，我们推荐阅读阮一峰老师的[《HTTP 协议入门》](http://www.ruanyifeng.com/blog/2016/08/http.html)，简单的说，通过HTTP我们可以获取网络上的（基于字符的）资源，开发中经常会用到的网络API（有的地方也称之为网络数据接口）就是基于HTTP来实现数据传输的。\n\n#### JSON格式\n\n**JSON**（**J**ava**S**cript **O**bject **N**otation）是一种轻量级的数据交换语言，该语言以易于让人阅读的文字（纯文本）为基础，用来传输由属性值或者序列性的值组成的数据对象。尽管JSON是最初只是Javascript中一种创建对象的字面量语法，但它在当下更是一种独立于语言的数据格式，很多编程语言都支持JSON格式数据的生成和解析，Python内置的json模块也提供了这方面的功能。由于JSON是纯文本，它和[XML](https://zh.wikipedia.org/wiki/XML)一样都适用于异构系统之间的数据交换，而相较于XML，JSON显得更加的轻便和优雅。下面是表达同样信息的XML和JSON，而JSON的优势是相当直观的。\n\nXML的例子：\n\n```XML\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<message>\n\t<from>Alice</from>\n\t<to>Bob</to>\n\t<content>Will you marry me?</content>\n</message>\n```\n\nJSON的例子：\n\n```JSON\n{\n    'from': 'Alice',\n    'to': 'Bob',\n    'content': 'Will you marry me?'\n}\n```\n\n#### requests库\n\nrequests是一个基于HTTP协议来使用网络的第三库，其[官方网站](http://cn.python-requests.org/zh_CN/latest/)有这样的一句介绍它的话：“Requests是唯一的一个**非转基因**的Python HTTP库，人类可以安全享用。”简单的说，使用requests库可以非常方便的使用HTTP，避免安全缺陷、冗余代码以及“重复发明轮子”（行业黑话，通常用在软件工程领域表示重新创造一个已有的或是早已被优化過的基本方法）。前面的文章中我们已经使用过这个库，下面我们还是通过requests来实现一个访问网络数据接口并从中获取美女图片下载链接然后下载美女图片到本地的例子程序，程序中使用了[天行数据](https://www.tianapi.com/)提供的网络API。\n\n我们可以先通过pip安装requests及其依赖库。\n\n```Shell\npip install requests\n```\n\n如果使用PyCharm作为开发工具，可以直接在代码中书写`import requests`，然后通过代码修复功能来自动下载安装requests。\n\n```Python\nfrom time import time\nfrom threading import Thread\n\nimport requests\n\n\n# 继承Thread类创建自定义的线程类\nclass DownloadHanlder(Thread):\n\n    def __init__(self, url):\n        super().__init__()\n        self.url = url\n\n    def run(self):\n        filename = self.url[self.url.rfind('/') + 1:]\n        resp = requests.get(self.url)\n        with open('/Users/Hao/' + filename, 'wb') as f:\n            f.write(resp.content)\n\n\ndef main():\n    # 通过requests模块的get函数获取网络资源\n    # 下面的代码中使用了天行数据接口提供的网络API\n    # 要使用该数据接口需要在天行数据的网站上注册\n    # 然后用自己的Key替换掉下面代码的中APIKey即可\n    resp = requests.get(\n        'http://api.tianapi.com/meinv/?key=APIKey&num=10')\n    # 将服务器返回的JSON格式的数据解析为字典\n    data_model = resp.json()\n    for mm_dict in data_model['newslist']:\n        url = mm_dict['picUrl']\n        # 通过多线程的方式实现图片下载\n        DownloadHanlder(url).start()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n### 基于传输层协议的套接字编程\n\n套接字这个词对很多不了解网络编程的人来说显得非常晦涩和陌生，其实说得通俗点，套接字就是一套用[C语言](https://zh.wikipedia.org/wiki/C%E8%AF%AD%E8%A8%80)写成的应用程序开发库，主要用于实现进程间通信和网络编程，在网络应用开发中被广泛使用。在Python中也可以基于套接字来使用传输层提供的传输服务，并基于此开发自己的网络应用。实际开发中使用的套接字可以分为三类：流套接字（TCP套接字）、数据报套接字和原始套接字。\n\n#### TCP套接字\n\n所谓TCP套接字就是使用TCP协议提供的传输服务来实现网络通信的编程接口。在Python中可以通过创建socket对象并指定type属性为SOCK_STREAM来使用TCP套接字。由于一台主机可能拥有多个IP地址，而且很有可能会配置多个不同的服务，所以作为服务器端的程序，需要在创建套接字对象后将其绑定到指定的IP地址和端口上。这里的端口并不是物理设备而是对IP地址的扩展，用于区分不同的服务，例如我们通常将HTTP服务跟80端口绑定，而MySQL数据库服务默认绑定在3306端口，这样当服务器收到用户请求时就可以根据端口号来确定到底用户请求的是HTTP服务器还是数据库服务器提供的服务。端口的取值范围是0~65535，而1024以下的端口我们通常称之为“著名端口”（留给像FTP、HTTP、SMTP等“著名服务”使用的端口，有的地方也称之为“周知端口”），自定义的服务通常不使用这些端口，除非自定义的是HTTP或FTP这样的著名服务。\n\n下面的代码实现了一个提供时间日期的服务器。\n\n```Python\nfrom socket import socket, SOCK_STREAM, AF_INET\nfrom datetime import datetime\n\n\ndef main():\n    # 1.创建套接字对象并指定使用哪种传输服务\n    # family=AF_INET - IPv4地址\n    # family=AF_INET6 - IPv6地址\n    # type=SOCK_STREAM - TCP套接字\n    # type=SOCK_DGRAM - UDP套接字\n    # type=SOCK_RAW - 原始套接字\n    server = socket(family=AF_INET, type=SOCK_STREAM)\n    # 2.绑定IP地址和端口(端口用于区分不同的服务)\n    # 同一时间在同一个端口上只能绑定一个服务否则报错\n    server.bind(('192.168.1.2', 6789))\n    # 3.开启监听 - 监听客户端连接到服务器\n    # 参数512可以理解为连接队列的大小\n    server.listen(512)\n    print('服务器启动开始监听...')\n    while True:\n        # 4.通过循环接收客户端的连接并作出相应的处理(提供服务)\n        # accept方法是一个阻塞方法如果没有客户端连接到服务器代码不会向下执行\n        # accept方法返回一个元组其中的第一个元素是客户端对象\n        # 第二个元素是连接到服务器的客户端的地址(由IP和端口两部分构成)\n        client, addr = server.accept()\n        print(str(addr) + '连接到了服务器.')\n        # 5.发送数据\n        client.send(str(datetime.now()).encode('utf-8'))\n        # 6.断开连接\n        client.close()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n运行服务器程序后我们可以通过Windows系统的telnet来访问该服务器，结果如下图所示。\n\n```Shell\ntelnet 192.168.1.2 6789\n```\n\n![](./res/telnet.png)\n\n当然我们也可以通过Python的程序来实现TCP客户端的功能，相较于实现服务器程序，实现客户端程序就简单多了，代码如下所示。\n\n```Python\nfrom socket import socket\n\n\ndef main():\n    # 1.创建套接字对象默认使用IPv4和TCP协议\n    client = socket()\n    # 2.连接到服务器(需要指定IP地址和端口)\n    client.connect(('192.168.1.2', 6789))\n    # 3.从服务器接收数据\n    print(client.recv(1024).decode('utf-8'))\n    client.close()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n需要注意的是，上面的服务器并没有使用多线程或者异步I/O的处理方式，这也就意味着当服务器与一个客户端处于通信状态时，其他的客户端只能排队等待。很显然，这样的服务器并不能满足我们的需求，我们需要的服务器是能够同时接纳和处理多个用户请求的。下面我们来设计一个使用多线程技术处理多个用户请求的服务器，该服务器会向连接到服务器的客户端发送一张图片。\n\n服务器端代码：\n\n```Python\nfrom socket import socket, SOCK_STREAM, AF_INET\nfrom base64 import b64encode\nfrom json import dumps\nfrom threading import Thread\n\n\ndef main():\n    \n    # 自定义线程类\n    class FileTransferHandler(Thread):\n\n        def __init__(self, cclient):\n            super().__init__()\n            self.cclient = cclient\n\n        def run(self):\n            my_dict = {}\n            my_dict['filename'] = 'guido.jpg'\n            # JSON是纯文本不能携带二进制数据\n            # 所以图片的二进制数据要处理成base64编码\n            my_dict['filedata'] = data\n            # 通过dumps函数将字典处理成JSON字符串\n            json_str = dumps(my_dict)\n            # 发送JSON字符串\n            self.cclient.send(json_str.encode('utf-8'))\n            self.cclient.close()\n\n    # 1.创建套接字对象并指定使用哪种传输服务\n    server = socket()\n    # 2.绑定IP地址和端口(区分不同的服务)\n    server.bind(('192.168.1.2', 5566))\n    # 3.开启监听 - 监听客户端连接到服务器\n    server.listen(512)\n    print('服务器启动开始监听...')\n    with open('guido.jpg', 'rb') as f:\n        # 将二进制数据处理成base64再解码成字符串\n        data = b64encode(f.read()).decode('utf-8')\n    while True:\n        client, addr = server.accept()\n        # 启动一个线程来处理客户端的请求\n        FileTransferHandler(client).start()\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n客户端代码：\n\n```Python\nfrom socket import socket\nfrom json import loads\nfrom base64 import b64decode\n\n\ndef main():\n    client = socket()\n    client.connect(('192.168.1.2', 5566))\n    # 定义一个保存二进制数据的对象\n    in_data = bytes()\n    # 由于不知道服务器发送的数据有多大每次接收1024字节\n    data = client.recv(1024)\n    while data:\n        # 将收到的数据拼接起来\n        in_data += data\n        data = client.recv(1024)\n    # 将收到的二进制数据解码成JSON字符串并转换成字典\n    # loads函数的作用就是将JSON字符串转成字典对象\n    my_dict = loads(in_data.decode('utf-8'))\n    filename = my_dict['filename']\n    filedata = my_dict['filedata'].encode('utf-8')\n    with open('/Users/Hao/' + filename, 'wb') as f:\n        # 将base64格式的数据解码成二进制数据并写入文件\n        f.write(b64decode(filedata))\n    print('图片已保存.')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n在这个案例中，我们使用了JSON作为数据传输的格式（通过JSON格式对传输的数据进行了序列化和反序列化的操作），但是JSON并不能携带二进制数据，因此对图片的二进制数据进行了Base64编码的处理。Base64是一种用64个字符表示所有二进制数据的编码方式，通过将二进制数据每6位一组的方式重新组织，刚好可以使用0~9的数字、大小写字母以及“+”和“/”总共64个字符表示从`000000`到`111111`的64种状态。[维基百科](https://zh.wikipedia.org/wiki/Base64)上有关于Base64编码的详细讲解，不熟悉Base64的读者可以自行阅读。\n\n> **说明**：上面的代码主要为了讲解网络编程的相关内容因此并没有对异常状况进行处理，请读者自行添加异常处理代码来增强程序的健壮性。\n\n#### UDP套接字\n\n传输层除了有可靠的传输协议TCP之外，还有一种非常轻便的传输协议叫做用户数据报协议，简称UDP。TCP和UDP都是提供端到端传输服务的协议，二者的差别就如同打电话和发短信的区别，后者不对传输的可靠性和可达性做出任何承诺从而避免了TCP中握手和重传的开销，所以在强调性能和而不是数据完整性的场景中（例如传输网络音视频数据），UDP可能是更好的选择。可能大家会注意到一个现象，就是在观看网络视频时，有时会出现卡顿，有时会出现花屏，这无非就是部分数据传丢或传错造成的。在Python中也可以使用UDP套接字来创建网络应用，对此我们不进行赘述，有兴趣的读者可以自行研究。\n"
  },
  {
    "path": "Day01-15/Day15/网络应用开发.md",
    "content": "## 网络应用开发\n\n### 发送电子邮件\n\n在即时通信软件如此发达的今天，电子邮件仍然是互联网上使用最为广泛的应用之一，公司向应聘者发出录用通知、网站向用户发送一个激活账号的链接、银行向客户推广它们的理财产品等几乎都是通过电子邮件来完成的，而这些任务应该都是由程序自动完成的。\n\n就像我们可以用HTTP（超文本传输协议）来访问一个网站一样，发送邮件要使用SMTP（简单邮件传输协议），SMTP也是一个建立在TCP（传输控制协议）提供的可靠数据传输服务的基础上的应用级协议，它规定了邮件的发送者如何跟发送邮件的服务器进行通信的细节，而Python中的smtplib模块将这些操作简化成了几个简单的函数。\n\n下面的代码演示了如何在Python发送邮件。\n\n```Python\nfrom smtplib import SMTP\nfrom email.header import Header\nfrom email.mime.text import MIMEText\n\n\ndef main():\n    # 请自行修改下面的邮件发送者和接收者\n\tsender = 'abcdefg@126.com'\n\treceivers = ['uvwxyz@qq.com', 'uvwxyz@126.com']\n\tmessage = MIMEText('用Python发送邮件的示例代码.', 'plain', 'utf-8')\n\tmessage['From'] = Header('王大锤', 'utf-8')\n\tmessage['To'] = Header('骆昊', 'utf-8')\n\tmessage['Subject'] = Header('示例代码实验邮件', 'utf-8')\n\tsmtper = SMTP('smtp.126.com')\n    # 请自行修改下面的登录口令\n\tsmtper.login(sender, 'secretpass')\n\tsmtper.sendmail(sender, receivers, message.as_string())\n\tprint('邮件发送完成!')\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n如果要发送带有附件的邮件，那么可以按照下面的方式进行操作。\n\n```Python\nfrom smtplib import SMTP\nfrom email.header import Header\nfrom email.mime.text import MIMEText\nfrom email.mime.image import MIMEImage\nfrom email.mime.multipart import MIMEMultipart\n\nimport urllib\n\n\ndef main():\n    # 创建一个带附件的邮件消息对象\n    message = MIMEMultipart()\n    \n    # 创建文本内容\n    text_content = MIMEText('附件中有本月数据请查收', 'plain', 'utf-8')\n    message['Subject'] = Header('本月数据', 'utf-8')\n    # 将文本内容添加到邮件消息对象中\n    message.attach(text_content)\n\n    # 读取文件并将文件作为附件添加到邮件消息对象中\n    with open('/Users/Hao/Desktop/hello.txt', 'rb') as f:\n        txt = MIMEText(f.read(), 'base64', 'utf-8')\n        txt['Content-Type'] = 'text/plain'\n        txt['Content-Disposition'] = 'attachment; filename=hello.txt'\n        message.attach(txt)\n    # 读取文件并将文件作为附件添加到邮件消息对象中\n    with open('/Users/Hao/Desktop/汇总数据.xlsx', 'rb') as f:\n        xls = MIMEText(f.read(), 'base64', 'utf-8')\n        xls['Content-Type'] = 'application/vnd.ms-excel'\n        xls['Content-Disposition'] = 'attachment; filename=month-data.xlsx'\n        message.attach(xls)\n    \n    # 创建SMTP对象\n    smtper = SMTP('smtp.126.com')\n    # 开启安全连接\n    # smtper.starttls()\n    sender = 'abcdefg@126.com'\n    receivers = ['uvwxyz@qq.com']\n    # 登录到SMTP服务器\n    # 请注意此处不是使用密码而是邮件客户端授权码进行登录\n    # 对此有疑问的读者可以联系自己使用的邮件服务器客服\n    smtper.login(sender, 'secretpass')\n    # 发送邮件\n    smtper.sendmail(sender, receivers, message.as_string())\n    # 与邮件服务器断开连接\n    smtper.quit()\n\tprint('发送完成!')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n### 发送短信\n\n发送短信也是项目中常见的功能，网站的注册码、验证码、营销信息基本上都是通过短信来发送给用户的。在下面的代码中我们使用了[互亿无线](http://www.ihuyi.com/)短信平台（该平台为注册用户提供了50条免费短信以及常用开发语言发送短信的demo，可以登录该网站并在用户自服务页面中对短信进行配置）提供的API接口实现了发送短信的服务，当然国内的短信平台很多，读者可以根据自己的需要进行选择（通常会考虑费用预算、短信达到率、使用的难易程度等指标），如果需要在商业项目中使用短信服务建议购买短信平台提供的套餐服务。\n\n```Python\nimport urllib.parse\nimport http.client\nimport json\n\n\ndef main():\n    host  = \"106.ihuyi.com\"\n    sms_send_uri = \"/webservice/sms.php?method=Submit\"\n    # 下面的参数需要填入自己注册的账号和对应的密码\n    params = urllib.parse.urlencode({'account': '你自己的账号', 'password' : '你自己的密码', 'content': '您的验证码是：147258。请不要把验证码泄露给其他人。', 'mobile': '接收者的手机号', 'format':'json' })\n    print(params)\n    headers = {'Content-type': 'application/x-www-form-urlencoded', 'Accept': 'text/plain'}\n    conn = http.client.HTTPConnection(host, port=80, timeout=30)\n    conn.request('POST', sms_send_uri, params, headers)\n    response = conn.getresponse()\n    response_str = response.read()\n    jsonstr = response_str.decode('utf-8')\n    print(json.loads(jsonstr))\n    conn.close()\n\n\nif __name__ == '__main__':\n    main()\n\n\n```\n\n"
  },
  {
    "path": "Day16-20/Python语言进阶.md",
    "content": "## Python进阶知识\n\n"
  },
  {
    "path": "Day21-30/Web前端概述.md",
    "content": "## Web前端概述\n\n### HTML简史\n\n1. 1991年10月：一个非正式CERN（[欧洲核子研究中心](https://zh.wikipedia.org/wiki/%E6%AD%90%E6%B4%B2%E6%A0%B8%E5%AD%90%E7%A0%94%E7%A9%B6%E7%B5%84%E7%B9%94)）文件首次公开18个HTML标签，这个文件的作者是物理学家[蒂姆·伯纳斯-李](https://zh.wikipedia.org/wiki/%E8%92%82%E5%A7%86%C2%B7%E4%BC%AF%E7%BA%B3%E6%96%AF-%E6%9D%8E)，因此他是[万维网](https://zh.wikipedia.org/wiki/%E4%B8%87%E7%BB%B4%E7%BD%91)的发明者，也是[万维网联盟](https://zh.wikipedia.org/wiki/%E4%B8%87%E7%BB%B4%E7%BD%91%E8%81%94%E7%9B%9F)的主席。\n2. 1995年11月：HTML 2.0标准发布（RFC 1866）。\n3. 1997年1月：HTML 3.2作为[W3C](https://zh.wikipedia.org/wiki/W3C)推荐标准发布。\n4. 1997年12月：HTML 4.0作为W3C推荐标准发布。\n5.  1999年12月：HTML4.01作为W3C推荐标准发布。\n6. 2008年1月：HTML5由W3C作为工作草案发布。\n7. 2011年5月：W3C将HTML5推进至“最终征求”（Last Call）阶段。\n8. 2012年12月：W3C指定HTML5作为“候选推荐”阶段。\n9. 2014年10月：HTML5作为稳定W3C推荐标准发布，这意味着HTML5的标准化已经完成。\n\n#### HTML5新特性\n\n1. 引入原生多媒体支持（audio和video标签）\n2. 引入可编程内容（canvas标签）\n3. 引入语义Web（article、aside、details、figure、footer、header、nav、section、summary等标签）\n4. 引入新的表单控件（日历、邮箱、搜索等）\n5. 引入对离线存储更好的支持\n6. 引入对定位、拖放、WebSocket、后台任务等的支持\n\n### 使用标签承载内容\n\n####  结构\n\n- head\n  - title\n  - meta\n- body\n\n#### 文本\n\n- 标题和段落\n- 粗体和斜体\n- 上标和下标\n- 空白（白色空间折叠）\n- 折行和水平标尺\n- 语义化标记\n  - 加粗和强调\n  - 引用\n  - 缩写词和首字母缩写词\n  - 引文\n  - 所有者联系信息\n  - 内容的修改\n\n#### 列表（list）\n\n - 有序列表（ordered list）\n - 无序列表（unordered list）\n - 定义列表（definition list）\n\n#### 链接（anchor）\n\n- 页面链接\n- 锚链接\n- 功能链接\n\n#### 图像（image）\n\n- 图像存储位置\n- 图像及其宽高\n- 选择正确的图像格式\n  - JPEG\n  - GIF\n  - PNG\n- 矢量图\n- figure标签\n\n#### 表格（table）\n\n- 基本的表格结构\n- 表格的标题\n- 跨行和跨列\n- 长表格\n\n#### 表单（form）\n\n- 如何收集信息\n- 表单控件（input）\n  - 文本框 / 密码框 / 文本域\n  - 单选按钮 / 复选按钮 / 下拉列表\n  - 提交按钮 / 图像按钮 / 文件上传\n- 组合表单元素\n  - fieldset / legend\n- HTML5的表单控件\n  - 日期\n  - 电子邮件 / URL\n  - 搜索\n\n#### 音视频（audio / video）\n\n- 视频格式和播放器\n- 视频托管服务\n- 添加视频的准备工作\n- video标签和属性\n- audio标签和属性\n\n#### 其他\n\n- 文档类型\n- 注释\n- 属性\n  - id\n  - class\n- 块级元素 / 行级元素\n- 内联框架（internal frame）\n- 页面信息（meta）\n- 转义字符（实体替换符）\n\n### 使用CSS渲染页面\n\n#### 简介\n\n- CSS的作用\n- CSS的工作原理\n- 规则、属性和值\n\n#### 颜色（color）\n\n- 如何指定颜色\n- 颜色术语和颜色对比\n- 背景色\n\n#### 文本（text / font）\n\n- 文本的大小和字型(font-size / font-family)\n- 斜体、粗体、大写和下划线(font-weight / font-style / text-decoration)\n- 行间距(line-height)、字母间距(letter-spacing)和单词间距(word-spacing)\n- 对齐(text-align)方式和缩进(text-ident)\n- 链接样式（:link / :visited / :active / :hover）\n- CSS3新属性\n  - 投影\n  - 首字母和首行文本(p:first-letter / p:first-line)\n  - 响应用户\n\n#### 盒子（box model）\n\n- 盒子大小的控制（width / height）\n- 盒子的边框、外边距和内边距（border /  margin / padding）\n- 盒子的显示和隐藏（display / visibility）\n- CSS3新属性\n  - 边框图像（border-image）\n  - 投影（border-shadow）\n  - 圆角（border-radius）\n\n#### 列表、表格和表单\n\n- 列表的项目符号（list-style）\n- 表格的边框和背景（border-collapse）\n- 表单控件的外观\n- 表单控件的对齐\n- 浏览器的开发者工具\n\n#### 图像\n\n- 控制图像的大小（display: inline-block）\n- 对齐图像\n- 背景图像（background / background-image / background-repeat / background-position）\n\n#### 布局\n\n- 控制元素的位置（position / z-index）\n  - 普通流\n  - 相对定位\n  - 绝对定位\n  - 固定定位\n  - 浮动元素（float / clear）\n- 网站布局\n  - HTML5布局\n- 适配屏幕尺寸\n  - 固定宽度布局\n  - 流体布局\n  - 布局网格\n\n### 使用JavaScript控制行为\n\n#### JavaScript基本语法\n\n- 语句和注释\n- 变量和数据类型\n  - 声明和赋值\n  - 简单数据类型和复杂数据类型\n  - 变量的命名规则\n- 表达式和运算符\n  - 赋值运算符\n  - 算术运算符\n  - 比较运算符\n  - 逻辑运算符\n- 分支结构\n  - if…else...\n  - switch…case…default...\n- 循环结构\n  - for循环\n  - while循环\n  - do…while循环\n- 数组\n  - 创建数组\n  - 操作数组中的元素\n- 函数\n  - 声明函数\n  - 调用函数\n  - 参数和返回值\n  - 匿名函数\n  - 立即调用函数\n\n#### 面向对象\n\n - 对象的概念\n - 创建对象的字面量语法\n - 访问成员运算符\n - 创建对象的构造函数语法\n    - this关键字\n - 添加和删除属性\n    - delete关键字\n - 全局对象\n    - Number / String / Boolean\n    - Date / Math / RegEx / Array\n\n#### BOM\n\n - window对象的属性和方法\n - history对象\n    - forward() / back() / go()\n - location对象\n - navigator对象\n - screen对象\n\n#### DOM\n\n - DOM树\n - 访问元素\n    - getElementById() / querySelector()\n    - getElementsByClassName() / getElementsByTagName() / querySelectorAll()\n    - parentNode / previousSibling / nextSibling / firstChild / lastChild\n- 操作元素\n  - nodeValue\n  - innerHTML / textContent / createElement() / createTextNode() / appendChild() / removeChild()\n  - className / id / hasAttribute() / getAttribute() / setAttribute() / removeAttribute()\n- 事件处理\n  - 事件类型\n    - UI事件：load / unload / error / resize / scroll\n    - 键盘事件：keydown / keyup / keypress\n    - 鼠标事件：click / dbclick / mousedown / mouseup / mousemove / mouseover / mouseout\n    - 焦点事件：focus / blur\n    - 表单事件：input / change / submit / reset / cut / copy / paste / select\n  - 事件绑定\n    - HTML事件处理程序（不推荐使用，因为要做到标签与代码分离）\n    - 传统的DOM事件处理程序（只能附加一个回调函数）\n    - 事件监听器（旧的浏览器中不被支持）\n  - 事件流：事件捕获 / 事件冒泡\n  - 事件对象（低版本IE中的window.event）\n    - target（低版本IE中的srcElement）\n    - type\n    - cancelable\n    - preventDefault()\n    - stopPropagation()（低版本IE中的cancelBubble）\n  - 鼠标事件 - 事件发生的位置\n    - 屏幕位置：screenX和screenY\n    - 页面位置：pageX和pageY\n    - 客户端位置：clientX和clientY\n  - 键盘事件 - 哪个键被按下了\n    - keyCode属性\n    - String.fromCharCode(event.keyCode)\n  - HTML5事件\n    - DOMContentLoaded\n    - hashchange\n    - beforeunload\n\n#### JavaScript API\n\n- HTML5中的API：geolocation / localStorage / sessionStorage / history\n\n### 使用jQuery\n\n#### jQuery概述\n\n1. Write Less Do More（用更少的代码来完成更多的工作）\n2. 使用CSS选择器来查找元素（更简单更方便）\n3. 使用jQuery方法来操作元素（解决浏览器兼容性问题、应用于所有元素并施加多个方法）\n\n#### 引入jQuery\n\n- 下载jQuery的开发版和压缩版\n- 从CDN加载jQuery\n\n```HTML\n<script src=\"https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js\"></script>\n<script>\n    window.jQuery || \n        document.write('<script src=\"js/jquery-3.3.1.min.js\"></script>')\n</script>\n```\n\n#### 查找元素\n\n- 选择器\n  - \\* / element / #id / .class / selector1, selector2\n  - ancestor descendant / parent>child / previous+next / previous~siblings \n- 筛选器\n  - 基本筛选器：:not(selector) / :first / :last / :even / :odd / :eq(index) / :gt(index) / :lt(index) / :animated / :focus\n  - 内容筛选器：:contains('…') / :empty / :parent / :has(selector)\n  - 可见性筛选器：:hidden / :visible\n  - 子节点筛选器：:nth-child(expr) / :first-child / :last-child / :only-child\n  - 属性筛选器：[attribute] / [attribute='value'] / [attribute!='value'] / [attribute^='value'] / [attribute$='value'] / [attribute|='value'] / [attribute~='value']\n- 表单：:input / :text / :password / :radio / :checkbox / :submit / :image / :reset / :button / :file / :selected / :enabled / :disabled / :checked\n\n#### 执行操作\n\n- 内容操作\n  - 获取/修改内容：html() / text() / replaceWith() / remove()\n  - 获取/设置元素：before() / after() / prepend() / append() / remove() / clone() / unwrap() / detach() / empty() / add()\n  - 获取/修改属性：attr() / removeAttr() / addClass() / removeClass() / css()\n  - 获取/设置表单值：val()\n- 查找操作\n  - 查找方法：find() /  parent() / children() / siblings() / next() / nextAll() / prev() / prevAll()\n  - 筛选器：filter() / not() / has() / is() / contains()\n  - 索引编号：eq()\n- 尺寸和位置\n  - 尺寸相关：height() / width() / innerHeight() / innerWidth() / outerWidth() / outerHeight()\n  - 位置相关：offset() / position() / scrollLeft() / scrollTop()\n- 特效和动画\n  - 基本动画：show() / hide() / toggle()\n  - 消失出现：fadeIn() / fadeOut() / fadeTo() / fadeToggle()\n  - 滑动效果：slideDown() / slideUp() / slideToggle()\n  - 自定义：delay() / stop() / animate()\n- 事件\n  - 文档加载：ready() / load()\n  - 用户交互：on() / off()\n\n#### 链式操作\n\n#### 检测页面是否可用\n\n```HTML\n<script>\n    $(document).ready(function() {\n        \n    });\n</script>\n```\n\n```HTML\n<script>\n    $(function() {\n        \n    });\n</script>\n```\n\n#### jQuery插件\n\n- jQuery Validation\n- jQuery Treeview\n- jQuery Autocomplete\n- jQuery UI\n\n#### 避免和其他库的冲突\n\n先引入其他库再引入jQuery的情况。\n\n```HTML\n<script src=\"other.js\"></script>\n<script src=\"jquery.js\"></script>\n<script>\n\tjQuery.noConflict();\n    jQuery(function() {\n        jQuery('div').hide();\n    });\n</script>\n```\n\n先引入jQuery再引入其他库的情况。\n\n```HTML\n<script src=\"jquery.js\"></script>\n<script src=\"other.js\"></script>\n<script>\n    jQuery(function() {\n        jQuery('div').hide();\n    });\n</script>\n```\n\n#### 使用Ajax\n\n- 原生的Ajax\n- 基于jQuery的Ajax\n  - 加载内容\n  - 提交表单\n\n### 使用Bootstrap\n\n#### 特点\n\n1. 支持主流的浏览器和移动设备\n2. 容易上手\n3. 响应式设计\n\n#### 内容\n\n1. 网格系统\n2. 封装的CSS\n3. 现成的组件\n4. JavaScript插件\n\n"
  },
  {
    "path": "Day21-30/classical_layout.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title></title>\n\t\t<style>\n\t\t\t* {\n\t\t\t\tmargin: 0;\n\t\t\t\tpadding: 0;\n\t\t\t\tfont-family: Verdana, '宋体'; \n\t\t\t}\n\t\t\tbody {\n\t\t\t\twidth: 960px;\n\t\t\t\tmargin: 10px auto;\n\t\t\t\tbackground-image: url(img/dark-wood.jpg);\n\t\t\t}\n\t\t\t#header, #main, #footer {\n\t\t\t\tbackground-color: lightgray;\n\t\t\t\tmargin: 10px 0;\n\t\t\t\tclear: both;\n\t\t\t}\n\t\t\t#header h1 {\n\t\t\t\theight: 60px;\n\t\t\t\tline-height: 60px;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t\t#nav {\n\t\t\t\theight: 35px;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t\t#nav ul li {\n\t\t\t\tline-height: 35px;\n\t\t\t\twidth: 100px;\n\t\t\t\tmargin:0 10px;\n\t\t\t\tdisplay: inline-block;\n\t\t\t}\n\t\t\ta {\n\t\t\t\ttext-decoration: none;\n\t\t\t}\n\t\t\ta:link, a:visited, a:active {\n\t\t\t\tcolor: black;\n\t\t\t}\n\t\t\t#nav ul li:hover {\n\t\t\t\tborder-bottom: 4px solid red;\n\t\t\t}\n\t\t\t.feature {\n\t\t\t\theight: 250px;\n\t\t\t\ttext-align: center;\n\t\t\t\tbackground-color: #ADD8E6;\n\t\t\t}\n\t\t\t.one, .two, .three {\n\t\t\t\twidth: 300px;\n\t\t\t\theight: 150px;\n\t\t\t\tfloat: left;\n\t\t\t}\n\t\t\t.one {\n\t\t\t\tmargin: 10px 15px 0 0;\n\t\t\t\tbackground-color: #FFEBCD;\n\t\t\t}\n\t\t\t.two {\n\t\t\t\tmargin: 10px 15px;\n\t\t\t\tbackground-color: coral;\n\t\t\t}\n\t\t\t.three {\n\t\t\t\tmargin: 10px 0 0 15px;\n\t\t\t\tbackground-color: darkseagreen;\n\t\t\t}\n\t\t\t#footer {\n\t\t\t\ttext-align: center;\n\t\t\t\tline-height: 45px;\n\t\t\t\theight: 45px;\n\t\t\t\tfont-size: 1.2em;\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div id=\"header\">\n\t\t\t<h1>Logo</h1>\n\t\t\t<div id=\"nav\">\n\t\t\t\t<ul>\n\t\t\t\t\t<li><a href=\"\">Home</a></li>\n\t\t\t\t\t<li><a href=\"\">Products</a></li>\n\t\t\t\t\t<li><a href=\"\">Services</a></li>\n\t\t\t\t\t<li><a href=\"\">About</a></li>\n\t\t\t\t\t<li><a href=\"\">Contact</a></li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</div>\n\t\t<div id=\"main\">\n\t\t\t<div class=\"feature\">\n\t\t\t\t<!-- 这一块相当于是页面的最主要的区域 -->\n\t\t\t</div>\n\t\t\t<div class=\"one\"></div>\n\t\t\t<div class=\"two\"></div>\n\t\t\t<div class=\"three\"></div>\n\t\t</div>\n\t\t<div id=\"footer\">\n\t\t\t&copy; Copyright 2011\n\t\t</div>\n\t</body>\n</html>\n"
  },
  {
    "path": "Day21-30/example.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title></title>\n\t\t<style>\n\t\t\t* {\n\t\t\t\tmargin: 0;\n\t\t\t\tpadding: 0;\n\t\t\t}\n\t\t\t.menu {\n\t\t\t\tmargin: 20px 50px;\n\t\t\t}\n\t\t\t.menu li {\n\t\t\t\tlist-style: none;\n\t\t\t\twidth: 120px;\n\t\t\t\theight: 35px;\n\t\t\t\tline-height: 35px;\n\t\t\t\tcolor: white;\n\t\t\t\ttext-align: center;\n\t\t\t\tborder-bottom: 1px solid lightgray;\n\t\t\t}\n\t\t\t.menu>li {\n\t\t\t\tbackground-color: #8FBC8F;\n\t\t\t\toverflow: hidden;\n\t\t\t}\n\t\t\t.menu>li:hover {\n\t\t\t\theight: auto;\n\t\t\t}\n\t\t\t.menu li ul li {\n\t\t\t\tbackground-color: lightsteelblue;\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<ul class=\"menu\">\n\t\t\t<li>\n\t\t\t\tMenu 1\n\t\t\t\t<ul>\n\t\t\t\t\t<li>Menu 1-1</li>\n\t\t\t\t\t<li>Menu 1-2</li>\n\t\t\t\t\t<li>Menu 1-3</li>\n\t\t\t\t</ul>\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\tMenu 2\n\t\t\t\t<ul>\n\t\t\t\t\t<li>Menu 2-1</li>\n\t\t\t\t\t<li>Menu 2-2</li>\n\t\t\t\t</ul>\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\tMenu 3\n\t\t\t\t<ul>\n\t\t\t\t\t<li>Menu 3-1</li>\n\t\t\t\t\t<li>Menu 3-2</li>\n\t\t\t\t\t<li>Menu 3-3</li>\n\t\t\t\t\t<li>Menu 3-4</li>\n\t\t\t\t\t<li>Menu 3-5</li>\n\t\t\t\t</ul>\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\tMenu 4\n\t\t\t\t<ul>\n\t\t\t\t\t<li>Menu 4-1</li>\n\t\t\t\t\t<li>Menu 4-2</li>\n\t\t\t\t</ul>\n\t\t\t</li>\n\t\t\t<li>\n\t\t\t\tMenu 5\n\t\t\t\t<ul>\n\t\t\t\t\t<li>Menu 5-1</li>\n\t\t\t\t\t<li>Menu 5-2</li>\n\t\t\t\t\t<li>Menu 5-3</li>\n\t\t\t\t\t<li>Menu 5-4</li>\n\t\t\t\t</ul>\n\t\t\t</li>\n\t\t</ul>\n\t</body>\n</html>\n"
  },
  {
    "path": "Day21-30/form.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title></title>\n\t\t<style>\n\t\t\t* {\n\t\t\t\tmargin: 0;\n\t\t\t\tpadding: 0;\n\t\t\t\tfont-size: 18px;\n\t\t\t}\n\t\t\t#login label {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 150px;\n\t\t\t\ttext-align: right;\n\t\t\t\tmargin-right: 20px;\n\t\t\t}\n\t\t\t.formitem {\n\t\t\t\tmargin: 20px 0;\n\t\t\t}\n\t\t\t.hint {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 320px;\n\t\t\t\tfont-size: 14px;\n\t\t\t\tmargin-left: 10px;\n\t\t\t}\n\t\t\t.correct {\n\t\t\t\tcolor: green;\n\t\t\t}\n\t\t\t.incorrect {\n\t\t\t\tcolor: red;\n\t\t\t}\n\t\t\t#login input[type=\"submit\"] {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 120px;\n\t\t\t\theight: 30px;\n\t\t\t\tbackground-color: darkred;\n\t\t\t\tcolor: white;\n\t\t\t\tfont-size: 20px;\n\t\t\t\tline-height: 30px;\n\t\t\t\tborder: none;\n\t\t\t\tcursor: pointer;\n\t\t\t\tmargin-left: 200px;\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<form id=\"login\" action=\"\" method=\"post\">\n\t\t\t<div class=\"formitem\">\n\t\t\t\t<label for=\"username\">用户名: </label>\n\t\t\t\t<input type=\"text\" id=\"username\" name=\"username\">\n\t\t\t\t<span id=\"uidHint\" class=\"hint\"></span>\n\t\t\t</div>\n\t\t\t<div class=\"formitem\">\n\t\t\t\t<label for=\"password\">密码: </label>\n\t\t\t\t<input type=\"password\" id=\"password\" name=\"password\">\n\t\t\t\t<span id=\"pwdHint\" class=\"hint\"></span>\n\t\t\t</div>\n\t\t\t<div class=\"formitem\">\n\t\t\t\t<label for=\"repassword\">确认密码: </label>\n\t\t\t\t<input type=\"password\" id=\"repassword\">\n\t\t\t\t<span id=\"rePwdHint\" class=\"hint\"></span>\n\t\t\t</div>\n\t\t\t<div class=\"formitem\">\n\t\t\t\t<label for=\"tel\">手机号: </label>\n\t\t\t\t<input type=\"text\" id=\"tel\" name=\"tel\">\n\t\t\t\t<span id=\"telHint\" class=\"hint\"></span>\n\t\t\t</div>\n\t\t\t<div class=\"formitem\">\n\t\t\t\t<label for=\"code\">验证码: </label>\n\t\t\t\t<input type=\"text\" id=\"code\" name=\"code\" size=\"4\">\n\t\t\t\t<input type=\"button\" value=\"获取验证码\">\n\t\t\t</div>\n\t\t\t<div class=\"formitem\">\n\t\t\t\t<input type=\"submit\" value=\"立即开通\">\n\t\t\t</div>\n\t\t\t<div class=\"formitem\">\n\t\t\t\t<label for=\"agreement\"></label>\n\t\t\t\t<input type=\"checkbox\" id=\"agreement\">\n\t\t\t\t<span class=\"hint\">我同意<a href=\"#\">《XYZ服务协议》</a></span>\n\t\t\t</div>\n\t\t</form>\n\t\t<script src=\"js/mylib.js\" ></script>\n\t\t<script>\t\n\t\t\t(function() {\n\t\t\t\t// 使用正则表达式的字面量语法创建正则表达式对象\n\t\t\t\tvar uidRegEx = /^\\w{6,20}$/;\n\t\t\t\tvar pwdRegEx = /^.{8,20}$/;\n\t\t\t\tvar telRegEx = /^1[345789]\\d{9}$/;\n\t\t\t\tvar uid = $('username');\n\t\t\t\tfunction checkUsername() {\n\t\t\t\t\tvar uidHint = $('uidHint');\n\t\t\t\t\tvar username = uid.value.trim();\n\t\t\t\t\tif (uidRegEx.test(username)) {\n\t\t\t\t\t\tuidHint.textContent = '√';\n\t\t\t\t\t\tuidHint.className = 'hint correct';\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tuidHint.textContent = '用户名由字母数字下划线构成且长度为6-20个字符';\n\t\t\t\t\t\tuidHint.className = 'hint incorrect';\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\thandleEvent(uid, 'blur', checkUsername);\n\t\t\t\tvar pwd = $('password');\n\t\t\t\tfunction checkPassword() {\n\t\t\t\t\tvar pwdHint = $('pwdHint');\n\t\t\t\t\tvar password = pwd.value;\n\t\t\t\t\tif (pwdRegEx.test(password)) {\n\t\t\t\t\t\tpwdHint.textContent = '√';\n\t\t\t\t\t\tpwdHint.className = 'hint correct';\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tpwdHint.textContent = '密码长度为8-20个字符';\n\t\t\t\t\t\tpwdHint.className = 'hint incorrect';\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\thandleEvent(pwd, 'blur', checkPassword);\n\t\t\t\tvar rePwd = $('repassword');\n\t\t\t\tfunction checkRepassword() {\n\t\t\t\t\tvar rePwdHint = $('rePwdHint');\n\t\t\t\t\tvar password = pwd.value;\n\t\t\t\t\tvar repassword = rePwd.value;\n\t\t\t\t\tif (repassword.length == 0) {\n\t\t\t\t\t\trePwdHint.textContent = '确认密码不能为空';\n\t\t\t\t\t\trePwdHint.className = 'hint incorrect';\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (repassword == password) {\n\t\t\t\t\t\trePwdHint.textContent = '√';\n\t\t\t\t\t\trePwdHint.className = 'hint correct';\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\trePwdHint.textContent = '密码和确认密码不一致';\n\t\t\t\t\t\trePwdHint.className = 'hint incorrect';\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\thandleEvent(rePwd, 'blur', checkRepassword);\n\t\t\t\tvar telInput = $('tel');\n\t\t\t\tfunction checkTel() {\n\t\t\t\t\tvar telHint = $('telHint');\n\t\t\t\t\tvar tel = telInput.value;\n\t\t\t\t\tif (telRegEx.test(tel)) {\n\t\t\t\t\t\ttelHint.textContent = '√';\n\t\t\t\t\t\ttelHint.className = 'hint correct';\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttelHint.textContent = '请输入有效的手机号';\n\t\t\t\t\t\ttelHint.className = 'hint incorrect';\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\thandleEvent(telInput, 'blur', checkTel);\n\t\t\t\tvar form = $('login') || document.forms[0];\n\t\t\t\t// 给表单对象绑定表单提交事件\n\t\t\t\thandleEvent(form, 'submit', function(evt) {\n\t\t\t\t\tevt = evt || window.event;\n\t\t\t\t\t// 阻止表单提交等到验证通过了之后手动提交表单\n\t\t\t\t\tevt.preventDefault();\n\t\t\t\t\tif (!$('agreement').checked) {\n\t\t\t\t\t\talert('请先选中同意《XYZ服务协议》');\n\t\t\t\t\t\treturn ;\n\t\t\t\t\t}\n\t\t\t\t\t// 请注意&&和&之间区别 前者有短路效果后者没有\n\t\t\t\t\tif (checkUsername() & checkPassword() &\n\t\t\t\t\t\tcheckRepassword() & checkTel()) {\n\t\t\t\t\t\tvar target = evt.target || evt.srcElement;\n\t\t\t\t\t\t// 如果所有表单数据验证都通过了就提交表单\n\t\t\t\t\t\ttarget.submit();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}());\n\t\t</script>\n\t</body>\n</html>\n"
  },
  {
    "path": "Day21-30/form_and_table.html",
    "content": "<!DOCTYPE html>\n<html lang=\"zh\">\n\t<head>\n\t\t<meta charset=\"UTF-8\" />\n\t\t<meta name=\"description\" content=\"\" />\n\t\t<title>用户登录</title>\n\t\t<style>\n\t\t\tbody {\n\t\t\t\twidth: 90%;\n\t\t\t\tmargin: 0 auto;\n\t\t\t\tfont-size: 16px;\n\t\t\t}\n\t\t\t#login {\n\t\t\t\twidth: 290px;\n\t\t\t\tmargin: 20px auto;\n\t\t\t}\n\t\t\t#login fieldset {\n\t\t\t\tborder-radius: 5px;\n\t\t\t}\n\t\t\t#login legend {\n\t\t\t\tbackground-color: lightgray;\n\t\t\t\tpadding: 2px 15px;\n\t\t\t\tborder-radius: 5px;\n\t\t\t}\n\t\t\t#login span {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 60px;\n\t\t\t\ttext-align: right;\n\t\t\t}\n\t\t\t#login input {\n\t\t\t\tmargin: 12px 5px;\n\t\t\t\tborder: none;\n\t\t\t}\n\t\t\t#login input[name^=\"user\"] {\n\t\t\t\twidth: 175px;\n\t\t\t\toutline: none;\n\t\t\t\tborder-bottom: 1px dotted darkgray;\n\t\t\t}\n\t\t\t#login input[type=\"submit\"] {\n\t\t\t\tmargin-left: 195px;\n\t\t\t\tcolor: white;\n\t\t\t\tbackground-color: chocolate;\n\t\t\t\tborder-radius: 5px;\n\t\t\t}\n\t\t\t#login input[type=\"submit\"]:hover {\n\t\t\t\tbackground-color: darkgreen;\n\t\t\t\tcursor: pointer;\n\t\t\t}\n\t\t\t#data {\n\t\t\t\tmargin: 10px auto;\n\t\t\t\tborder-collapse: collapse;\n\t\t\t}\n\t\t\t#data td {\n\t\t\t\tborder-bottom: 1px solid gray;\n\t\t\t\tborder-right: 1px solid gray;\n\t\t\t\twidth: 160px;\n\t\t\t\theight: 60px;\n\t\t\t}\n\t\t\t#data td.tl {\n\t\t\t\tborder-top-left-radius: 10px;\n\t\t\t}\n\t\t\t#data td.tr {\n\t\t\t\tborder-top-right-radius: 10px;\n\t\t\t}\n\t\t\t#data td.bl {\n\t\t\t\tborder-bottom-left-radius: 10px;\n\t\t\t}\n\t\t\t#data td.br {\n\t\t\t\tborder-bottom-right-radius: 10px;\n\t\t\t}\n\t\t\t#data td.last {\n\t\t\t\tborder-right: none;\n\t\t\t}\n\t\t\t#data td.first {\n\t\t\t\twidth: 250px;\n\t\t\t\tpadding-left: 10px;\n\t\t\t}\n\t\t\t#data td.center {\n\t\t\t\tcolor: white;\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t\t#data td.bottom {\n\t\t\t\tborder-bottom: none;\n\t\t\t}\n\t\t\t#data tr.head {\n\t\t\t\tbackground-color:lightblue;\n\t\t\t}\n\t\t\t#data tr.odd {\n\t\t\t\tbackground-color: beige;\n\t\t\t}\n\t\t\t#data tr.even {\n\t\t\t\tbackground-color: blanchedalmond;\n\t\t\t}\n\t\t</style>\n\t</head>\n\n\t<body>\n\t\t<form id=\"login\" action=\"\" method=\"post\">\n\t\t\t<fieldset>\n\t\t\t\t<legend>用户登录</legend>\n\t\t\t\t<span>用户名: </span>\n\t\t\t\t<input type=\"text\" name=\"username\" required>\n\t\t\t\t<span>密码: </span>\n\t\t\t\t<input type=\"password\" name=\"userpass\" required>\n\t\t\t\t<span>邮箱: </span>\n\t\t\t\t<input type=\"email\" name=\"useremail\" required>\n\t\t\t\t<input type=\"submit\" value=\"登录\" />\n\t\t\t</fieldset>\n\t\t</form>\n\t\t<table id=\"data\">\n\t\t\t<tr class=\"head\">\n\t\t\t\t<td class=\"tl first\"></td>\n\t\t\t\t<td class=\"center\">成都</td>\n\t\t\t\t<td class=\"center\">北京</td>\n\t\t\t\t<td class=\"tr center last\">杭州</td>\n\t\t\t</tr>\n\t\t\t<tr class=\"odd\">\n\t\t\t\t<td class=\"first\">Python从入门到住院全国巡演</td>\n\t\t\t\t<td class=\"after\">2018年2月28日 上午9:30</td>\n\t\t\t\t<td class=\"after\">2018年3月28日 上午9:30</td>\n\t\t\t\t<td class=\"last\">2018年4月28日 上午9:30</td>\n\t\t\t</tr>\n\t\t\t<tr class=\"even\">\n\t\t\t\t<td class=\"first\">MySQL从删库到跑路公开课</td>\n\t\t\t\t<td>2018年2月27日 上午9:30</td>\n\t\t\t\t<td>2018年3月5日 上午9:30</td>\n\t\t\t\t<td class=\"last\">2018年4月2日 上午9:30</td>\n\t\t\t</tr>\n\t\t\t<tr class=\"odd\">\n\t\t\t\t<td class=\"first\">Django从学习到上吊交流会</td>\n\t\t\t\t<td>2018年2月28日 上午9:30</td>\n\t\t\t\t<td></td>\n\t\t\t\t<td class=\"last\">2018年5月21日 上午9:30</td>\n\t\t\t</tr>\n\t\t\t<tr class=\"even\">\n\t\t\t\t<td class=\"first bottom bl\">爬虫从精通到坐牢无遮大会</td>\n\t\t\t\t<td class=\"bottom\">2018年3月3日 上午9:30</td>\n\t\t\t\t<td class=\"bottom\">2018年4月17日 上午9:30</td>\n\t\t\t\t<td class=\"last bottom br\">2018年1月15日 上午9:30</td>\n\t\t\t</tr>\n\t\t</table>\n\t</body>\n\n</html>"
  },
  {
    "path": "Day21-30/jquery3.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<title></title>\n\t\t<style>\n\t\t\t* { \n\t\t\t\tmargin: 0;\n\t\t\t\tpadding: 0;\n\t\t\t}\n\t\t\tbody {\n\t\t\t\twidth: 960px;\n\t\t\t\tmargin: 20px auto;\n\t\t\t}\n\t\t\t#cart {\n\t\t\t\tmargin: 0 auto;\n\t\t\t\twidth: 850px;\n\t\t\t}\n\t\t\t#cart-header {\n\t\t\t\theight: 40px;\n\t\t\t\tbackground-color: lightgray;\n\t\t\t\tmargin-bottom: 20px;\n\t\t\t}\n\t\t\t#cart-header div {\n\t\t\t\tline-height: 40px;\n\t\t\t}\n\t\t\t.left {\n\t\t\t\tfloat: left;\n\t\t\t}\n\t\t\t.right {\n\t\t\t\tfloat: right;\n\t\t\t}\n\t\t\t.w110 {\n\t\t\t\twidth: 100px;\n\t\t\t}\n\t\t\t.ml10 {\n\t\t\t\tmargin-left: 10px;\n\t\t\t}\n\t\t\t.w120 {\n\t\t\t\twidth: 120px;\n\t\t\t}\n\t\t\t.w250 {\n\t\t\t\twidth: 250px;\n\t\t\t}\n\t\t\t.center {\n\t\t\t\ttext-align: center;\n\t\t\t}\n\t\t\t.w20 {\n\t\t\t\twidth: 20px;\n\t\t\t}\n\t\t\t.w90 {\n\t\t\t\twidth: 90px;\n\t\t\t}\n\t\t\t.clear {\n\t\t\t\tclear: both;\n\t\t\t}\n\t\t\t#cart-items>div {\n\t\t\t\theight: 100px;\n\t\t\t}\n\t\t\t#cart-items>div>div {\n\t\t\t\tline-height: 100px;\n\t\t\t}\n\t\t\t.w250 span {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\tfont-size: 12px;\n\t\t\t\tline-height: 16px !important;\n\t\t\t}\n\t\t\t.single-item {\n\t\t\t\tborder-bottom: 1px solid gray;\n\t\t\t}\n\t\t\t.small-button {\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 20px;\n\t\t\t\theight: 20px;\n\t\t\t\tborder: none;\n\t\t\t}\n\t\t\t.big-button {\n\t\t\t\tcolor: white;\n\t\t\t\tbackground-color: red;\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 120px;\n\t\t\t\theight: 40px;\n\t\t\t\tborder: none;\n\t\t\t\tfont-size: 22px;\n\t\t\t}\n\t\t\t#totalCount, #totalPrice {\n\t\t\t\tcolor: red;\n\t\t\t}\n\t\t\t#totalPrice {\n\t\t\t\tfont: bolder 20px Arial;\n\t\t\t\tdisplay: inline-block;\n\t\t\t\twidth: 150px;\n\t\t\t}\n\t\t\t#cart a {\n\t\t\t\ttext-decoration: none;\n\t\t\t}\n\t\t\t#cart a:link, #cart a:visited, #cart a:active {\n\t\t\t\tcolor: gray;\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div id=\"cart\">\n\t\t\t<div id=\"cart-header\">\n\t\t\t\t<div class=\"left w110 ml10\">\n\t\t\t\t\t<input id=\"selectAll\" type=\"checkbox\">\n\t\t\t\t\t<label for=\"selectAll\">全选</label>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"left w250\">商品</div>\n\t\t\t\t<div class=\"left w120 center\">单价</div>\n\t\t\t\t<div class=\"left w120 center\">数量</div>\n\t\t\t\t<div class=\"left w120 center\">小计</div>\n\t\t\t\t<div class=\"left w120 center\">操作</div>\n\t\t\t</div>\n\t\t\t<div id=\"cart-items\">\n\t\t\t\t<div class=\"clear single-item\">\n\t\t\t\t\t<div class=\"left w20 ml10\">\n\t\t\t\t\t\t<input name=\"selectOne\" type=\"checkbox\">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w90\">\n\t\t\t\t\t\t<a href=\"\">\n\t\t\t\t\t\t\t<img src=\"img/a1.jpg\">\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w250\">\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t海澜之家/Heilan Home春装商务白衬衫男修身HNCAD3A067Y 漂白(69) 漂\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w120 center\">&yen;<span class=\"price\">138.00</span></div>\n\t\t\t\t\t<div class=\"left w120 center\">\n\t\t\t\t\t\t<button class=\"small-button\">-</button>\n\t\t\t\t\t\t<input class=\"center count\" type=\"text\" size=\"2\" value=\"1\">\n\t\t\t\t\t\t<button class=\"small-button\">+</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w120 center\">&yen;<span>138.00</span></div>\n\t\t\t\t\t<div class=\"left w120 center\">\n\t\t\t\t\t\t<a href=\"javascript:void(0);\">删除</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"clear single-item\">\n\t\t\t\t\t<div class=\"left w20 ml10\">\n\t\t\t\t\t\t<input name=\"selectOne\" type=\"checkbox\">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w90\">\n\t\t\t\t\t\t<a href=\"\">\n\t\t\t\t\t\t\t<img src=\"img/a2.jpg\">\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w250\">\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\tHLA海澜之家长袖衬衫男牛津纺休闲干净透气HNEAJ1E048A浅灰\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w120 center\">&yen;<span class=\"price\">128.00</span></div>\n\t\t\t\t\t<div class=\"left w120 center\">\n\t\t\t\t\t\t<button class=\"small-button\">-</button>\n\t\t\t\t\t\t<input class=\"center count\" type=\"text\" size=\"2\" value=\"1\">\n\t\t\t\t\t\t<button class=\"small-button\">+</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w120 center\">&yen;<span>128.00</span></div>\n\t\t\t\t\t<div class=\"left w120 center\">\n\t\t\t\t\t\t<a href=\"javascript:void(0);\">删除</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"clear single-item\">\n\t\t\t\t\t<div class=\"left w20 ml10\">\n\t\t\t\t\t\t<input name=\"selectOne\" type=\"checkbox\">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w90\">\n\t\t\t\t\t\t<a href=\"\">\n\t\t\t\t\t\t\t<img src=\"img/a3.jpg\">\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w250\">\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\tHLA海澜之家牛津纺清新休闲衬衫2018春季新品质感柔软长袖衬衫男\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w120 center\">&yen;<span class=\"price\">99.00</span></div>\n\t\t\t\t\t<div class=\"left w120 center\">\n\t\t\t\t\t\t<button class=\"small-button\">-</button>\n\t\t\t\t\t\t<input class=\"center count\" type=\"text\" size=\"2\" value=\"1\">\n\t\t\t\t\t\t<button class=\"small-button\">+</button>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"left w120 center\">&yen;99.00</div>\n\t\t\t\t\t<div class=\"left w120 center\">\n\t\t\t\t\t\t<a href=\"javascript:void(0);\">删除</a>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<div id=\"cart-footer\">\n\t\t\t\t<div class=\"clear left\">\n\t\t\t\t\t<a id=\"clearSelected\" href=\"javascript:void(0);\">删除选中商品</a>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"right\">\n\t\t\t\t\t<span>总共选中了<span id=\"totalCount\">0</span>件商品</span>\n\t\t\t\t\t<span>总计: <span id=\"totalPrice\">&yen;0.00</span></span>\n\t\t\t\t\t<button id=\"pay\" class=\"big-button\">去结算</button>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t\t<script src=\"js/jquery.min.js\"></script>\n\t\t<script>\n\t\t\t// jQuery中的$函数(jQuery)的作用\n\t\t\t// 1. 如果$函数的参数是一个函数那么该函数绑定文档加载完成后要执行的回调函数\n\t\t\t// 2. 如果$函数的参数是一个选择器字符串那么$函数会返回对应的元素(jQuery对象)\n\t\t\t// 3. 如果$函数的参数是一个标签字符串那么$函数会创建该元素并返回(jQuery对象)\n\t\t\t// 4. 如果$函数的参数是一个原生的JS元素对象那么$函数会将它转变成jQuery对象\n\t\t\t$(function() {\n\t\t\t\t// this到底是什么要看具体的上下文环境\n\t\t\t\t// 简单的说函数中的this指的是谁调用了这个函数或者谁引发了这个函数的执行\n\t\t\t\t$('#selectAll').on('change', function(evt) {\n\t\t\t\t\t// 获取事件源的两种方式: evt.target或者this\n\t\t\t\t\t// 这里拿到的是原生的JavaScript对象\n\t\t\t\t\tif ($(this).prop('checked')) {\n\t\t\t\t\t\t$('.single-item input[type=\"checkbox\"]').prop('checked', true);\n\t\t\t\t\t\tcalcTotal();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$('.single-item input[type=\"checkbox\"]').prop('checked', false);\n\t\t\t\t\t\t$('#totalCount').text('0');\n\t\t\t\t\t\t$('#totalPrice').html('&yen;0.00');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// 为单个商品项的复选框绑定改变事件\n\t\t\t\t$('input[name=\"selectOne\"]').on('change', function() {\n\t\t\t\t\tif (!$(this).prop('checked')) {\n\t\t\t\t\t\t$('#selectAll').prop('checked', false);\n\t\t\t\t\t}\n\t\t\t\t\tcalcTotal();\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// 为删除选中商品超链接绑定事件回调\n\t\t\t\t$('#clearSelected').on('click', function() {\n\t\t\t\t\tif (confirm('确定要删除所选商品吗?')) {\n\t\t\t\t\t\t$('.single-item').each(function() {\n\t\t\t\t\t\t\tif ($(this).find('input[name=\"selectOne\"]').prop('checked')) {\n\t\t\t\t\t\t\t\t$(this).remove();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t\tcalcTotal();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// 为减少和添加商品数量的按钮绑定事件回调\n\t\t\t\t$('.single-item button').on('click', function(evt) {\n\t\t\t\t\t$(this).parent().parent().find('input[name=\"selectOne\"]').prop('checked', true);\n\t\t\t\t\tif ($(this).text() == '-') {\n\t\t\t\t\t\tvar count = parseInt($(this).next().val());\n\t\t\t\t\t\tif (count > 1) {\n\t\t\t\t\t\t\tcount -= 1;\n\t\t\t\t\t\t\t$(this).next().val(count);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\talert('商品数量最少为1');\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar count = parseInt($(this).prev().val());\n\t\t\t\t\t\tif (count < 200) {\n\t\t\t\t\t\t\tcount += 1;\n\t\t\t\t\t\t\t$(this).prev().val(count);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\talert('商品数量最多为200');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar price = parseFloat($(this).parent().prev().find('span').text());\n\t\t\t\t\t$(this).parent().next().html('&yen;' + (price * count).toFixed(2));\n\t\t\t\t\tcalcTotal();\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// 为单个商品项删除超链接绑定事件回调\n\t\t\t\t$('.single-item a').on('click', function() {\n\t\t\t\t\tif (window.confirm('确定要删除该项吗?')) {\n\t\t\t\t\t\t$(this).parent().parent().remove();\n\t\t\t\t\t\tcalcTotal();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// 为商品数量文本框绑定改变事件回调\n\t\t\t\t$('.single-item input[type=\"text\"]').on('change', function() {\n\t\t\t\t\t$(this).parent().parent().find('input[name=\"selectOne\"]').prop('checked', true);\n\t\t\t\t\tvar count = parseInt($(this).val());\n\t\t\t\t\t// 12 == \"12\"\n\t\t\t\t\t// \"12abc\" == 12\n\t\t\t\t\t// \"xyz\" == NaN\n\t\t\t\t\tif (count != $(this).val() || count < 1 || count > 200) {\n\t\t\t\t\t\talert('无效的商品数量值');\n\t\t\t\t\t\tcount = 1;\n\t\t\t\t\t\t$(this).val(count);\n\t\t\t\t\t}\n\t\t\t\t\tvar price = parseFloat($(this).parent().prev().find('span').text());\n\t\t\t\t\t$(this).parent().next().html('&yen;' + (price * count).toFixed(2));\n\t\t\t\t\tcalcTotal();\n\t\t\t\t});\n\t\t\t\t\n\t\t\t\t// 计算总计\n\t\t\t\tfunction calcTotal() {\n\t\t\t\t\tvar checkBoxes = $('input[name=\"selectOne\"]');\n\t\t\t\t\tvar priceSpans = $('.single-item .price');\n\t\t\t\t\tvar countInputs = $('.single-item .count');\n\t\t\t\t\tvar totalCount = 0;\n\t\t\t\t\tvar totalPrice = 0;\n\t\t\t\t\tfor (var i = 0; i < priceSpans.length; i += 1) {\n\t\t\t\t\t\t// 复选框被勾中的购物车项才进行计算\n\t\t\t\t\t\tif ($(checkBoxes[i]).prop('checked')) {\n\t\t\t\t\t\t\t// 强调: jQuery对象使用下标运算或get方法会还原成原生的JavaScript对象\n\t\t\t\t\t\t\tvar price = parseFloat($(priceSpans[i]).text());\n\t\t\t\t\t\t\tvar count = parseInt($(countInputs[i]).val());\n\t\t\t\t\t\t\ttotalCount += count;\n\t\t\t\t\t\t\ttotalPrice += price * count;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t$('#totalCount').text(totalCount);\n\t\t\t\t\t$('#totalPrice').html('&yen;' + totalPrice.toFixed(2));\n\t\t\t\t}\n\t\t\t});\n\t\t</script>\n\t</body>\n</html>\n"
  },
  {
    "path": "Day21-30/qq_link.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title></title>\n\t</head>\n\t<body>\n\t\t<a target=\"_blank\" href=\"http://wpa.qq.com/msgrd?v=3&uin=957658&site=qq&menu=yes\"><img border=\"0\" src=\"http://wpa.qq.com/pa?p=2:957658:53\" alt=\"点我聊一聊\" title=\"点我聊一聊\"/></a>\n\t</body>\n</html>"
  },
  {
    "path": "Day31-35/玩转Linux.md",
    "content": "## 玩转Linux操作系统\n\n### 操作系统发展史\n\n![](./res/history-of-os.png)\n\n### Linux概述\n\nLinux是一个通用操作系统。一个操作系统要负责任务调度、内存分配、处理外围设备I/O等操作。操作系统通常由内核和系统程序（设备驱动、底层库、shell、服务程序等）两部分组成。\n\nLinux内核是芬兰人Linus Torvalds开发的，于1991年9月发布。而Linux操作系统作为Internet时代的产物，它是由全世界许多开发者共同合作开发的，是一个自由的操作系统（注意是自由不是免费）。\n\n### Linux系统优点\n\n1. 通用操作系统，不跟特定的硬件绑定。\n2. 用C语言编写，有可移植性，有内核编程接口。\n3. 支持多用户和多任务，支持安全的分层文件系统。\n4. 大量的实用程序，完善的网络功能以及强大的支持文档。\n5. 可靠的安全性和良好的稳定性，对开发者更友好。\n\n### 基础命令\n\nLinux系统的命令通常都是如下所示的格式：\n\n```Shell\n命令名称 [命名参数] [命令对象]\n```\n\n1. 获取登录信息 - **w** / **who** / **last**。\n\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# w\n    23:31:16 up 12:16,  2 users,  load average: 0.00, 0.01, 0.05\n   USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT\n   root     pts/0    182.139.66.250   23:03    4.00s  0.02s  0.00s w\n   jackfrue pts/1    182.139.66.250   23:26    3:56   0.00s  0.00s -bash\n   [root@izwz97tbgo9lkabnat2lo8z ~]# who\n   root     pts/0        2018-04-12 23:03 (182.139.66.250)\n   jackfrued pts/1        2018-04-12 23:26 (182.139.66.250)\n   [root@izwz97tbgo9lkabnat2lo8z ~]# who am i\n   root     pts/0        2018-04-12 23:03 (182.139.66.250)\n   ```\n\n2. 查看自己使用的Shell - **ps**。\n\n   Shell也被称为“壳”，它是用户与内核交流的翻译官，简单的说就是人与计算机交互的接口。目前很多Linux系统默认的Shell都是bash（<u>B</u>ourne <u>A</u>gain <u>SH</u>ell），因为它可以使用Tab键进行命令补全、可以保存历史命令、可以方便的配置环境变量以及执行批处理操作等。\n\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# ps\n     PID TTY          TIME CMD\n    3531 pts/0    00:00:00 bash\n    3553 pts/0    00:00:00 ps\n   ```\n\n3. 查看命令的说明 - **whatis**。\n\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# whatis ps\n   ps (1)        - report a snapshot of the current processes.\n   [root@izwz97tbgo9lkabnat2lo8z ~]# whatis python\n   python (1)    - an interpreted, interactive, object-oriented programming language\n   ```\n\n4. 查看命令的位置 - **which** / **whereis**。\n\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# whereis ps\n   ps: /usr/bin/ps /usr/share/man/man1/ps.1.gz\n   [root@izwz97tbgo9lkabnat2lo8z ~]# whereis python\n   python: /usr/bin/python /usr/bin/python2.7 /usr/lib/python2.7 /usr/lib64/python2.7 /etc/python /usr/include/python2.7 /usr/share/man/man1/python.1.gz\n   [root@izwz97tbgo9lkabnat2lo8z ~]# which ps\n   /usr/bin/ps\n   [root@izwz97tbgo9lkabnat2lo8z ~]# which python\n   /usr/bin/python\n   ```\n\n5. 查看帮助文档 - **man** / **info** / **apropos**。\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# ps --help\n   Usage:\n    ps [options]\n    Try 'ps --help <simple|list|output|threads|misc|all>'\n     or 'ps --help <s|l|o|t|m|a>'\n    for additional help text.\n   For more details see ps(1).\n   [root@izwz97tbgo9lkabnat2lo8z ~]# man ps\n   PS(1)                                User Commands                                PS(1)\n   NAME\n          ps - report a snapshot of the current processes.\n   SYNOPSIS\n          ps [options]\n   DESCRIPTION\n   ...\n   [root@izwz97tbgo9lkabnat2lo8z ~]# info ps\n   ...\n   ```\n\n6. 切换用户 - **su**。\n\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# su hellokitty\n   [hellokitty@izwz97tbgo9lkabnat2lo8z root]$\n   ```\n\n7. 以管理员身份执行命令 - **sudo**。\n\n   ```Shell\n   [jackfrued@izwz97tbgo9lkabnat2lo8z ~]$ ls /root\n   ls: cannot open directory /root: Permission denied\n   [jackfrued@izwz97tbgo9lkabnat2lo8z ~]$ sudo ls /root\n   [sudo] password for jackfrued:\n   calendar.py  code  error.txt  hehe  hello.c  index.html  myconf  result.txt\n   ```\n\n   > **说明**：如果希望用户能够以管理员身份执行命令，用户必须在sudoers（/etc/sudoers）名单中。\n\n8. 登入登出相关 - **logout** / **exit** / **adduser** / **userdel** / **passwd** / **ssh**。\n\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# adduser jackfrued\n   [root@izwz97tbgo9lkabnat2lo8z ~]# passwd jackfrued\n   Changing password for user jackfrued.\n   New password:\n   Retype new password:\n   passwd: all authentication tokens updated successfully.\n   [root@izwz97tbgo9lkabnat2lo8z ~]# ssh hellokitty@1.2.3.4\n   hellokitty@1.2.3.4's password:\n   Last login: Thu Apr 12 23:05:32 2018 from 10.12.14.16\n   [hellokitty@izwz97tbgo9lkabnat2lo8z ~]$ logout\n   Connection to 1.2.3.4 closed.\n   [root@izwz97tbgo9lkabnat2lo8z ~]#\n   ```\n\n9. 查看系统和主机名 - **uname** / **hostname**。\n\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# uname\n   Linux\n   [root@izwz97tbgo9lkabnat2lo8z ~]# hostname\n   izwz97tbgo9lkabnat2lo8z\n   [root@iZwz97tbgo9lkabnat2lo8Z ~]# cat /etc/centos-release\n   CentOS Linux release 7.4.1708 (Core) \n   ```\n\n10. 重启和关机 - **reboot** / **init 6** / **shutdown** / **init 0**。\n\n11. 查看历史命令 - **history**。\n\n### 实用程序\n\n#### 文件和文件夹操作\n\n1. 创建/删除目录 - **mkdir** / **rmdir**。\n\n2. 创建/删除文件 - **touch** / **rm**。\n\n   - touch命令用于创建空白文件或修改文件时间。在Linux系统中一个文件有三种时间：\n     - 更改内容的时间（mtime）\n     - 更改权限的时间（ctime）\n     - 最后访问时间（atime）\n\n3. 切换和查看当前工作目录 - **cd** / **pwd**。\n\n4. 查看目录内容 - **ls**。\n\n5. 查看文件内容 - **cat** / **head** / **tail** / **more** / **less**。\n\n6. 拷贝/移动文件 - **cp** / **mv**。\n\n7. 查看文件及内容 - **find** / **grep**。\n\n   ```Shell\n   [root@izwz97tbgo9lkabnat2lo8z ~]# find -name *.html\n   ./index.html\n   ./code/index.html\n   [root@izwz97tbgo9lkabnat2lo8z ~]# grep \"<script>\" . -R -n\n   ./index.html:15:                <script>\n   ./code/index.html:2884: <script>\n   ./code/foo.html:2:<!--STATUS OK--><html> <head><meta ...\n   ```\n\n8. 符号链接 - **ln**。\n\n9. 压缩和归档 - **gzip** / **gunzip** / **xz** / **tar**。\n\n10. 其他工具 - **sort** / **uniq** / **diff** / **file** / **wc**。\n\n#### 管道和重定向\n\n1. 管道的使用 - **\\|**。\n2. 输出重定向和错误重定向 - **\\>** / **2\\>**。\n3. 输入重定向 - **\\<**。\n\n#### 别名\n\n1. **alias**\n2. **unalias**\n\n#### 其他程序\n\n1. 时间和日期 - **date** / **cal**。\n2. 录制操作脚本 - **script**。\n3. 给用户发送消息 - **mesg** / **write** / **wall** / **mail**。\n\n### 文件系统\n\n#### 文件和路径\n\n1. 命名规则\n2. 扩展名\n3. 隐藏文件\n4. 工作目录和主目录\n5. 绝对路径和相对路径\n\n#### 目录结构\n\n1. /bin - 基本命令的二进制文件\n2. /boot - 引导加载程序的静态文件\n3. /dev - 设备文件\n4. /etc - 配置文件\n5. /home - 用户主目录的父目录\n6. /lib - 共享库文件\n7. /lib64 - 共享64位库文件\n8. /lost+found - 存放未链接文件\n9. /media - 自动识别设备的挂载目录\n10. /mnt - 临时挂载文件系统的挂载点\n11. /opt - 可选插件软件包安装位置\n12. /proc -  内核和进程信息\n13. /root - root账户主目录\n14. /run - 存放系统运行时需要的东西\n15. /sbin - 超级用户的二进制文件\n16. /sys - 设备的伪文件系统\n17. /tmp - 临时文件夹\n18. /usr - 用户应用目录\n19. /var - 变量数据目录\n\n#### 访问权限\n\n1. **chmod**。\n2. **chown**。\n\n#### 磁盘管理\n\n1. 列出文件系统的磁盘使用状况 - **df**。\n2. 磁盘分区表操作 - **fdisk**。\n3. 格式化文件系统 - **mkfs**。\n4. 文件系统检查 - **fsck**。\n5. 挂载/卸载 - **mount** / **umount**。\n\n### 编辑器vim\n\n1. 启动和退出\n\n2. 命令模式和编辑模式\n\n3. 光标操作\n\n4. 文本操作\n\n5. 查找和替换\n\n   /正则表达式\n\n   :1,$s/正则表达式/替换后的内容/gice\n\n   g - global\n\n   i - ignore case\n\n   c - confirm\n\n   e - error\n\n6. 参数设定\n\n   .vimrc\n\n   set ts=4\n\n   set nu\n\n7. 高级技巧\n\n   - 映射快捷键\n     - inoremap key:...\n   - 录制宏\n     - 在命令模式下输入qa开始录制宏（qa/qb/qc/qd）\n     - 执行你的操作，这些操作都会被录制下来\n     - 如果要录制的操作完成了，按q结束录制\n     - @a播放宏（1000@a - 将宏播放1000次）\n\n### 环境变量\n\n1. HOME\n2. SHELL\n3. HISTSIZE\n4. RANDOM\n5. PATH\n\n### 软件安装和配置\n\n#### yum\n\n- yum update\n- yum install / yum remove\n- yum list / yum search\n- yum makecache\n\n#### rpm\n\n- rpm -ivh \\-\\-force \\-\\-nodeps\n- rpm -e \n- rpm -qa | grep\n\n#### 源代码构建安装\n\n- ...\n- make && make install\n\n#### 实例\n\n1. 安装MySQL。\n2. 安装Redis。\n3. 安装NginX。\n\n### 配置服务\n\n1. systemctl start / stop / restart / status\n2. systemctl enable / disable\n3. 计划任务 - **crontab**。\n4. 开机自启。\n\n### 网络访问和管理\n\n1. 通过网络获取资源 - **wget**。\n   - -b 后台下载模式\n   - -O 下载到指定的目录\n   - -r 递归下载\n2. 显示/操作网络配置（旧） - **ipconfig**。\n3. 显示/操作网络配置（新） - **ip**。\n4. 网络可达性检查 - **ping**。\n5. 查看网络服务和端口 - **netstat**。\n6. 安全文件拷贝 - **scp**。\n7. 安全文件传输 - **sftp**。\n\n### Shell和Shell编程\n\n1. 通配符。\n2. 后台运行。\n\n### 其他内容\n\n1. awk\n2. sed\n3. xargs"
  },
  {
    "path": "Day36-40/NoSQL入门.md",
    "content": "## NoSQL入门\n\n### NoSQL概述\n\n\n\n### 主流NoSQL数据库\n\n\n\n### Redis概述\n\n\n\n### MongoDB概述\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Day36-40/关系型数据库MySQL.md",
    "content": "## 关系型数据入门\n\n### 关系型数据概述\n\n1. 数据持久化。\n2. 数据库发展史。\n3. 关系型数据库特点。\n4. E-R图。\n5. 关系型数据库产品。\n\n### MySQL简介\n\n1. 安装和配置。\n2. 常用命令。\n\n### SQL详解\n\n1. DDL\n2. DML\n3. DQL\n\n### Python数据库编程\n\n1. MySQLdb\n2. PyMySQL\n\n### ORM概述\n\n\n"
  },
  {
    "path": "Day41-55/Django2实战01.md",
    "content": "## Django 2.x实战(01) - 快速上手\n\nWeb开发的早期阶段，开发者需要手动编写每个页面，例如一个新闻门户网站，每天都要修改它的HTML页面，这样随着网站规模和体量的增大，这种方式就变得极度糟糕。为了解决这个问题，开发人员想到了用外部程序来为Web服务器生成动态内容，也就是说HTML页面以及页面中的动态内容不再通过手动编写而是通过程序自动生成。最早的时候，这项技术被称为CGI（公共网关接口），当然随着时间的推移，CGI暴露出的问题也越来越多，例如大量重复的样板代码，总体性能较为低下等，因此在呼唤新的英雄的时代，PHP、ASP、JSP这类Web应用开发技术在上世纪90年代中后期如雨后春笋般涌现。通常我们说的Web应用是指通过浏览器来访问网络资源的应用程序，因为浏览器的普及性以及易用性，Web应用使用起来方便简单，而且在应用更新时用户通常不需要做任何的处理就能使用更新后的应用，而且也不用关心用户到底用的是什么操作系统，甚至不用区分是PC端还是移动端。\n\n### Web应用机制和术语\n\n下图向我们展示了Web应用的工作流程，其中涉及到的术语如下表所示。\n\n![](./res/web-application.png)\n\n> 说明：相信有经验的读者会发现，这张图中其实还少了很多东西，例如反向代理服务器、数据库服务器、防火墙等，而且图中的每个节点在实际项目部署时可能是一组节点组成的集群。当然，如果你对这些没有什么概念也不要紧，后续的课程中我们会为大家进行讲解。\n\n| 术语          | 解释                                                         |\n| ------------- | ------------------------------------------------------------ |\n| **URL/URI**   | 统一资源定位符/统一资源标识符，网络资源的唯一标识            |\n| **域名**      | 与Web服务器地址对应的一个易于记忆的字符串名字                |\n| **DNS**       | 域名解析服务，可以将域名转换成对应的IP地址                   |\n| **IP地址**    | 网络上的主机的身份标识，通过IP地址可以区分不同的主机         |\n| **HTTP**      | 超文本传输协议，应用层协议，万维网数据通信的基础             |\n| **反向代理**  | 代理客户端向服务器发出请求，然后将服务器返回的资源返回给客户端 |\n| **Web服务器** | 接受HTTP请求，然后返回HTML文件、纯文本文件、图像等资源给请求者 |\n| **Nginx**     | 高性能的Web服务器，也可以用作[反向代理](https://zh.wikipedia.org/wiki/%E5%8F%8D%E5%90%91%E4%BB%A3%E7%90%86)，[负载均衡](https://zh.wikipedia.org/wiki/%E8%B4%9F%E8%BD%BD%E5%9D%87%E8%A1%A1) 和 [HTTP缓存](https://zh.wikipedia.org/wiki/HTTP%E7%BC%93%E5%AD%98) |\n\n#### HTTP协议\n\n这里我们稍微费一些笔墨来谈谈上面提到的HTTP。HTTP（超文本传输协议）是构建于TCP（传输控制协议）之上应用级协议，它利用了TCP提供的可靠的传输服务实现了Web应用中的数据交换。按照维基百科上的介绍，设计HTTP最初的目的是为了提供一种发布和接收[HTML](https://zh.wikipedia.org/wiki/HTML)页面的方法，也就是说这个协议是浏览器和Web服务器之间传输的数据的载体。关于这个协议的详细信息以及目前的发展状况，大家可以阅读阮一峰老师的[《HTTP 协议入门》](http://www.ruanyifeng.com/blog/2016/08/http.html)、[《互联网协议入门》](http://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html)系列以及[《图解HTTPS协议》](http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html)进行了解，下图是我于2009年9月10日凌晨4点在四川省网络通信技术重点实验室用开源协议分析工具Ethereal（抓包工具WireShark的前身）截取的访问百度首页时的HTTP请求和响应的报文（协议数据），由于Ethereal截取的是经过网络适配器的数据，因此可以清晰的看到从物理链路层到应用层的协议数据。\n\nHTTP请求（请求行+请求头+空行+[消息体]）：\n\n![](./res/http-request.png)\n\nHTTP响应（响应行+响应头+空行+消息体）：\n\n![](./res/http-response.png)\n\n>  说明：但愿这两张如同泛黄的照片般的截图帮助你大概的了解到HTTP是一个怎样的协议。\n\n### Django概述\n\nPython的Web框架有上百个，比它的关键字还要多。所谓Web框架，就是用于开发Web服务器端应用的基础设施（通常指封装好的模块和一系列的工具）。事实上，即便没有Web框架，我们仍然可以通过socket或[CGI](https://zh.wikipedia.org/wiki/%E9%80%9A%E7%94%A8%E7%BD%91%E5%85%B3%E6%8E%A5%E5%8F%A3)来开发Web服务器端应用，但是这样做的成本和代价在实际开发中通常是不能接受的。通过Web框架，我们可以化繁为简，同时降低创建、更新、扩展应用程序的工作量。Python的Web框架中比较有名的有：Flask、Django、Tornado、Pyramid、Bottle、Web2py、web.py等。\n\n在基于Python的Web框架中，Django是所有重量级选手中最有代表性的一位，开发者可以基于Django快速的开发可靠的Web应用程序，因为它减少了Web开发中不必要的开销，对常用的设计和开发模式进行了封装，并对MVC架构提供了支持（MTV）。许多成功的网站和App都是基于Django框架构建的，国内比较有代表性的网站包括：知乎、豆瓣网、果壳网、搜狐闪电邮箱、101围棋网、海报时尚网、背书吧、堆糖、手机搜狐网、咕咚、爱福窝、果库等。\n\n![](./res/mvc.png)\n\nDjango诞生于2003年，它是一个在真正的应用中成长起来的项目，由劳伦斯出版集团旗下在线新闻网站的内容管理系统（CMS）研发团队编写（主要是Adrian Holovaty和Simon Willison），以比利时的吉普赛爵士吉他手Django Reinhardt来命名，在2005年夏天作为开源框架发布。使用Django能用很短的时间构建出功能完备的网站，因为它代替程序员完成了所有乏味和重复的劳动，剩下真正有意义的核心业务给程序员，这一点就是对DRY（Don't Repeat Yourself）理念的最好践行。\n\n### 快速上手\n\n#### 准备工作\n\n1. 检查Python环境：Django 1.11需要Python 2.7或Python 3.4以上的版本；Django 2.0需要Python 3.4以上的版本。\n\n   ```Shell\n   $ python3 --version\n   ```\n\n   ```Shell\n   $ python3\n   >>> import sys\n   >>> sys.version\n   >>> sys.version_info\n   ```\n\n2. 创建项目文件夹并切换到该目录，例如我们要实例一个OA（办公自动化）项目。\n\n   ```Shell\n   $ mkdir oa\n   $ cd oa\n   ```\n\n3. 创建并激活虚拟环境。\n\n   ```Shell\n   $ python3 -m venv venv\n   $ source venv/bin/activate\n   ```\n   > 注意：Windows系统下是执行`venv/Scripts/activate.bat`批处理文件。\n\n4. 更新包管理工具pip。\n\n   ```Shell\n   (venv)$ python -m pip install --upgrade pip\n   ```\n   > 注意：请注意终端提示符发生的变化，前面的`(venv)`说明我们已经进入虚拟环境，而虚拟环境下的python和pip已经是Python 3的解释器和包管理工具了。\n\n5. 安装Django。\n\n   ```Shell\n   (venv)$ pip install django\n   ```\n\n   或指定版本号来安装对应的Django的版本。\n\n   ```Shell\n   (venv)$ pip install django==1.11\n   ```\n\n6. 检查Django的版本。\n\n   ```Shell\n   (venv)$ python -m django --version\n   (venv)$ django-admin --version\n   ```\n\n   ```Shell\n   (venv)$ python\n   >>> import django\n   >>> django.get_version()\n   ```\n   下图展示了Django版本和Python版本的对应关系，在我们的项目中我们选择了最新的Django 2.0的版本。\n\n   | Django版本 | Python版本              |\n   | ---------- | ----------------------- |\n   | 1.8        | 2.7、3.2、3.3、3.4、3.5 |\n   | 1.9、1.10  | 2.7、3.4、3.5           |\n   | 1.11       | 2.7、3.4、3.5、3.6      |\n   | 2.0        | 3.4、3.5、3.6           |\n\n   > 说明：在创建这篇文章时Django 2.1版本尚未正式发布，因此我们的教程使用了2.0.5版本。\n\n7. 使用`django-admin`创建项目，项目命名为oa。\n\n   ```Shell\n   (venv)$ django-admin startproject oa .\n   ```\n\n   > 注意：上面的命令最后的那个点，它表示在当前路径下创建项目。\n\n   执行上面的命令后看看生成的文件和文件夹，它们的作用如下所示：\n\n   - `manage.py`： 一个让你用各种方式管理 Django 项目的命令行工具。\n   - `oa/__init__.py`：一个空文件，告诉 Python 这个目录应该被认为是一个 Python 包。\n   - `oa/settings.py`：Django 项目的配置文件。\n   - `oa/urls.py`：Django 项目的 URL 声明，就像你网站的“目录”。\n   - `oa/wsgi.py`：作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。\n\n8. 启动服务器运行项目。\n\n   ```Shell\n   (venv)$ python manage.py runserver\n   ```\n\n   在浏览器中输入<http://127.0.0.1:8000>访问我们的服务器，效果如下图所示。\n\n   ![](./res/django-index-1.png)\n\n\n   > 说明1：刚刚启动的是Django自带的用于开发和测试的服务器，它是一个用纯Python编写的轻量级Web服务器，但它并不是真正意义上的生产级别的服务器，千万不要将这个服务器用于和生产环境相关的任何地方。\n\n   > 说明2：用于开发的服务器在需要的情况下会对每一次的访问请求重新载入一遍Python代码。所以你不需要为了让修改的代码生效而频繁的重新启动服务器。然而，一些动作，比如添加新文件，将不会触发自动重新加载，这时你得自己手动重启服务器。\n\n   > 说明3：可以通过`python manage.py help`命令查看可用命令列表；在启动服务器时，也可以通过`python manage.py runserver 1.2.3.4:56789`来指定绑定的IP地址和端口。\n\n   > 说明4：可以通过Ctrl+C来终止服务器的运行。\n\n9. 接下来我们进入项目目录oa并修改配置文件settings.py，Django是一个支持国际化和本地化的框架，因此刚才我们看到的默认首页也是支持国际化的，我们将默认语言修改为中文，时区设置为东八区。\n\n   ```Shell\n   (venv)$ cd oa\n   (venv)$ vim settings.py\n   ```\n\n   ```Python\n   # 此处省略上面的内容\n   \n   # 设置语言代码\n   LANGUAGE_CODE = 'zh-hans'\n   # 设置时区\n   TIME_ZONE = 'Asia/Chongqing'\n   \n   # 此处省略下面的内容\n   ```\n\n10. 回到manage.py所在的目录，刷新刚才的页面。\n\n  ```Shell\n  (venv)$ cd ..\n  (venv)$ python manage.py runserver\n  ```\n\n  ![](./res/django-index-2.png)\n\n#### 动态页面\n\n1. 创建名为hrs（人力资源系统）的应用（注：一个项目可以包含多个应用）。\n\n   ```Shell\n   (venv)$ python manage.py startapp hrs\n   ```\n\n   执行上面的命令会在当前路径下创建hrs目录，其目录结构如下所示：\n\n   - `__init__.py`：一个空文件，告诉 Python 这个目录应该被认为是一个 Python 包。\n   - `admin.py`：可以用来注册模型，让Django自动创建管理界面。\n   -  `apps.py`：当前应用的配置。\n   - `migrations`：存放与模型有关的数据库迁移信息。\n     - `__init__.py`：一个空文件，告诉 Python 这个目录应该被认为是一个 Python 包。\n   - `models.py`：存放应用的数据模型，即实体类及其之间的关系（MVC/MVT中的M）。\n   - `tests.py`：包含测试应用各项功能的测试类和测试函数。\n   - `views.py`：处理请求并返回响应的函数（MVC中的C，MVT中的V）。\n2. 进入应用目录修改视图文件views.py。\n\n   ```Shell\n   (venv)$ cd hrs\n   (venv)$ vim views.py\n   ```\n\n   ```Python\n   from django.http import HttpResponse\n   \n   \n   def index(request):\n       return HttpResponse('<h1>Hello, Django!</h1>')\n   \n   ```\n\n3. 在应用目录创建一个urls.py文件并映射URL。\n\n   ```Shell\n   (venv)$ touch urls.py\n   (venv)$ vim urls.py\n   ```\n\n   ```Python\n   from django.urls import path\n   \n   from hrs import views\n   \n   urlpatterns = [\n       path('', views.index, name='index'),\n   ]\n   ```\n   > 说明：上面使用的path函数是Django 2.x中新添加的函数，除此之外还有re_path是支持正则表达式的URL映射函数；Django 1.x中是用url函数来设定URL映射。\n\n4. 切换到项目目录，修改该目录下的urls.py文件，对应用中设定的URL进行合并。\n\n   ```Shell\n   (venv) $ cd ..\n   (venv) $ cd oa\n   (venv) $ vim urls.py\n   ```\n\n   ```Python\n   from django.contrib import admin\n   from django.urls import path, include\n   \n   urlpatterns = [\n       path('admin/', admin.site.urls),\n       path('hrs/', include('hrs.urls')),\n   ]\n   ```\n\n5. 启动项目并访问应用。\n\n   ```Shell\n   (venv)$ cd ..\n   (venv)$ python manage.py runserver\n   ```\n\n   在浏览器中访问<http://localhost:8000/hrs>。\n\n   > 说明：如果想实现远程访问，需要先确认防火墙是否已经打开了8000端口，而且需要在配置文件settings.py中修改ALLOWED_HOSTS的设置，添加一个'*'表示允许所有的客户端访问Web应用。\n\n6. 修改views.py生成动态内容。\n\n   ```Shell\n   (venv)$ cd hrs\n   (venv)$ vim views.py\n   ```\n\n   ```Python\n   from django.http import HttpResponse\n   \n   from io import StringIO\n   from random import randrange\n   \n   fruits = ['苹果', '草莓', '榴莲', '香蕉', '葡萄', '山竹', '蓝莓', '西瓜']\n   \n   \n   def index(request):\n       output = StringIO()\n       output.write('<html>\\n')\n       output.write('<head>\\n')\n       output.write('\\t<meta charset=\"utf-8\">\\n')\n       output.write('\\t<title>首页</title>')\n       output.write('</head>\\n')\n       output.write('<body>\\n')\n       output.write('\\t<h1>Hello, world!</h1>\\n')\n       output.write('\\t<hr>\\n')\n       output.write('\\t<ol>\\n')\n       for _ in range(3):\n           rindex = randrange(0, len(fruits))\n           output.write('\\t\\t<li>' + fruits[rindex]  + '</li>\\n')\n       output.write('\\t</ol>\\n')\n       output.write('</body>\\n')\n       output.write('</html>\\n')\n       return HttpResponse(output.getvalue())\n   \n   ```\n\n#### 使用视图模板\n\n上面通过拼接HTML代码的方式生成动态视图的做法在实际开发中是无能接受的，这一点我相信是不言而喻的。为了解决这个问题，我们可以提前准备一个模板页，所谓模板页就是一个带占位符的HTML页面，当我们将程序中获得的数据替换掉页面中的占位符时，一个动态页面就产生了。\n\n我们可以用Django框架中template模块的Template类创建模板对象，通过模板对象的render方法实现对模板的渲染。所谓的渲染就是用数据替换掉模板页中的占位符，Django框架通过shortcuts模块的快捷函数render简化了渲染模板的操作，具体的用法如下所示。\n\n1. 先回到manage.py文件所在的目录创建一个templates文件夹。\n\n   ```Shell\n   (venv)$ cd ..\n   (venv)$ mkdir templates\n   (venv)$ cd templates\n   ```\n\n2. 创建模板页index.html。\n\n   ```Shell\n   (venv)$ touch index.html\n   (venv)$ vim index.html\n   ```\n   ```HTML\n   <!DOCTYPE html>\n   <html lang=\"en\">\n   <head>\n   \t<meta charset=\"UTF-8\">\n   \t<title>首页</title>\n   </head>\n   <body>\n   \t<h1>{{ greeting }}</h1>\n   \t<hr>\n   \t<h3>今天推荐{{ num }}种水果是:</h3>\n   \t<ul>\n   \t\t{% for fruit in fruits %}\n   \t\t<li>{{ fruit }}</li>\n   \t\t{% endfor %}\n   \t</ul>\n   </body>\n   </html>\n   ```\n   注意在模板页中我们使用了`{{ greeting }}`这样的模板占位符语法，也使用了`{% for %}`这样的模板指令，如果对此不熟悉并不要紧，我们会在后续的内容中进一步的讲解模板的用法。\n\n3. 回到应用目录，修改views.py文件。\n\n   ```Shell\n   (venv)$ cd ..\n   (venv)$ cd hrs\n   (venv)$ vim views.py\n   ```\n\n   ```Python\n   from django.shortcuts import render\n   from random import randrange\n   \n   \n   def index(request):\n       fruits = ['苹果', '香蕉', '草莓', '葡萄', '山竹', '杨梅', '西瓜', '榴莲']\n       start, end = 0, randrange(len(fruits))\n       ctx = {\n           'greeting': 'Hello, Django!',\n           'num': end + 1,\n           'fruits': fruits[start:end + 1]\n       }\n       return render(request, 'index.html', ctx)\n   \n   ```\n\n   到此为止，我们还没有办法让views.py中的render函数找到模板文件index.html，为此我们需要修改settings.py文件，配置模板文件所在的路径。\n\n4. 切换到项目目录修改settings.py文件。\n\n   ```Shell\n   (venv)$ cd ..\n   (venv)$ cd oa\n   (venv)$ vim settings.py\n   ```\n\n   ```Python\n   # 此处省略上面的内容\n   \n   TEMPLATES = [\n       {\n           'BACKEND': 'django.template.backends.django.DjangoTemplates',\n           'DIRS': [os.path.join(BASE_DIR, 'templates')],\n           'APP_DIRS': True,\n           'OPTIONS': {\n               'context_processors': [\n                   'django.template.context_processors.debug',\n                   'django.template.context_processors.request',\n                   'django.contrib.auth.context_processors.auth',\n                   'django.contrib.messages.context_processors.messages',\n               ],\n           },\n       },\n   ]\n   \n   # 此处省略下面的内容\n   ```\n\n5. 重新运行项目并查看结果。\n\n   ```Shell\n   (venv)$ cd ..\n   (venv)$ python manage.py runserver\n   ```\n\n   ![](./res/runserver.png)\n\n### 总结\n\n至此，我们已经利用Django框架完成了一个非常小的Web应用，虽然它并没有任何的实际价值，但是我们需要通过这个项目了解到Django框架的使用方式。当然，如果使用PyCharm的Professional版本，也可以通过PyCharm的创建项目的选项直接创建Django项目，使用PyCharm的好处在于编写代码时可以获得代码提示、错误修复、自动导入等功能，从而提升开发效率，但是代价是需要支付对应的费用才能使用专业版的PyCharm，社区版的PyCharm中并未包含对Web框架的支持。\n\n此外，学习Django最好的资料肯定是它的[官方文档](https://docs.djangoproject.com/zh-hans/2.0/)，除此之外图灵社区最近出版的[《Django基础教程》](http://www.ituring.com.cn/book/2630)也是非常适合初学者的读物。 "
  },
  {
    "path": "Day41-55/Django2实战02.md",
    "content": "## Django 2.x实战(02) - 深入模型\n\n在上一个章节中，我们提到了Django是一个基于MVC架构的Web框架，MVC架构要追求的是模型和视图的解耦合，而其中的模型说得更直白一些就是数据，所以通常也被称作数据模型。在实际的项目中，数据模型通常通过数据库实现持久化操作，而关系型数据库在很长一段时间都是持久化的首选方案，在我们的OA项目中，我们选择使用MySQL来实现数据持久化。\n\n### 配置关系型数据库MySQL \n\n1. 进入oa文件夹，修改项目的settings.py文件，首先将我们之前创建的应用hrs添加已安装的项目中，然后配置MySQL作为持久化方案。\n\n   ```Shell\n   (venv)$ cd oa\n   (venv)$ vim settings.py\n   ```\n\n   ```Python\n   # 此处省略上面的代码\n   \n   INSTALLED_APPS = [\n       'django.contrib.admin',\n       'django.contrib.auth',\n       'django.contrib.contenttypes',\n       'django.contrib.sessions',\n       'django.contrib.messages',\n       'django.contrib.staticfiles',\n       'hrs',\n   ]\n   \n   DATABASES = {\n       'default': {\n           'ENGINE': 'django.db.backends.mysql',\n           'NAME': 'oa',\n           'HOST': 'localhost',\n           'PORT': 3306,\n           'USER': 'root',\n           'PASSWORD': '123456',\n       }\n   }\n   \n   # 此处省略下面的代码\n   ```\n\n   在配置ENGINE属性时，常用的可选值包括：\n\n   - `'django.db.backends.sqlite3'`：SQLite嵌入式数据库\n   - `'django.db.backends.postgresql'`：BSD许可证下发行的开源关系型数据库产品\n   - `'django.db.backends.mysql'`：转手多次目前属于甲骨文公司的经济高效的数据库产品\n   - `'django.db.backends.oracle'`：甲骨文公司的旗舰关系型数据库产品\n\n   其他的配置可以参考官方文档中[数据库配置](https://docs.djangoproject.com/zh-hans/2.0/ref/databases/#third-party-notes)的部分。\n\n   NAME属性代表数据库的名称，如果使用SQLite它对应着一个文件，在这种情况下NAME的属性值应该是一个绝对路径。如果使用其他关系型数据库，还要配置对应的HOST（主机）、PORT（端口）、USER（用户名）、PASSWORD（口令）等属性。\n\n2. 安装MySQL客户端工具，Python 3中使用PyMySQL，Python 2中用MySQLdb。\n\n   ```Shell\n   (venv)$ pip install pymysql\n   ```\n\n   如果使用Python 3需要修改**项目**的`__init__.py`文件并加入如下所示的代码，这段代码的作用是将PyMySQL视为MySQLdb来使用，从而避免Django找不到连接MySQL的客户端工具而询问你：“Did you install mysqlclient? ”（你安装了mysqlclient吗？）。\n\n   ```Python\n   import pymysql\n   \n   pymysql.install_as_MySQLdb()\n   ```\n\n3. 运行manage.py并指定migrate参数实现数据库迁移，为应用程序创建对应的数据表，当然在此之前需要**先启动MySQL数据库服务器并创建名为oa的数据库**，在MySQL中创建数据库的语句如下所示。\n\n   ```SQL\n   drop database if exists oa;\n   create database oa default charset utf8;\n   ```\n\n   ```Shell\n   (venv)$ cd ..\n   (venv)$ python manage.py migrate\n   Operations to perform:\n     Apply all migrations: admin, auth, contenttypes, sessions\n   Running migrations:\n     Applying contenttypes.0001_initial... OK\n     Applying auth.0001_initial... OK\n     Applying admin.0001_initial... OK\n     Applying admin.0002_logentry_remove_auto_add... OK\n     Applying contenttypes.0002_remove_content_type_name... OK\n     Applying auth.0002_alter_permission_name_max_length... OK\n     Applying auth.0003_alter_user_email_max_length... OK\n     Applying auth.0004_alter_user_username_opts... OK\n     Applying auth.0005_alter_user_last_login_null... OK\n     Applying auth.0006_require_contenttypes_0002... OK\n     Applying auth.0007_alter_validators_add_error_messages... OK\n     Applying auth.0008_alter_user_username_max_length... OK\n     Applying auth.0009_alter_user_last_name_max_length... OK\n     Applying sessions.0001_initial... OK\n   ```\n\n4. 可以看到，Django帮助我们创建了10张表，这些都是使用Django框架需要的东西，稍后我们就会用到这些表。除此之外，我们还应该为我们自己的应用创建数据模型。如果要在hrs应用中实现对部门和员工的管理，我们可以创建如下所示的数据模型。\n\n   ```Shell\n   (venv)$ cd hrs\n   (venv)$ vim models.py\n   ```\n\n   ```Python\n   from django.db import models\n   \n   \n   class Dept(models.Model):\n       \"\"\"部门类\"\"\"\n       \n       no = models.IntegerField(primary_key=True, db_column='dno', verbose_name='部门编号')\n       name = models.CharField(max_length=20, db_column='dname', verbose_name='部门名称')\n       location = models.CharField(max_length=10, db_column='dloc', verbose_name='部门所在地')\n   \n       class Meta:\n           db_table = 'tb_dept'\n   \n   \n   class Emp(models.Model):\n       \"\"\"员工类\"\"\"\n       \n       no = models.IntegerField(primary_key=True, db_column='eno', verbose_name='员工编号')\n       name = models.CharField(max_length=20, db_column='ename', verbose_name='员工姓名')\n       job = models.CharField(max_length=10, verbose_name='职位')\n       # 自参照完整性多对一外键关联\n       mgr = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='主管编号')\n       sal = models.DecimalField(max_digits=7, decimal_places=2, verbose_name='月薪')\n       comm = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True, verbose_name='补贴')\n       dept = models.ForeignKey(Dept, db_column='dno', on_delete=models.PROTECT, verbose_name='所在部门')\n   \n       class Meta:\n           db_table = 'tb_emp'\n   \n   \n   ```\n   > 说明：上面定义模型时使用了字段类及其属性，其中IntegerField对应数据库中的integer类型，CharField对应数据库的varchar类型，DecimalField对应数据库的decimal类型，ForeignKey用来建立多对一外键关联。字段属性primary_key用于设置主键，max_length用来设置字段的最大长度，db_column用来设置数据库中与字段对应的列，verbose_name则设置了Django后台管理系统中该字段显示的名称。如果对这些东西感到很困惑也不要紧，文末提供了字段类、字段属性、元数据选项等设置的相关说明，不清楚的读者可以稍后查看对应的参考指南。\n\n5. 通过模型创建数据表。\n\n   ```Shell\n   (venv)$ cd ..\n   (venv)$ python manage.py makemigrations hrs\n   Migrations for 'hrs':\n     hrs/migrations/0001_initial.py\n       - Create model Dept\n       - Create model Emp\n   (venv)$ python manage.py migrate\n   Operations to perform:\n     Apply all migrations: admin, auth, contenttypes, hrs, sessions\n   Running migrations:\n     Applying hrs.0001_initial... OK\n   ```\n\n   执行完数据迁移操作之后，可以在通过图形化的MySQL客户端工具查看到E-R图（实体关系图）。\n\n   ![](./res/er-graph.png)\n\n### 在后台管理模型\n\n1. 创建超级管理员账号。\n\n   ```Shell\n   (venv)$ python manage.py createsuperuser\n   Username (leave blank to use 'hao'): jackfrued\n   Email address: jackfrued@126.com\n   Password: \n   Password (again): \n   Superuser created successfully.\n   ```\n\n2. 启动Web服务器，登录后台管理系统。\n\n   ```Shell\n   (venv)$ python manage.py runserver\n   ```\n\n   访问<http://127.0.0.1:8000/admin>，会来到如下图所示的登录界面。\n\n   ![](./res/admin-login.png)\n\n   登录后进入管理员操作平台。\n\n   ![](./res/admin-welcome.png)\n\n   至此我们还没有看到之前创建的模型类，需要在应用的admin.py文件中模型进行注册。\n\n3. 注册模型类。\n\n   ```Shell\n   (venv)$ cd hrs\n   (venv)$ vim admin.py\n   ```\n\n   ```Python\n   from django.contrib import admin\n   \n   from hrs.models import Emp, Dept\n   \n   admin.site.register(Dept)\n   admin.site.register(Emp)\n   \n   ```\n\n   注册模型类后，就可以在后台管理系统中看到它们。\n\n   ![](./res/admin-model.png)\n\n4. 对模型进行CRUD操作。\n\n   可以在管理员平台对模型进行C（新增）R（查看）U（更新）D（删除）操作，如下图所示。\n\n   添加新的部门。\n\n   ![](./res/admin-model-create.png)\n\n   查看所有部门。\n\n   ![](./res/admin-model-read.png)\n\n   更新和删除部门。\n\n   ![](./res/admin-model-delete-and-update.png)\n\n5. 注册模型管理类。\n\n   再次修改admin.py文件，通过注册模型管理类，可以在后台管理系统中更好的管理模型。\n\n   ```Python\n   from django.contrib import admin\n   \n   from hrs.models import Emp, Dept\n   \n   \n   class DeptAdmin(admin.ModelAdmin):\n   \n       list_display = ('no', 'name', 'location')\n       ordering = ('no', )\n   \n   \n   class EmpAdmin(admin.ModelAdmin):\n   \n       list_display = ('no', 'name', 'job', 'mgr', 'sal', 'comm', 'dept')\n       search_fields = ('name', 'job')\n   \n   \n   admin.site.register(Dept, DeptAdmin)\n   admin.site.register(Emp, EmpAdmin)\n   \n   ```\n\n   ![](./res/admin-model-depts.png)\n\n   ![](./res/admin-model-emps.png)\n\n   为了更好的查看模型数据，可以为Dept和Emp两个模型类添加`__str__`魔法方法。\n\n   ```Python\n   from django.db import models\n   \n   \n   class Dept(models.Model):\n       \"\"\"部门类\"\"\"\n       \n       # 此处省略上面的代码\n       \n       def __str__(self):\n           return self.name\n   \n       # 此处省略下面的代码\n   \n   \n   class Emp(models.Model):\n       \"\"\"员工类\"\"\"\n       \n       # 此处省略上面的代码\n       \n       mgr = models.ForeignKey('self', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='直接主管')\n       \n       # 此处省略下面的代码\n       \n       # 此处省略上面的代码\n   \n       def __str__(self):\n           return self.name\n   \n       # 此处省略下面的代码\n   \n   ```\n\n   修改代码后刷新查看Emp模型的页面，效果如下图所示。\n\n   ![](./res/admin-model-emps-modified.png)\n\n### 使用ORM完成模型的CRUD操作\n\n在了解了Django提供的模型管理平台之后，我们来看看如何从代码层面完成对模型的CRUD（Create / Read / Update / Delete）操作。我们可以通过manage.py开启Shell交互式环境，然后使用Django内置的ORM框架对模型进行CRUD操作。\n\n```Shell\n(venv)$ cd ..\n(venv)$ python manage.py shell\nPython 3.6.4 (v3.6.4:d48ecebad5, Dec 18 2017, 21:07:28) \n[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.\n(InteractiveConsole)\n>>> \n```\n\n#### 新增\n\n```Shell\n>>>\n>>> from hrs.models import Dept, Emp\n>>> dept = Dept(40, '研发2部', '深圳')\n>>> dept.save()\n```\n\n#### 更新\n\n```Shell\n>>>\n>>> dept.name = '研发3部'\n>>> dept.save()\n```\n\n#### 查询\n\n查询所有对象。\n\n```Shell\n>>>\n>>> Dept.objects.all()\n<QuerySet [<Dept: 研发1部>, <Dept: 销售1部>, <Dept: 运维1部>, <Dept: 研发3部>]>\n```\n\n过滤数据。\n\n```Shell\n>>> \n>>> Dept.objects.filter(name='研发3部') # 查询部门名称为“研发3部”的部门\n<QuerySet [<Dept: 研发3部>]>\n>>>\n>>> Dept.objects.filter(name__contains='研发') # 查询部门名称包含“研发”的部门(模糊查询)\n<QuerySet [<Dept: 研发1部>, <Dept: 研发3部>]>\n>>>\n>>> Dept.objects.filter(no__gt=10).filter(no__lt=40) # 查询部门编号大于10小于40的部门\n<QuerySet [<Dept: 销售1部>, <Dept: 运维1部>]>\n>>>\n>>> Dept.objects.filter(no__range=(10, 30)) # 查询部门编号在10到30之间的部门\n<QuerySet [<Dept: 研发1部>, <Dept: 销售1部>, <Dept: 运维1部>]>\n```\n\n查询单个对象。\n\n```Shell\n>>> \n>>> Dept.objects.get(pk=10)\n<Dept: 研发1部>\n>>>\n>>> Dept.objects.get(no=20)\n<Dept: 销售1部>\n>>>\n>>> Dept.objects.get(no__exact=30)\n<Dept: 运维1部>\n```\n\n排序数据。\n\n```Shell\n>>>\n>>> Dept.objects.order_by('no') # 查询所有部门按部门编号升序排列\n<QuerySet [<Dept: 研发1部>, <Dept: 销售1部>, <Dept: 运维1部>, <Dept: 研发3部>]>\n>>>\n>>> Dept.objects.order_by('-no') # 查询所有部门按部门编号降序排列\n<QuerySet [<Dept: 研发3部>, <Dept: 运维1部>, <Dept: 销售1部>, <Dept: 研发1部>]>\n```\n\n切片数据。\n\n```Shell\n>>>\n>>> Dept.objects.order_by('no')[0:2] # 按部门编号排序查询1~2部门\n<QuerySet [<Dept: 研发1部>, <Dept: 销售1部>]>\n>>>\n>>> Dept.objects.order_by('no')[2:4] # 按部门编号排序查询3~4部门\n<QuerySet [<Dept: 运维1部>, <Dept: 研发3部>]>\n```\n\n高级查询。\n\n```Shell\n>>>\n>>> Emp.objects.filter(dept__no=10) # 根据部门编号查询该部门的员工\n<QuerySet [<Emp: 乔峰>, <Emp: 张无忌>, <Emp: 张三丰>]>\n>>>\n>>> Emp.objects.filter(dept__name__contains='销售') # 查询名字包含“销售”的部门的员工\n<QuerySet [<Emp: 黄蓉>]>\n>>>\n>>> Dept.objects.get(pk=10).emp_set.all() # 通过部门反查部门所有的员工\n<QuerySet [<Emp: 乔峰>, <Emp: 张无忌>, <Emp: 张三丰>]>\n```\n\n> 说明1：由于员工与部门之间存在多对一外键关联，所以也能通过部门反向查询该部门的员工（从一对多关系中“一”的一方查询“多”的一方），反向查询属性默认的名字是`类名小写_set`（如上面例子中的`emp_set`），当然也可以在创建模型时通过`ForeingKey`的`related_name`属性指定反向查询属性的名字。如果不希望执行反向查询可以将`related_name`属性设置为`'+'`或以`'+'`开头的字符串。\n\n> 说明2：查询多个对象的时候返回的是QuerySet对象，QuerySet使用了惰性查询，即在创建QuerySet对象的过程中不涉及任何数据库活动，等真正用到对象时（求值QuerySet）才向数据库发送SQL语句并获取对应的结果，这一点在实际开发中需要引起注意！\n\n> 说明3：可以在QuerySet上使用`update()`方法一次更新多个对象。\n\n#### 删除\n\n```Shell\n>>>\n>>> Dept.objects.get(pk=40).delete()\n(1, {'hrs.Dept': 1})\n```\n\n### Django模型最佳实践\n\n1. 正确的模型命名和关系字段命名。\n2. 设置适当的`related_name`属性。\n3. 用`OneToOneField`代替`ForeignKeyField(unique=True)`。\n4. 通过“迁移操作”（migrate）来添加模型。\n5. 用NoSQL来应对需要降低范式级别的场景。\n6. 如果布尔类型可以为空要使用`NullBooleanField`。\n7. 在模型中放置业务逻辑。\n8. 用`<ModelName>.DoesNotExists`取代`ObjectDoesNotExists`。\n9. 在数据库中不要出现无效数据。\n10. 不要对`QuerySet`调用`len()`函数。\n11. 将`QuerySet`的`exists()`方法的返回值用于`if`条件。\n12. 用`DecimalField`来存储货币相关数据而不是`FloatField`。\n13. 定义`__str__`方法。\n14. 不要将数据文件放在同一个目录中。\n\n> 说明：以上内容来自于STEELKIWI网站的[*Best Practice working with Django models in Python*](https://steelkiwi.com/blog/best-practices-working-django-models-python/)，有兴趣的小伙伴可以阅读原文。\n\n### 模型定义参考\n\n#### 字段\n\n对字段名称的限制\n\n- 字段名不能是Python的保留字，否则会导致语法错误\n- 字段名不能有多个连续下划线，否则影响ORM查询操作\n\nDjango模型字段类\n\n| 字段类                |  说明                                                         |\n| --------------------- | ------------------------------------------------------------ |\n| AutoField             |自增ID字段                                                   |\n| BigIntegerField       |64位有符号整数                                               |\n| BinaryField           | 存储二进制数据的字段，对应Python的bytes类型                  |\n| BooleanField          | 存储True或False                                              |\n| CharField             | 长度较小的字符串                                             |\n| DateField             | 存储日期，有auto_now和auto_now_add属性                       |\n| DateTimeField         | 存储日期和日期，两个附加属性同上                             |\n| DecimalField          |存储固定精度小数，有max_digits（有效位数）和decimal_places（小数点后面）两个必要的参数 |\n| DurationField         |存储时间跨度                                                 |\n| EmailField            | 与CharField相同，可以用EmailValidator验证                    |\n| FileField             | 文件上传字段                                                 |\n| FloatField            | 存储浮点数                                                   |\n| ImageField            | 其他同FileFiled，要验证上传的是不是有效图像                  |\n| IntegerField          | 存储32位有符号整数。                                         |\n| GenericIPAddressField | 存储IPv4或IPv6地址                                           |\n| NullBooleanField      | 存储True、False或null值                                      |\n| PositiveIntegerField  | 存储无符号整数（只能存储正数）                               |\n| SlugField             | 存储slug（简短标注）                                         |\n| SmallIntegerField     | 存储16位有符号整数                                           |\n| TextField             | 存储数据量较大的文本                                         |\n| TimeField             | 存储时间                                                     |\n| URLField              | 存储URL的CharField                                           |\n| UUIDField             | 存储全局唯一标识符                                           |\n\n#### 字段属性\n\n通用字段属性\n\n| 选项           | 说明                                                         |\n| -------------- | ------------------------------------------------------------ |\n| null           | 数据库中对应的字段是否允许为NULL，默认为False                |\n| blank          | 后台模型管理验证数据时，是否允许为NULL，默认为False          |\n| choices        | 设定字段的选项，各元组中的第一个值是设置在模型上的值，第二值是人类可读的值 |\n| db_column      | 字段对应到数据库表中的列名，未指定时直接使用字段的名称       |\n| db_index       | 设置为True时将在该字段创建索引                               |\n| db_tablespace  | 为有索引的字段设置使用的表空间，默认为DEFAULT_INDEX_TABLESPACE |\n| default        | 字段的默认值                                                 |\n| editable       | 字段在后台模型管理或ModelForm中是否显示，默认为True          |\n| error_messages | 设定字段抛出异常时的默认消息的字典，其中的键包括null、blank、invalid、invalid_choice、unique和unique_for_date |\n| help_text      | 表单小组件旁边显示的额外的帮助文本。                         |\n| primary_key    | 将字段指定为模型的主键，未指定时会自动添加AutoField用于主键，只读。 |\n| unique         | 设置为True时，表中字段的值必须是唯一的                       |\n| verbose_name   | 字段在后台模型管理显示的名称，未指定时使用字段的名称         |\n\nForeignKey属性\n\n1. limit_choices_to：值是一个Q对象或返回一个Q对象，用于限制后台显示哪些对象。\n2. related_name：用于获取关联对象的关联管理器对象（反向查询），如果不允许反向，该属性应该被设置为`'+'`，或者以`'+'`结尾。\n3. to_field：指定关联的字段，默认关联对象的主键字段。\n4. db_constraint：是否为外键创建约束，默认值为True。\n5. on_delete：外键关联的对象被删除时对应的动作，可取的值包括django.db.models中定义的：\n   - CASCADE：级联删除。\n   - PROTECT：抛出ProtectedError异常，阻止删除引用的对象。\n   - SET_NULL：把外键设置为null，当null属性被设置为True时才能这么做。\n   - SET_DEFAULT：把外键设置为默认值，提供了默认值才能这么做。\n\nManyToManyField属性\n\n1. symmetrical：是否建立对称的多对多关系。\n2. through：指定维持多对多关系的中间表的Django模型。\n3. throughfields：定义了中间模型时可以指定建立多对多关系的字段。\n4. db_table：指定维持多对多关系的中间表的表名。\n\n#### 模型元数据选项\n\n| 选项                  | 说明                                                         |\n| --------------------- | ------------------------------------------------------------ |\n| abstract              | 设置为True时模型是抽象父类                                   |\n| app_label             | 如果定义模型的应用不在INSTALLED_APPS中可以用该属性指定       |\n| db_table              | 模型使用的数据表名称                                         |\n| db_tablespace         | 模型使用的数据表空间                                         |\n| default_related_name  | 关联对象回指这个模型时默认使用的名称，默认为<model_name>_set |\n| get_latest_by         | 模型中可排序字段的名称。                                     |\n| managed               | 设置为True时，Django在迁移中创建数据表并在执行flush管理命令时把表移除 |\n| order_with_respect_to | 标记对象为可排序的                                           |\n| ordering              | 对象的默认排序                                               |\n| permissions           | 创建对象时写入权限表的额外权限                               |\n| default_permissions   | 默认为`('add', 'change', 'delete')`                          |\n| unique_together       | 设定组合在一起时必须独一无二的字段名                         |\n| index_together        | 设定一起建立索引的多个字段名                                 |\n| verbose_name          | 为对象设定人类可读的名称                                     |\n| verbose_name_plural   | 设定对象的复数名称                                           |\n\n### 查询参考\n\n按字段查找可以用的条件：\n\n1. exact / iexact：精确匹配/忽略大小写的精确匹配查询\n2. contains / icontains / startswith / istartswith / endswith / iendswith：基于`like`的模糊查询\n3. in：集合运算\n4. gt / gte / lt / lte：大于/大于等于/小于/小于等于关系运算\n5. range：指定范围查询（SQL中的`between…and…`）\n6. year / month / day / week_day / hour / minute / second：查询时间日期\n7. isnull：查询空值（True）或非空值（False）\n8. search：基于全文索引的全文检索\n9. regex / iregex：基于正则表达式的模糊匹配查询\n\nQ对象（用于执行复杂查询）的使用：\n\n```Shell\n>>>\n>>> from django.db.models import Q\n>>> Emp.objects.filter(\n...     Q(name__startswith='张'),\n...     Q(sal__gte=5000) | Q(comm__gte=1000)\n... ) # 查询名字以“张”开头 工资大于等于5000或补贴大于等于1000的员工\n<QuerySet [<Emp: 张三丰>]>\n```\n\n\n\n"
  },
  {
    "path": "Day41-55/Django2实战03.md",
    "content": "## Django 2.x实战(03) - 视图、模板和URL\n\n"
  },
  {
    "path": "Day41-55/Django2实战04.md",
    "content": "## Django 2.x实战(04) - 表单的应用\n\n"
  },
  {
    "path": "Day41-55/Django2实战05.md",
    "content": "## Django 2.x实战(05) - Cookie和会话\n\n\n\n"
  },
  {
    "path": "Day41-55/Django2实战06.md",
    "content": "## Django 2.x实战(06) - 日志和缓存\n\n\n\n"
  },
  {
    "path": "Day41-55/Django2实战07.md",
    "content": "## Django 2.x实战(07) - 文件上传和通用视图\n\n\n\n"
  },
  {
    "path": "Day41-55/Django2实战08.md",
    "content": "## Django 2.x实战(08) - 用户/角色/权限和中间件\n\n\n\n"
  },
  {
    "path": "Day41-55/Django2实战09.md",
    "content": "## Django 2.x实战(09) - RESTful架构和应用(上)\n\n\n\n"
  },
  {
    "path": "Day41-55/Django2实战10.md",
    "content": "## Django 2.x实战(10) - RESTful架构和应用(下)\n\n\n\n"
  },
  {
    "path": "Day41-55/Django2项目实战.md",
    "content": ""
  },
  {
    "path": "Day41-55/car/car/__init__.py",
    "content": "import pymysql\n\npymysql.install_as_MySQLdb()"
  },
  {
    "path": "Day41-55/car/car/settings.py",
    "content": "\"\"\"\nDjango settings for car project.\n\nGenerated by 'django-admin startproject' using Django 2.0.5.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/2.0/ref/settings/\n\"\"\"\n\nimport os\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = 'ol6dmf6im(w!l*z4w+_whm&)8@(c7%4&tlhd%uh6$lfx=pi*5e'\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = True\n\nALLOWED_HOSTS = []\n\n\n# Application definition\n\nINSTALLED_APPS = [\n    'django.contrib.admin',\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'django.contrib.sessions',\n    'django.contrib.messages',\n    'django.contrib.staticfiles',\n    'search',\n]\n\nMIDDLEWARE = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.common.CommonMiddleware',\n    'django.middleware.csrf.CsrfViewMiddleware',\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n    'django.contrib.messages.middleware.MessageMiddleware',\n    'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\nROOT_URLCONF = 'car.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [os.path.join(BASE_DIR, 'templates')]\n        ,\n        'APP_DIRS': True,\n        'OPTIONS': {\n            'context_processors': [\n                'django.template.context_processors.debug',\n                'django.template.context_processors.request',\n                'django.contrib.auth.context_processors.auth',\n                'django.contrib.messages.context_processors.messages',\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = 'car.wsgi.application'\n\n\n# Database\n# https://docs.djangoproject.com/en/2.0/ref/settings/#databases\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.mysql',\n        'NAME': 'car',\n        'HOST': 'localhost',\n        'PORT': 3306,\n        'USER': 'root',\n        'PASSWORD': '123456',\n    }\n}\n\n\n# Password validation\n# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/2.0/topics/i18n/\n\nLANGUAGE_CODE = 'en-us'\n\nTIME_ZONE = 'UTC'\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/2.0/howto/static-files/\nSTATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]\n\nSTATIC_URL = '/static/'\n"
  },
  {
    "path": "Day41-55/car/car/urls.py",
    "content": "\"\"\"car URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n    https://docs.djangoproject.com/en/2.0/topics/http/urls/\nExamples:\nFunction views\n    1. Add an import:  from my_app import views\n    2. Add a URL to urlpatterns:  path('', views.home, name='home')\nClass-based views\n    1. Add an import:  from other_app.views import Home\n    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')\nIncluding another URLconf\n    1. Import the include() function: from django.urls import include, path\n    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))\n\"\"\"\nfrom django.contrib import admin\nfrom django.conf.urls import url\n\nfrom search import views\n\nurlpatterns = [\n    url(r'^search$', views.search),\n    url(r'^search2$', views.ajax_search),\n    url(r'^add', views.add),\n    url(r'^admin/', admin.site.urls),\n]\n"
  },
  {
    "path": "Day41-55/car/car/wsgi.py",
    "content": "\"\"\"\nWSGI config for car project.\n\nIt exposes the WSGI callable as a module-level variable named ``application``.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/\n\"\"\"\n\nimport os\n\nfrom django.core.wsgi import get_wsgi_application\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"car.settings\")\n\napplication = get_wsgi_application()\n"
  },
  {
    "path": "Day41-55/car/manage.py",
    "content": "#!/usr/bin/env python\nimport os\nimport sys\n\nif __name__ == \"__main__\":\n    os.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"car.settings\")\n    try:\n        from django.core.management import execute_from_command_line\n    except ImportError as exc:\n        raise ImportError(\n            \"Couldn't import Django. Are you sure it's installed and \"\n            \"available on your PYTHONPATH environment variable? Did you \"\n            \"forget to activate a virtual environment?\"\n        ) from exc\n    execute_from_command_line(sys.argv)\n"
  },
  {
    "path": "Day41-55/car/search/__init__.py",
    "content": ""
  },
  {
    "path": "Day41-55/car/search/admin.py",
    "content": "from django.contrib import admin\n\nfrom search.models import CarRecord\n\n\nclass CarRecordAdmin(admin.ModelAdmin):\n\n    list_display = ('carno', 'reason', 'date', 'punish', 'isdone')\n    search_fields = ('carno', )\n\n\nadmin.site.register(CarRecord, CarRecordAdmin)\n"
  },
  {
    "path": "Day41-55/car/search/apps.py",
    "content": "from django.apps import AppConfig\n\n\nclass SearchConfig(AppConfig):\n    name = 'search'\n"
  },
  {
    "path": "Day41-55/car/search/migrations/0001_initial.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.11 on 2018-05-24 01:16\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name='CarRecord',\n            fields=[\n                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),\n                ('carno', models.CharField(max_length=7)),\n                ('reason', models.CharField(max_length=50)),\n                ('date', models.DateTimeField(db_column='happen_date')),\n                ('punlish', models.CharField(max_length=50)),\n                ('isdone', models.BooleanField(default=False)),\n            ],\n            options={\n                'db_table': 'tb_car_record',\n            },\n        ),\n    ]\n"
  },
  {
    "path": "Day41-55/car/search/migrations/0002_auto_20180524_1420.py",
    "content": "# -*- coding: utf-8 -*-\n# Generated by Django 1.11 on 2018-05-24 06:20\nfrom __future__ import unicode_literals\n\nfrom django.db import migrations\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('search', '0001_initial'),\n    ]\n\n    operations = [\n        migrations.AlterModelOptions(\n            name='carrecord',\n            options={'ordering': ('-date',)},\n        ),\n        migrations.RenameField(\n            model_name='carrecord',\n            old_name='punlish',\n            new_name='punish',\n        ),\n    ]\n"
  },
  {
    "path": "Day41-55/car/search/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "Day41-55/car/search/models.py",
    "content": "from django.db import models\n\n\nclass CarRecord(models.Model):\n    carno = models.CharField(max_length=7)\n    reason = models.CharField(max_length=50)\n    date = models.DateTimeField(db_column='happen_date', auto_now_add=True)\n    punish = models.CharField(max_length=50)\n    isdone = models.BooleanField(default=False)\n\n    @property\n    def happen_date(self):\n        return self.date.strftime('%Y-%m-%d %H:%M:%S')\n        \"\"\"\n        return '%d年%02d月%02d日 %02d:%02d:%02d' % \\\n               (self.date.year, self.date.month, self.date.day,\n                self.date.hour, self.date.minute, self.date.second)\n        \"\"\"\n\n    class Meta:\n        db_table = 'tb_car_record'\n        ordering = ('-date', )\n"
  },
  {
    "path": "Day41-55/car/search/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "Day41-55/car/search/views.py",
    "content": "from datetime import datetime\nfrom json import JSONEncoder\n\nfrom django import forms\nfrom django.http import JsonResponse\nfrom django.shortcuts import render, redirect\n\nfrom search.models import CarRecord\n\n# 序列化/串行化/腌咸菜 - 把对象按照某种方式处理成字节或者字符的序列\n# 反序列化/反串行化 - 把字符或者字节的序列重新还原成对象\n# Python实现序列化和反序列化的工具模块 - json / pickle / shelve\n# return HttpResponse(json.dumps(obj), content_type='application/json')\n# return JsonResponse(obj, encoder=, safe=False)\n# from django.core.serializers import serialize\n# return HttpResponse(serialize('json', obj), content_type='application/json; charset=utf-8')\nMAX_AGE = 14 * 24 * 60 * 60\n\n\nclass CarRecordEncoder(JSONEncoder):\n\n    def default(self, o):\n        del o.__dict__['_state']\n        o.__dict__['date'] = o.happen_date\n        return o.__dict__\n\n\ndef ajax_search(request):\n    current_time = datetime.now().ctime()\n    # Cookie是保存在浏览器临时文件中的用户数据(通常是识别用户身份的ID/token或者是用户的偏好设置)\n    # 因为每次请求服务器时在HTTP请求的请求头中都会携带本网站的Cookie数据\n    # 那么服务器就可以获取这些信息来识别用户身份或者了解用户的偏好 这就是所谓的用户跟踪\n    # 因为HTTP本身是无状态的 所以需要使用Cookie/隐藏域/URL重写这样的技术来实现用户跟踪\n    # 从请求中读取指定的cookie - 通过cookie的名字找到对应的值\n    # 如果请求中没有指定名字的cookie可以通过get方法的第二个参数设置一个默认的返回值\n    last_visit_time = request.COOKIES.get('last_visit_time')\n    if request.method == 'GET':\n        response = render(request, 'search2.html',\n                          {'last': last_visit_time if last_visit_time\n                           else '你是第一次访问我们的网站'})\n        # 通过render渲染页面后先用set_cookie方法设置cookie后再返回HttpResponse对象\n        # 第一个参数是cookie的名字 第二个参数是cookie的值 第三个参数是过期时间(秒)\n        response.set_cookie('last_visit_time', current_time, max_age=MAX_AGE)\n        return response\n    else:\n        carno = request.POST['carno']\n        record_list = list(CarRecord.objects.filter(carno__icontains=carno))\n        # 第一个参数是要转换成JSON格式(序列化)的对象\n        # encoder参数要指定完成自定义对象序列化的编码器(JSONEncoder的子类型)\n        # safe参数的值如果为True那么传入的第一个参数只能是字典\n        # return HttpResponse(json.dumps(record_list), content_type='application/json; charset=utf-8')\n        return JsonResponse(record_list, encoder=CarRecordEncoder,\n                            safe=False)\n\n\ndef search(request):\n    # 请求行中的请求命令\n    # print(request.method)\n    # 请求行中的路径\n    # print(request.path)\n    # 请求头(以HTTP_打头的键是HTTP请求的请求头)\n    # print(request.META)\n    # 查询参数: http://host/path/resource?a=b&c=d\n    # print(request.GET)\n    # 表单参数\n    # print(request.POST)\n    if request.method == 'GET':\n        ctx = {'show_result': False}\n    else:\n        carno = request.POST['carno']\n        ctx = {\n            'show_result': True,\n            'record_list': list(CarRecord.objects.filter(carno__contains=carno))}\n    return render(request, 'search.html', ctx)\n\n\nclass CarRecordForm(forms.ModelForm):\n    carno = forms.CharField(min_length=7, max_length=7, label='车牌号', error_messages={'carno': '请输入有效的车牌号'})\n    reason = forms.CharField(max_length=50, label='违章原因')\n    punish = forms.CharField(max_length=50, required=False, label='处罚方式')\n\n    \"\"\"\n    # 执行额外的表单数据验证\n    def clean_carno(self):\n        _carno = self.cleaned_data['carno']\n        if not condition:\n            raise forms.ValidationError('...')\n        return _carno\n    \"\"\"\n\n    class Meta:\n        model = CarRecord\n        fields = ('carno', 'reason', 'punish')\n\n\ndef add(request):\n    if request.method == 'GET':\n        f = CarRecordForm(initial={'reason': '打警察', 'punish': '牢底坐穿'})\n    else:\n        f = CarRecordForm(request.POST)\n        if f.is_valid():\n            f.save()\n            return redirect('/search2')\n    return render(request, 'add.html', {'f': f})\n"
  },
  {
    "path": "Day41-55/car/templates/add.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>添加</title>\n    <style>\n        .err {\n            color: red;\n            font-size: 14px;\n        }\n    </style>\n</head>\n<body>\n    <h2>添加违章记录</h2>\n    <hr>\n    <p>\n        {% for hint in hints %}\n        <div class=\"err\">{{ hint }}</div>\n        {% endfor %}\n    </p>\n    <form action=\"/add\" method=\"post\">\n        {% for field in f.visible_fields %}\n            <div>\n            {{ field.label }}\n            {{ field }}\n            {% for error in field.errors %}\n                <span class=\"err\">{{ error }}</span>\n            {% endfor %}\n            </div>\n        {% endfor %}\n        {% csrf_token %}\n        <input type=\"submit\" value=\"添加\">\n    </form>\n</body>\n</html>"
  },
  {
    "path": "Day41-55/car/templates/search.html",
    "content": "<!DOCTYPE html>\n{% load staticfiles %}\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>车辆违章查询</title>\n    <style>\n        * {\n            font: 18px/30px Arial;\n        }\n        #container {\n            width: 960px;\n            margin: 0 auto;\n        }\n        #container form {\n            width: 620px;\n            margin: 10px auto;\n            padding-top: 100px;\n        }\n        #container form input[type=search] {\n            display: inline-block;\n            width: 480px;\n            height: 30px;\n        }\n        #container form input[type=submit] {\n            display: inline-block;\n            width: 80px;\n            height: 40px;\n            border: None;\n            background-color: red;\n            color: white;\n            margin-left: 20px;\n        }\n        #container table {\n            width: 920px;\n            margin: 20px auto;\n            border-collapse: collapse;\n        }\n        #container table th {\n            font-weight: bolder;\n            border-bottom: 1px solid darkgray;\n        }\n        #container table td {\n            text-align: center;\n            height: 50px;\n            width: 180px;\n        }\n    </style>\n</head>\n<body>\n    <div id=\"container\">\n        <form action=\"/search\" method=\"post\">\n            <!-- 跨站身份伪造: 利用浏览器存储的cookie中的用户身份标识冒充用户执行操作 -->\n            <!-- 防范跨站身份伪造最佳的做法就是在表单中放置随机令牌 -->\n            <!-- 除此之外通过设置令牌还可以防范表单重复提交以及重放攻击 -->\n            <!-- 隐藏域 / 隐式表单域: 页面上是无法看到该内容-->\n            {% csrf_token %}\n            <input type=\"search\" name=\"carno\" placeholder=\"请输入你的车牌号\" required>\n            <input type=\"submit\" value=\"搜索\">\n        </form>\n        <hr>\n        {% if show_result %}\n        <table>\n            <tr>\n                <th>车牌号</th>\n                <th>违章原因</th>\n                <th>违章时间</th>\n                <th>处罚方式</th>\n                <th>是否受理</th>\n            </tr>\n            {% for record in record_list %}\n            <tr>\n                <td>{{ record.carno }}</td>\n                <td>{{ record.reason }}</td>\n                <td>{{ record.happen_date }}</td>\n                <td>{{ record.punish }}</td>\n                <td>\n                    {% if record.isdone %}\n                        <img src=\"{% static '/images/icon-yes.svg' %}\">\n                    {% else %}\n                        <img src=\"{% static '/images/icon-no.svg' %}\">\n                    {% endif %}\n                </td>\n            </tr>\n            {% endfor %}\n        </table>\n        {% endif %}\n    </div>\n</body>\n</html>"
  },
  {
    "path": "Day41-55/car/templates/search2.html",
    "content": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>车辆违章查询</title>\n    <style>\n        * {\n            font: 18px/30px Arial;\n        }\n        #container {\n            width: 960px;\n            margin: 0 auto;\n        }\n        #search {\n            width: 720px;\n            margin: 10px auto;\n            padding-top: 100px;\n        }\n        #search input[type=search] {\n            display: inline-block;\n            width: 480px;\n            height: 30px;\n        }\n        #search input[type=submit] {\n            display: inline-block;\n            width: 80px;\n            height: 40px;\n            border: None;\n            background-color: red;\n            color: white;\n            margin-left: 20px;\n        }\n        #result {\n            width: 920px;\n            margin: 20px auto;\n            border-collapse: collapse;\n        }\n        #result th {\n            font-weight: bolder;\n            border-bottom: 1px solid darkgray;\n        }\n        #result td, #result th {\n            text-align: center;\n            height: 50px;\n            width: 180px;\n        }\n    </style>\n</head>\n<body>\n    <div id=\"container\">\n        <form id=\"search\" action=\"/search\" method=\"post\">\n            <!-- 跨站身份伪造: 利用浏览器存储的cookie中的用户身份标识冒充用户执行操作 -->\n            <!-- 防范跨站身份伪造最佳的做法就是在表单中放置随机令牌 -->\n            <!-- 除此之外通过设置令牌还可以防范表单重复提交以及重放攻击 -->\n            <!-- 隐藏域 / 隐式表单域: 页面上是无法看到该内容-->\n            {% csrf_token %}\n            <input type=\"search\" id=\"carno\" name=\"carno\" placeholder=\"请输入你的车牌号\" required>\n            <input type=\"submit\" value=\"搜索\">\n            <a href=\"/add\">添加新记录</a>\n        </form>\n        <hr>\n        <table id=\"result\">\n            <thead>\n                <tr>\n                    <th>车牌号</th>\n                    <th>违章原因</th>\n                    <th>违章时间</th>\n                    <th>处罚方式</th>\n                    <th>是否受理</th>\n                </tr>\n            </thead>\n            <tbody>\n\n            </tbody>\n        </table>\n        <p>{{ last }}</p>\n    </div>\n    <script src=\"https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js\"></script>\n    <script>\n        $(function() {\n            $('#search').on('submit', function(evt) {\n                evt.preventDefault();\n                var carno = $('#carno').val();\n                var token = $('#search input[type=hidden]').val()\n                $.ajax({\n                    url: '/search2',\n                    type: 'post',\n                    data: {\n                        'carno': carno,\n                        'csrfmiddlewaretoken': token\n                    },\n                    dataType: 'json',\n                    success: function(json) {\n                        $('#result tbody').children().remove();\n                        for (var i = 0; i < json.length; i += 1) {\n                            var record = json[i];\n                            var tr = $('<tr>').append($('<td>').text(record.carno))\n                                .append($('<td>').text(record.reason))\n                                .append($('<td>').text(record.date))\n                                .append($('<td>').text(record.punish));\n                            var imgName = record.isdone ? 'icon-yes.svg' : 'icon-no.svg';\n                            tr.append($('<td>').append($('<img>').attr('src', '/static/images/' + imgName)));\n                            $('#result tbody').append(tr);\n                        }\n                    }\n                });\n            });\n        });\n    </script>\n</body>\n</html>"
  },
  {
    "path": "Day41-55/oa/hrs/__init__.py",
    "content": ""
  },
  {
    "path": "Day41-55/oa/hrs/admin.py",
    "content": "from django.contrib import admin\n\nfrom hrs.models import Dept, Emp\n\n\nclass DeptAdmin(admin.ModelAdmin):\n\n    list_display = ('no', 'name', 'location')\n    ordering = ('no', )\n\n\nclass EmpAdmin(admin.ModelAdmin):\n\n    list_display = ('no', 'name', 'job', 'sal', 'dept')\n    search_fields = ('name', 'job')\n    ordering = ('dept', )\n\n\nadmin.site.register(Dept, DeptAdmin)\nadmin.site.register(Emp, EmpAdmin)\n"
  },
  {
    "path": "Day41-55/oa/hrs/apps.py",
    "content": "from django.apps import AppConfig\n\n\nclass HrsConfig(AppConfig):\n    name = 'hrs'\n"
  },
  {
    "path": "Day41-55/oa/hrs/migrations/0001_initial.py",
    "content": "# Generated by Django 2.0.5 on 2018-05-22 03:07\n\nfrom django.db import migrations, models\nimport django.db.models.deletion\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name='Dept',\n            fields=[\n                ('no', models.IntegerField(primary_key=True, serialize=False)),\n                ('name', models.CharField(max_length=20)),\n                ('location', models.CharField(max_length=10)),\n            ],\n            options={\n                'db_table': 'tb_dept',\n            },\n        ),\n        migrations.CreateModel(\n            name='Emp',\n            fields=[\n                ('no', models.IntegerField(primary_key=True, serialize=False)),\n                ('name', models.CharField(max_length=20)),\n                ('job', models.CharField(max_length=10)),\n                ('mgr', models.IntegerField(null=True)),\n                ('sal', models.DecimalField(decimal_places=2, max_digits=7)),\n                ('comm', models.DecimalField(decimal_places=2, max_digits=7, null=True)),\n                ('dept', models.ForeignKey(on_delete=django.db.models.deletion.PROTECT, to='hrs.Dept')),\n            ],\n            options={\n                'db_table': 'tb_emp',\n            },\n        ),\n    ]\n"
  },
  {
    "path": "Day41-55/oa/hrs/migrations/0002_auto_20180523_0923.py",
    "content": "# Generated by Django 2.0.5 on 2018-05-23 01:23\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('hrs', '0001_initial'),\n    ]\n\n    operations = [\n        migrations.AddField(\n            model_name='dept',\n            name='excellent',\n            field=models.BooleanField(default=0, verbose_name='是否优秀'),\n        ),\n        migrations.AlterField(\n            model_name='dept',\n            name='location',\n            field=models.CharField(max_length=10, verbose_name='部门所在地'),\n        ),\n        migrations.AlterField(\n            model_name='dept',\n            name='name',\n            field=models.CharField(max_length=20, verbose_name='部门名称'),\n        ),\n        migrations.AlterField(\n            model_name='dept',\n            name='no',\n            field=models.IntegerField(primary_key=True, serialize=False, verbose_name='部门编号'),\n        ),\n        migrations.AlterField(\n            model_name='emp',\n            name='comm',\n            field=models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True),\n        ),\n        migrations.AlterField(\n            model_name='emp',\n            name='mgr',\n            field=models.IntegerField(blank=True, null=True),\n        ),\n    ]\n"
  },
  {
    "path": "Day41-55/oa/hrs/migrations/0003_auto_20180524_1646.py",
    "content": "# Generated by Django 2.0.5 on 2018-05-24 08:46\n\nfrom django.db import migrations, models\nimport django.db.models.deletion\n\n\nclass Migration(migrations.Migration):\n\n    dependencies = [\n        ('hrs', '0002_auto_20180523_0923'),\n    ]\n\n    operations = [\n        migrations.AlterField(\n            model_name='emp',\n            name='mgr',\n            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='hrs.Emp'),\n        ),\n    ]\n"
  },
  {
    "path": "Day41-55/oa/hrs/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "Day41-55/oa/hrs/models.py",
    "content": "from django.db import models\n\n# ORM - 对象关系映射\n# 对象模型  <--->   关系模型\n# 实体类    <--->   二维表\n# 属性      <--->   列\n# 对象      <--->   记录\n\n\nclass Dept(models.Model):\n    no = models.IntegerField(primary_key=True, verbose_name='部门编号')\n    name = models.CharField(max_length=20, verbose_name='部门名称')\n    location = models.CharField(max_length=10, verbose_name='部门所在地')\n    excellent = models.BooleanField(default=0, verbose_name='是否优秀')\n\n    def __str__(self):\n        return self.name\n\n    class Meta:\n        db_table = 'tb_dept'\n\n\nclass Emp(models.Model):\n    no = models.IntegerField(primary_key=True)\n    name = models.CharField(max_length=20)\n    job = models.CharField(max_length=10)\n    mgr = models.ForeignKey('self', null=True, blank=True, on_delete=models.SET_NULL)\n    # mgr = models.IntegerField(null=True, blank=True)\n    sal = models.DecimalField(max_digits=7, decimal_places=2)\n    comm = models.DecimalField(max_digits=7, decimal_places=2, null=True, blank=True)\n    dept = models.ForeignKey(Dept, on_delete=models.PROTECT)\n\n    class Meta:\n        db_table = 'tb_emp'\n"
  },
  {
    "path": "Day41-55/oa/hrs/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "Day41-55/oa/hrs/urls.py",
    "content": "from django.urls import path\n\nfrom hrs import views\n\nurlpatterns = [\n    path('depts', views.depts, name='depts'),\n    # url('depts/emps/(?P<no>[0-9]+)', views.emps, name='empsindept'),\n    path('depts/emps/<int:no>', views.emps, name='empsindept'),\n    path('deldept/<int:no>', views.del_dept, name='ddel')\n]\n"
  },
  {
    "path": "Day41-55/oa/hrs/views.py",
    "content": "from django.http import HttpResponse\nfrom django.shortcuts import render, redirect\nfrom django.db.models import ObjectDoesNotExist\n\nfrom json import dumps\n\nfrom hrs.models import Dept, Emp\n\n\ndef index(request):\n    ctx = {\n        'greeting': '你好，世界！'\n    }\n    return render(request, 'index.html', context=ctx)\n\n\ndef del_dept(request, no='0'):\n    try:\n        Dept.objects.get(pk=no).delete()\n        ctx = {'code': 200}\n    except (ObjectDoesNotExist, ValueError):\n        ctx = {'code': 404}\n    return HttpResponse(\n        dumps(ctx), content_type='application/json; charset=utf-8')\n    # 重定向 - 给浏览器一个URL, 让浏览器重新请求指定的页面\n    # return redirect(reverse('depts'))\n    # return depts(request)\n\n\ndef emps(request, no='0'):\n    # no = request.GET['no']\n    # dept = Dept.objects.get(no=no)\n    # ForeignKey(Dept, on_delete=models.PROTECT, related_name='emps')\n    # dept.emps.all()\n    # emps_list = dept.emp_set.all()\n    # all() / filter() ==> QuerySet\n    # QuerySet使用了惰性查询 - 如果不是非得取到数据那么不会发出SQL语句\n    # 这样做是为了节省服务器内存的开销 - 延迟加载 - 节省空间势必浪费时间\n    emps_list = list(Emp.objects.filter(dept__no=no).select_related('dept'))\n    ctx = {'emp_list': emps_list, 'dept_name': emps_list[0].dept.name} \\\n        if len(emps_list) > 0 else {}\n    return render(request, 'emp.html', context=ctx)\n\n\ndef depts(request):\n    ctx = {'dept_list': Dept.objects.all()}\n    return render(request, 'dept.html', context=ctx)\n"
  },
  {
    "path": "Day41-55/oa/manage.py",
    "content": "#!/usr/bin/env python\nimport os\nimport sys\n\nif __name__ == \"__main__\":\n    os.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"oa.settings\")\n    try:\n        from django.core.management import execute_from_command_line\n    except ImportError as exc:\n        raise ImportError(\n            \"Couldn't import Django. Are you sure it's installed and \"\n            \"available on your PYTHONPATH environment variable? Did you \"\n            \"forget to activate a virtual environment?\"\n        ) from exc\n    execute_from_command_line(sys.argv)\n"
  },
  {
    "path": "Day41-55/oa/oa/__init__.py",
    "content": "import pymysql\n\npymysql.install_as_MySQLdb()\n"
  },
  {
    "path": "Day41-55/oa/oa/settings.py",
    "content": "\"\"\"\nDjango settings for oa project.\n\nGenerated by 'django-admin startproject' using Django 2.0.5.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/2.0/ref/settings/\n\"\"\"\n\nimport os\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = 'c^dt134g38w^r4+0f$dpoe)1d5)q1kn+2%g--#!*+xvvn&93=_'\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = True\n\nALLOWED_HOSTS = []\n\n\n# Application definition\n\nINSTALLED_APPS = [\n    'django.contrib.admin',\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'django.contrib.sessions',\n    'django.contrib.messages',\n    'django.contrib.staticfiles',\n    'hrs',\n]\n\nMIDDLEWARE = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.common.CommonMiddleware',\n    'django.middleware.csrf.CsrfViewMiddleware',\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n    'django.contrib.messages.middleware.MessageMiddleware',\n    'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\nROOT_URLCONF = 'oa.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [os.path.join(BASE_DIR, 'templates')]\n        ,\n        'APP_DIRS': True,\n        'OPTIONS': {\n            'context_processors': [\n                'django.template.context_processors.debug',\n                'django.template.context_processors.request',\n                'django.contrib.auth.context_processors.auth',\n                'django.contrib.messages.context_processors.messages',\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = 'oa.wsgi.application'\n\n\n# Database\n# https://docs.djangoproject.com/en/2.0/ref/settings/#databases\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.mysql',\n        'NAME': 'oa',\n        'HOST': 'localhost',\n        'PORT': 3306,\n        'USER': 'root',\n        'PASSWORD': '123456'\n    }\n}\n\n\n# Password validation\n# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/2.0/topics/i18n/\n\nLANGUAGE_CODE = 'zh-hans'\n\nTIME_ZONE = 'Asia/Chongqing'\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/2.0/howto/static-files/\n\nSTATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]\n\nSTATIC_URL = '/static/'\n\n# 配置将日志输出到控制台 日志级别为DEBUG(最详细的日志)\n# DEBUG < INFO < WARNING < ERROR < CRITICAL\nLOGGING = {\n    'version': 1,\n    'disable_existing_loggers': False,\n    'handlers': {\n        'console': {\n            'class': 'logging.StreamHandler',\n        },\n    },\n    'loggers': {\n        'django': {\n            'handlers': ['console'],\n            'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),\n        },\n    },\n}\n"
  },
  {
    "path": "Day41-55/oa/oa/urls.py",
    "content": "\"\"\"oa URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n    https://docs.djangoproject.com/en/2.0/topics/http/urls/\nExamples:\nFunction views\n    1. Add an import:  from my_app import views\n    2. Add a URL to urlpatterns:  path('', views.home, name='home')\nClass-based views\n    1. Add an import:  from other_app.views import Home\n    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')\nIncluding another URLconf\n    1. Import the include() function: from django.urls import include, path\n    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))\n\"\"\"\nfrom django.contrib import admin\nfrom django.urls import path, include\n\nfrom hrs import views\n\nurlpatterns = [\n    path('', views.index),\n    path('admin/', admin.site.urls),\n    path('hrs/', include('hrs.urls')),\n]\n"
  },
  {
    "path": "Day41-55/oa/oa/wsgi.py",
    "content": "\"\"\"\nWSGI config for oa project.\n\nIt exposes the WSGI callable as a module-level variable named ``application``.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/\n\"\"\"\n\nimport os\n\nfrom django.core.wsgi import get_wsgi_application\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"oa.settings\")\n\napplication = get_wsgi_application()\n"
  },
  {
    "path": "Day41-55/oa/templates/dept.html",
    "content": "<!DOCTYPE html>\n{% load static %}\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>部门</title>\n    <link href=\"{% static 'css/bootstrap.min.css' %}\" rel=\"stylesheet\">\n    <style>\n        #dept td, #dept th {\n            text-align: center;\n        }\n    </style>\n</head>\n<body>\n<div class=\"container\">\n    <div class=\"row clearfix\">\n\t\t<div class=\"col-md-12 column\">\n\t\t\t<h3>部门信息</h3>\n            <hr>\n\t\t</div>\n\t</div>\n\n    <div class=\"row clearfix\">\n        <div class=\"col-md-8 column\">\n            <table id=\"dept\" class=\"table table-striped table-hover\">\n                <thead>\n                <tr>\n                    <th>部门编号</th>\n                    <th>部门名称</th>\n                    <th>部门所在地</th>\n                    <th>是否优秀</th>\n                    <th>操作</th>\n                </tr>\n                </thead>\n                <tbody>\n                    {% for dept in dept_list %}\n                    <tr>\n                        <td>{{ dept.no }}</td>\n                        <td>\n                            <!-- 写代码时要尽量避免使用硬编码(hard code) -->\n                            <a href=\"{% url 'empsindept' dept.no %}\">{{ dept.name }}</a>\n                        </td>\n                        <td>{{ dept.location }}</td>\n                        <td>\n                            {% if dept.excellent %}\n                                <span style=\"color: green;\">√</span>\n                            {% else %}\n                                <span style=\"color: red;\">×</span>\n                            {% endif %}\n                        </td>\n                        <td>\n                            <a id=\"{{ dept.no }}\" href=\"javascript:void(0);\" class=\"btn btn-xs btn-warning\">删除</a>\n                        </td>\n                    </tr>\n                    {% endfor %}\n                </tbody>\n            </table>\n        </div>\n        <div class=\"col-md-4 column\">\n        </div>\n    </div>\n</div>\n<script src=\"{% static 'js/jquery.min.js' %}\"></script>\n<script src=\"{% static 'js/bootstrap.min.js' %}\"></script>\n<script>\n    $(function() {\n        $('#dept tbody tr:even').addClass('info');\n        $('#dept tbody tr:odd').addClass('warning');\n        $('#dept a[id]').on('click', function(evt) {\n            var a = $(evt.target);\n            if (confirm('确定要删除吗?')) {\n                $.getJSON('/hrs/deldept/' + a.attr('id'), function(json) {\n                    if (json.code == 200) {\n                        a.parent().parent().remove();\n                        $('#dept tbody tr:even').addClass('info');\n                        $('#dept tbody tr:odd').addClass('warning');\n                    }\n                });\n            }\n        });\n    });\n</script>\n</body>\n</html>"
  },
  {
    "path": "Day41-55/oa/templates/emp.html",
    "content": "<!DOCTYPE html>\n{% load static %}\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>员工</title>\n    <link href=\"{% static 'css/bootstrap.min.css' %}\" rel=\"stylesheet\">\n</head>\n<body>\n<div class=\"container\">\n    <div class=\"row clearfix\">\n\t\t<div class=\"col-md-12 column\">\n\t\t\t<h3>{{ dept_name }}员工信息</h3>\n            <hr>\n\t\t</div>\n\t</div>\n    <div class=\"row clearfix\">\n        <div class=\"col-md-8 column\">\n            {% if emp_list %}\n            <table id=\"dept\" class=\"table table-striped table-hover\">\n                <thead>\n                <tr>\n                    <th>编号</th>\n                    <th>姓名</th>\n                    <th>职位</th>\n                    <th>月薪</th>\n                    <th>部门名称</th>\n                </tr>\n                </thead>\n                <tbody>\n                    {% for emp in emp_list %}\n                    <tr>\n                        <td>{{ emp.no }}</td>\n                        <td>{{ emp.name }}</td>\n                        <td>{{ emp.job }}</td>\n                        <td>{{ emp.sal }}</td>\n                        <td>{{ dept_name }}</td>\n                    </tr>\n                    {% endfor %}\n                </tbody>\n            </table>\n            {% else %}\n                <h2>此部门暂时没有员工!</h2>\n            {% endif %}\n        </div>\n        <div class=\"col-md-4 column\">\n        </div>\n    </div>\n    <a href=\"{% url 'depts' %}\">返回部门列表</a>\n</div>\n<script src=\"{% static 'js/jquery.min.js' %}\"></script>\n<script src=\"{% static 'js/bootstrap.min.js' %}\"></script>\n<script>\n    $(function() {\n        $('#dept tbody tr:even').addClass('info');\n        $('#dept tbody tr:odd').addClass('warning');\n    });\n</script>\n</body>\n</html>"
  },
  {
    "path": "Day41-55/oa/templates/index.html",
    "content": "<!DOCTYPE html>\n{% load staticfiles %}\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>首页</title>\n</head>\n<body>\n    <h1>{{ greeting }}</h1>\n    <hr>\n    <img src=\"{% static 'images/mm.jpg' %}\" alt=\"\">\n</body>\n</html>"
  },
  {
    "path": "Day41-55/shop/cart/__init__.py",
    "content": ""
  },
  {
    "path": "Day41-55/shop/cart/admin.py",
    "content": "from django.contrib import admin\n\nfrom cart.models import Goods\n\n\nclass GoodsAdmin(admin.ModelAdmin):\n\n    list_display = ('id', 'name', 'price', 'image')\n    search_fields = ('name', )\n\n\nadmin.site.register(Goods, GoodsAdmin)\n"
  },
  {
    "path": "Day41-55/shop/cart/apps.py",
    "content": "from django.apps import AppConfig\n\n\nclass CartConfig(AppConfig):\n    name = 'cart'\n"
  },
  {
    "path": "Day41-55/shop/cart/migrations/0001_initial.py",
    "content": "# Generated by Django 2.0.5 on 2018-05-25 06:28\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name='Goods',\n            fields=[\n                ('id', models.AutoField(db_column='gid', primary_key=True, serialize=False)),\n                ('name', models.CharField(db_column='gname', max_length=50)),\n                ('price', models.DecimalField(db_column='gprice', decimal_places=2, max_digits=10)),\n                ('image', models.CharField(db_column='gimage', max_length=255)),\n            ],\n            options={\n                'db_table': 'tb_goods',\n                'ordering': ('id',),\n            },\n        ),\n    ]\n"
  },
  {
    "path": "Day41-55/shop/cart/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "Day41-55/shop/cart/models.py",
    "content": "from django.db import models\n\n\nclass Goods(models.Model):\n    \"\"\"商品模型类\"\"\"\n\n    id = models.AutoField(primary_key=True, db_column='gid')\n    name = models.CharField(max_length=50, db_column='gname')\n    price = models.DecimalField(max_digits=10, decimal_places=2, db_column='gprice')\n    image = models.CharField(max_length=255, db_column='gimage')\n\n    class Meta:\n\n        db_table = 'tb_goods'\n        ordering = ('id', )\n"
  },
  {
    "path": "Day41-55/shop/cart/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "Day41-55/shop/cart/views.py",
    "content": "from django.shortcuts import render, redirect\n\nfrom cart.models import Goods\n\n\ndef index(request):\n    goods_list = list(Goods.objects.all())\n    return render(request, 'goods.html', {'goods_list': goods_list})\n\n\nclass CartItem(object):\n    \"\"\"购物车中的商品项\"\"\"\n\n    def __init__(self, goods, amount=1):\n        self.goods = goods\n        self.amount = amount\n\n    @property\n    def total(self):\n        return self.goods.price * self.amount\n\n\nclass ShoppingCart(object):\n    \"\"\"购物车\"\"\"\n\n    def __init__(self):\n        self.items = {}\n\n    def add_item(self, item):\n        if item.goods.id in self.items:\n            self.items[item.goods.id].amount += item.amount\n        else:\n            self.items[item.goods.id] = item\n\n    def remove_item(self, id):\n        if id in self.items:\n            self.items.remove(id)\n\n    def clear_all_items(self):\n        self.items.clear()\n\n    @property\n    def cart_items(self):\n        return self.items.values()\n\n    @property\n    def total(self):\n        val = 0\n        for item in self.items.values():\n            val += item.total\n        return val\n\n\ndef add_to_cart(request, id):\n    goods = Goods.objects.get(pk=id)\n    # 通过request对象的session属性可以获取到session\n    # session相当于是服务器端用来保存用户数据的一个字典\n    # session利用了Cookie保存sessionid\n    # 通过sessionid就可以获取与某个用户对应的会话(也就是用户数据)\n    # 如果在浏览器中清除了Cookie那么也就清除了sessionid\n    # 再次访问服务器时服务器会重新分配新的sessionid这也就意味着之前的用户数据无法找回\n    # 默认情况下Django的session被设定为持久会话而非浏览器续存期会话\n    # 通过SESSION_EXPIRE_AT_BROWSER_CLOSE和SESSION_COOKIE_AGE参数可以修改默认设定\n    # Django中的session是进行了持久化处理的因此需要设定session的序列化方式\n    # 1.6版开始Django默认的session序列化器是JsonSerializer\n    # 可以通过SESSION_SERIALIZER来设定其他的序列化器(例如PickleSerializer)\n    cart = request.session.get('cart', ShoppingCart())\n    cart.add_item(CartItem(goods))\n    request.session['cart'] = cart\n    return redirect('/')\n\n\ndef show_cart(request):\n    cart = request.session.get('cart', None)\n    return render(request, 'cart.html', {'cart': cart})\n"
  },
  {
    "path": "Day41-55/shop/manage.py",
    "content": "#!/usr/bin/env python\nimport os\nimport sys\n\nif __name__ == \"__main__\":\n    os.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"shop.settings\")\n    try:\n        from django.core.management import execute_from_command_line\n    except ImportError as exc:\n        raise ImportError(\n            \"Couldn't import Django. Are you sure it's installed and \"\n            \"available on your PYTHONPATH environment variable? Did you \"\n            \"forget to activate a virtual environment?\"\n        ) from exc\n    execute_from_command_line(sys.argv)\n"
  },
  {
    "path": "Day41-55/shop/shop/__init__.py",
    "content": "import pymysql\n\npymysql.install_as_MySQLdb()\n"
  },
  {
    "path": "Day41-55/shop/shop/settings.py",
    "content": "\"\"\"\nDjango settings for shop project.\n\nGenerated by 'django-admin startproject' using Django 2.0.5.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/2.0/ref/settings/\n\"\"\"\n\nimport os\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = '3(n^av%_kt*^2zhz0!iwkxv6_wp^ed7-dpow*vqr7ck0_6=9^e'\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = True\n\nALLOWED_HOSTS = []\n\n\n# Application definition\n\nINSTALLED_APPS = [\n    'django.contrib.admin',\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'django.contrib.sessions',\n    'django.contrib.messages',\n    'django.contrib.staticfiles',\n    'cart.apps.CartConfig',\n]\n\nMIDDLEWARE = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.common.CommonMiddleware',\n    'django.middleware.csrf.CsrfViewMiddleware',\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n    'django.contrib.messages.middleware.MessageMiddleware',\n    'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\nROOT_URLCONF = 'shop.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [os.path.join(BASE_DIR, 'templates')]\n        ,\n        'APP_DIRS': True,\n        'OPTIONS': {\n            'context_processors': [\n                'django.template.context_processors.debug',\n                'django.template.context_processors.request',\n                'django.contrib.auth.context_processors.auth',\n                'django.contrib.messages.context_processors.messages',\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = 'shop.wsgi.application'\n\n\n# Database\n# https://docs.djangoproject.com/en/2.0/ref/settings/#databases\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.mysql',\n        'NAME': 'shop',\n        'HOST': 'localhost',\n        'PORT': 3306,\n        'USER': 'root',\n        'PASSWORD': '123456',\n    }\n}\n\n\n# Password validation\n# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',\n    },\n]\n\nSESSION_SERIALIZER = 'django.contrib.sessions.serializers.PickleSerializer'\n\n# Internationalization\n# https://docs.djangoproject.com/en/2.0/topics/i18n/\n\nLANGUAGE_CODE = 'zh-hans'\n\nTIME_ZONE = 'Asia/Chongqing'\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/2.0/howto/static-files/\n\nSTATICFILES_DIRS = [os.path.join(BASE_DIR, 'static'),]\n\nSTATIC_URL = '/static/'\n"
  },
  {
    "path": "Day41-55/shop/shop/urls.py",
    "content": "\"\"\"shop URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n    https://docs.djangoproject.com/en/2.0/topics/http/urls/\nExamples:\nFunction views\n    1. Add an import:  from my_app import views\n    2. Add a URL to urlpatterns:  path('', views.home, name='home')\nClass-based views\n    1. Add an import:  from other_app.views import Home\n    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')\nIncluding another URLconf\n    1. Import the include() function: from django.urls import include, path\n    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))\n\"\"\"\nfrom django.contrib import admin\nfrom django.urls import path\n\nfrom cart import views\n\nurlpatterns = [\n    path('', views.index),\n    path('add_to_cart/<int:id>', views.add_to_cart),\n    path('show_cart', views.show_cart),\n    path('admin/', admin.site.urls),\n]\n"
  },
  {
    "path": "Day41-55/shop/shop/wsgi.py",
    "content": "\"\"\"\nWSGI config for shop project.\n\nIt exposes the WSGI callable as a module-level variable named ``application``.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/\n\"\"\"\n\nimport os\n\nfrom django.core.wsgi import get_wsgi_application\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"shop.settings\")\n\napplication = get_wsgi_application()\n"
  },
  {
    "path": "Day41-55/shop/templates/cart.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<style>\n\t\t\tth, td { margin: 0; padding: 0; width: 180px; text-align: left; }\n\t\t\t.name { font-size: 14px; font-weight: bolder; width: 280px; }\n\t\t\t.price { color: red; font-size: 18px; }\n\t\t\ta { display: inline-block; text-align: center; background-color: red; }\n\t\t\t.back { width: 120px; height: 30px; line-height: 30px; }\n\t\t\t.del { width: 60px; height: 20px; line-height: 20px; }\n\t\t\ta:link, a:visited { color: white; text-decoration: none; }\n\t\t\t.left { float: left; width: 1000px;}\n\t\t\t.right { float: right; }\n\t\t\t.total { text-align: right; }\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"left\">\n\t\t\t<h1>购物车列表</h1>\n\t\t\t<hr>\n\t\t</div>\n\t\t<div class=\"right\">\n\t\t\t<a href=\"/\" class=\"back\">返回</a>\n\t\t</div>\n\t\t{% if cart %}\n\t\t<table style=\"clear: both;\">\n\t\t\t<tr>\n\t\t\t\t<th>商品名称</th>\n\t\t\t\t<th>商品单价</th>\n\t\t\t\t<th>商品数量</th>\n\t\t\t\t<th>商品总价</th>\n\t\t\t\t<th>操作</th>\n\t\t\t</tr>\n\t\t\t{% for item in cart.cart_items %}\n\t\t\t<tr>\n\t\t\t\t<td class=\"name\">{{ item.goods.name }}</td>\n\t\t\t\t<td class=\"price\">&yen;{{ item.goods.price }}</td>\n\t\t\t\t<td>{{ item.amount }}</td>\n\t\t\t\t<td class=\"price\">&yen;{{ item.total }}</td>\n\t\t\t\t<td>\n\t\t\t\t\t<a href=\"\" class=\"del\">删除</a>\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t\t{% endfor %}\n\t\t\t<tr>\n\t\t\t\t<td colspan=\"5\" class=\"total price\">&yen;{{ cart.total }}元</td>\n\t\t\t</tr>\n\t\t</table>\n\t\t<a href=\"\" class=\"back\">清空购物车</a>\n\t\t{% else %}\n\t\t<h3 style=\"clear: both;\">购物车中暂时没有商品!</h3>\n\t\t{% endif %}\n\t</body>\n</html>"
  },
  {
    "path": "Day41-55/shop/templates/goods.html",
    "content": "<!DOCTYPE html>\n{% load staticfiles %}\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<style>\n\t\t\timg { display: inline-block; width: 150px; height: 150px; border: 1px solid gray; }\n\t\t\tth, td { margin: 0; padding: 0; width: 250px; text-align: left; }\n\t\t\t.name { font-size: 14px; font-weight: bolder; }\n\t\t\t.price { color: red; font-size: 18px; }\n\t\t\ta { display: inline-block; width: 120px; height: 30px; line-height: 30px; text-align: center; background-color: red; }\n\t\t\ta:link, a:visited { color: white; text-decoration: none; }\n\t\t\t.left { float: left; width: 1000px;}\n\t\t\t.right { float: right; }\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"left\">\n\t\t\t<h1>商品列表</h1>\n\t\t\t<hr>\n\t\t</div>\n\t\t<div class=\"right\">\n\t\t\t<a href=\"/show_cart\">查看购物车</a>\n\t\t</div>\n\t\t<table style=\"clear:both;\">\n\t\t\t<tr>\n\t\t\t\t<th>商品名称</th>\n\t\t\t\t<th>商品价格</th>\n\t\t\t\t<th>商品图片</th>\n\t\t\t\t<th>操作</th>\n\t\t\t</tr>\n\t\t\t{% for goods in goods_list %}\n\t\t\t<tr>\n\t\t\t\t<td class=\"name\">{{ goods.name }}</td>\n\t\t\t\t<td class=\"price\">&yen;{{ goods.price }}</td>\n\t\t\t\t<td>\n\t\t\t\t\t<img src=\"{% static goods.image %}\" alt=\"{{ goods.name }}\">\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<a href=\"/add_to_cart/{{ goods.id }}\">加入购物车</a>\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t\t{% endfor %}\n\t\t</table>\n\t</body>\n</html>"
  },
  {
    "path": "Day41-55/shop_origin/cart/__init__.py",
    "content": ""
  },
  {
    "path": "Day41-55/shop_origin/cart/admin.py",
    "content": "from django.contrib import admin\n\nfrom cart.models import Goods\n\n\nclass GoodsAdmin(admin.ModelAdmin):\n\n    list_display = ('id', 'name', 'price', 'image')\n\n\nadmin.site.register(Goods, GoodsAdmin)\n"
  },
  {
    "path": "Day41-55/shop_origin/cart/apps.py",
    "content": "from django.apps import AppConfig\n\n\nclass CartConfig(AppConfig):\n    name = 'cart'\n"
  },
  {
    "path": "Day41-55/shop_origin/cart/migrations/0001_initial.py",
    "content": "# Generated by Django 2.0.5 on 2018-05-25 05:11\n\nfrom django.db import migrations, models\n\n\nclass Migration(migrations.Migration):\n\n    initial = True\n\n    dependencies = [\n    ]\n\n    operations = [\n        migrations.CreateModel(\n            name='Goods',\n            fields=[\n                ('id', models.AutoField(db_column='gid', primary_key=True, serialize=False)),\n                ('name', models.CharField(db_column='gname', max_length=50)),\n                ('price', models.DecimalField(db_column='gprice', decimal_places=2, max_digits=10)),\n                ('image', models.CharField(db_column='gimage', max_length=255)),\n            ],\n            options={\n                'db_table': 'tb_goods',\n                'ordering': ('id',),\n            },\n        ),\n    ]\n"
  },
  {
    "path": "Day41-55/shop_origin/cart/migrations/__init__.py",
    "content": ""
  },
  {
    "path": "Day41-55/shop_origin/cart/models.py",
    "content": "from django.db import models\n\n\nclass Goods(models.Model):\n\n    id = models.AutoField(primary_key=True, db_column='gid')\n    name = models.CharField(max_length=50, db_column='gname')\n    price = models.DecimalField(max_digits=10, decimal_places=2, db_column='gprice')\n    image = models.CharField(max_length=255, db_column='gimage')\n\n    class Meta:\n        db_table = 'tb_goods'\n        ordering = ('id',)\n"
  },
  {
    "path": "Day41-55/shop_origin/cart/tests.py",
    "content": "from django.test import TestCase\n\n# Create your tests here.\n"
  },
  {
    "path": "Day41-55/shop_origin/cart/views.py",
    "content": "from django.shortcuts import render\n\nfrom cart.models import Goods\n\n\ndef index(request):\n    goods_list = list(Goods.objects.all())\n    return render(request, 'goods.html', {'goods_list': goods_list})\n\n\ndef show_cart(request):\n    return render(request, 'cart.html')\n\n\ndef add_to_cart(request, no):\n    pass\n"
  },
  {
    "path": "Day41-55/shop_origin/manage.py",
    "content": "#!/usr/bin/env python\nimport os\nimport sys\n\nif __name__ == \"__main__\":\n    os.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"shop.settings\")\n    try:\n        from django.core.management import execute_from_command_line\n    except ImportError as exc:\n        raise ImportError(\n            \"Couldn't import Django. Are you sure it's installed and \"\n            \"available on your PYTHONPATH environment variable? Did you \"\n            \"forget to activate a virtual environment?\"\n        ) from exc\n    execute_from_command_line(sys.argv)\n"
  },
  {
    "path": "Day41-55/shop_origin/shop/__init__.py",
    "content": "import pymysql\n\npymysql.install_as_MySQLdb()"
  },
  {
    "path": "Day41-55/shop_origin/shop/settings.py",
    "content": "\"\"\"\nDjango settings for shop project.\n\nGenerated by 'django-admin startproject' using Django 2.0.5.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/topics/settings/\n\nFor the full list of settings and their values, see\nhttps://docs.djangoproject.com/en/2.0/ref/settings/\n\"\"\"\n\nimport os\n\n# Build paths inside the project like this: os.path.join(BASE_DIR, ...)\nBASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))\n\n\n# Quick-start development settings - unsuitable for production\n# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/\n\n# SECURITY WARNING: keep the secret key used in production secret!\nSECRET_KEY = '+gqc54!5+uhvc^o0)fjvihmg&5uu^u+#s5m*fc+e+@bw*(+!w*'\n\n# SECURITY WARNING: don't run with debug turned on in production!\nDEBUG = True\n\nALLOWED_HOSTS = []\n\n\n# Application definition\n\nINSTALLED_APPS = [\n    'django.contrib.admin',\n    'django.contrib.auth',\n    'django.contrib.contenttypes',\n    'django.contrib.sessions',\n    'django.contrib.messages',\n    'django.contrib.staticfiles',\n    'cart',\n]\n\nMIDDLEWARE = [\n    'django.middleware.security.SecurityMiddleware',\n    'django.contrib.sessions.middleware.SessionMiddleware',\n    'django.middleware.common.CommonMiddleware',\n    'django.middleware.csrf.CsrfViewMiddleware',\n    'django.contrib.auth.middleware.AuthenticationMiddleware',\n    'django.contrib.messages.middleware.MessageMiddleware',\n    'django.middleware.clickjacking.XFrameOptionsMiddleware',\n]\n\nROOT_URLCONF = 'shop.urls'\n\nTEMPLATES = [\n    {\n        'BACKEND': 'django.template.backends.django.DjangoTemplates',\n        'DIRS': [os.path.join(BASE_DIR, 'templates')]\n        ,\n        'APP_DIRS': True,\n        'OPTIONS': {\n            'context_processors': [\n                'django.template.context_processors.debug',\n                'django.template.context_processors.request',\n                'django.contrib.auth.context_processors.auth',\n                'django.contrib.messages.context_processors.messages',\n            ],\n        },\n    },\n]\n\nWSGI_APPLICATION = 'shop.wsgi.application'\n\n\n# Database\n# https://docs.djangoproject.com/en/2.0/ref/settings/#databases\n\nDATABASES = {\n    'default': {\n        'ENGINE': 'django.db.backends.mysql',\n        'NAME': 'Shop',\n        'HOST': 'localhost',\n        'PORT': 3306,\n        'USER': 'root',\n        'PASSWORD': '123456',\n    }\n}\n\n\n# Password validation\n# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators\n\nAUTH_PASSWORD_VALIDATORS = [\n    {\n        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',\n    },\n    {\n        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',\n    },\n]\n\n\n# Internationalization\n# https://docs.djangoproject.com/en/2.0/topics/i18n/\n\nLANGUAGE_CODE = 'en-us'\n\nTIME_ZONE = 'Asia/Chongqing'\n\nUSE_I18N = True\n\nUSE_L10N = True\n\nUSE_TZ = True\n\n\n# Static files (CSS, JavaScript, Images)\n# https://docs.djangoproject.com/en/2.0/howto/static-files/\nSTATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]\nSTATIC_URL = '/static/'\n"
  },
  {
    "path": "Day41-55/shop_origin/shop/urls.py",
    "content": "\"\"\"shop URL Configuration\n\nThe `urlpatterns` list routes URLs to views. For more information please see:\n    https://docs.djangoproject.com/en/2.0/topics/http/urls/\nExamples:\nFunction views\n    1. Add an import:  from my_app import views\n    2. Add a URL to urlpatterns:  path('', views.home, name='home')\nClass-based views\n    1. Add an import:  from other_app.views import Home\n    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')\nIncluding another URLconf\n    1. Import the include() function: from django.urls import include, path\n    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))\n\"\"\"\nfrom django.contrib import admin\nfrom django.urls import path\n\nfrom cart import views\n\nurlpatterns = [\n    path('', views.index),\n    path('show_cart', views.show_cart),\n    path('add_to_cart/<int:no>', views.add_to_cart),\n    path('admin/', admin.site.urls),\n]\n"
  },
  {
    "path": "Day41-55/shop_origin/shop/wsgi.py",
    "content": "\"\"\"\nWSGI config for shop project.\n\nIt exposes the WSGI callable as a module-level variable named ``application``.\n\nFor more information on this file, see\nhttps://docs.djangoproject.com/en/2.0/howto/deployment/wsgi/\n\"\"\"\n\nimport os\n\nfrom django.core.wsgi import get_wsgi_application\n\nos.environ.setdefault(\"DJANGO_SETTINGS_MODULE\", \"shop.settings\")\n\napplication = get_wsgi_application()\n"
  },
  {
    "path": "Day41-55/shop_origin/shop_create_sql.sql",
    "content": "insert into tb_goods values \n(default, '乐事（Lay’s）无限薯片', 8.2, 'images/lay.jpg'),\n(default, '旺旺 仙贝 加量装 540g', 18.5, 'images/wang.jpg'),\n(default, '多儿比（Dolbee）黄桃水果罐头', 6.8, 'images/dolbee.jpg'),\n(default, '王致和 精制料酒 500ml', 7.9, 'images/wine.jpg'),\n(default, '陈克明 面条 鸡蛋龙须挂面', 1.0, 'images/noodle.jpg'),\n(default, '鲁花 菜籽油 4L', 69.9, 'images/oil.jpg');"
  },
  {
    "path": "Day41-55/shop_origin/templates/cart.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<style>\n\t\t\tth, td { margin: 0; padding: 0; width: 180px; text-align: left; }\n\t\t\t.name { font-size: 14px; font-weight: bolder; width: 280px; }\n\t\t\t.price { color: red; font-size: 18px; }\n\t\t\ta { display: inline-block; text-align: center; background-color: red; }\n\t\t\t.back { width: 120px; height: 30px; line-height: 30px; }\n\t\t\t.del { width: 60px; height: 20px; line-height: 20px; }\n\t\t\ta:link, a:visited { color: white; text-decoration: none; }\n\t\t\t.left { float: left; width: 1000px;}\n\t\t\t.right { float: right; }\n\t\t\t.total { text-align: right; }\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"left\">\n\t\t\t<h1>购物车列表</h1>\n\t\t\t<hr>\n\t\t</div>\n\t\t<div class=\"right\">\n\t\t\t<a href=\"list_goods\" class=\"back\">返回</a>\n\t\t</div>\n\t\t{% if cart_items %}\n\t\t<table style=\"clear: both;\">\n\t\t\t<tr>\n\t\t\t\t<th>商品名称</th>\n\t\t\t\t<th>商品单价</th>\n\t\t\t\t<th>商品数量</th>\n\t\t\t\t<th>商品总价</th>\n\t\t\t\t<th>操作</th>\n\t\t\t</tr>\n\t\t\t{% for item in cart_items %}\n\t\t\t<tr>\n\t\t\t\t<td class=\"name\">{{ item.name }}</td>\n\t\t\t\t<td class=\"price\">&yen;{{ item.unit_price }}</td>\n\t\t\t\t<td>{{ item.amount }}</td>\n\t\t\t\t<td class=\"price\">&yen;{{ item.total_price }}</td>\n\t\t\t\t<td>\n\t\t\t\t\t<a href=\"\" class=\"del\">删除</a>\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t\t{% endfor %}\n\t\t\t<tr>\n\t\t\t\t<td colspan=\"5\" class=\"total price\">&yen;{{ cart.total }}元</td>\n\t\t\t</tr>\n\t\t</table>\n\t\t<a href=\"clear_cart\" class=\"back\">清空购物车</a>\n\t\t{% else %}\n\t\t<h3 style=\"clear: both;\">购物车中暂时没有商品!</h3>\n\t\t{% endif %}\n\t</body>\n</html>"
  },
  {
    "path": "Day41-55/shop_origin/templates/goods.html",
    "content": "<!DOCTYPE html>\n{% load staticfiles %}\n<html>\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<style>\n\t\t\timg { display: inline-block; width: 150px; height: 150px; border: 1px solid gray; }\n\t\t\tth, td { margin: 0; padding: 0; width: 250px; text-align: left; }\n\t\t\t.name { font-size: 14px; font-weight: bolder; }\n\t\t\t.price { color: red; font-size: 18px; }\n\t\t\ta { display: inline-block; width: 120px; height: 30px; line-height: 30px; text-align: center; background-color: red; }\n\t\t\ta:link, a:visited { color: white; text-decoration: none; }\n\t\t\t.left { float: left; width: 1000px;}\n\t\t\t.right { float: right; }\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div class=\"left\">\n\t\t\t<h1>商品列表</h1>\n\t\t\t<hr>\n\t\t</div>\n\t\t<div class=\"right\">\n\t\t\t<a href=\"/show_cart\">查看购物车</a>\n\t\t</div>\n\t\t<table style=\"clear:both;\">\n\t\t\t<tr>\n\t\t\t\t<th>商品名称</th>\n\t\t\t\t<th>商品价格</th>\n\t\t\t\t<th>商品图片</th>\n\t\t\t\t<th>操作</th>\n\t\t\t</tr>\n\t\t\t{% for goods in goods_list %}\n\t\t\t<tr>\n\t\t\t\t<td class=\"name\">{{ goods.name }}</td>\n\t\t\t\t<td class=\"price\">&yen;{{ goods.price }}</td>\n\t\t\t\t<td>\n\t\t\t\t\t<img src=\"{% static goods.image %}\" alt=\"{{ goods.name }}\">\n\t\t\t\t</td>\n\t\t\t\t<td>\n\t\t\t\t\t<a href=\"/add_to_cart/{{ goods.id }}\">加入购物车</a>\n\t\t\t\t</td>\n\t\t\t</tr>\n\t\t\t{% endfor %}\n\t\t</table>\n\t</body>\n</html>"
  },
  {
    "path": "Day56-65/Flask安装和入门.md",
    "content": ""
  },
  {
    "path": "Day56-65/Flask项目实战.md",
    "content": ""
  },
  {
    "path": "Day56-65/使用Flask进行项目开发.md",
    "content": ""
  },
  {
    "path": "Day56-65/数据库操作.md",
    "content": ""
  },
  {
    "path": "Day56-65/模板的使用.md",
    "content": ""
  },
  {
    "path": "Day56-65/表单的处理.md",
    "content": ""
  },
  {
    "path": "Day66-75/01.网络爬虫和相关工具.md",
    "content": "## 网络爬虫和相关工具\n\n### 网络爬虫\n\n网络爬虫（web crawler），以前经常称之为网络蜘蛛（spider），是按照一定的规则自动浏览万维网并获取信息的机器人程序（或脚本），曾经被广泛的应用于互联网搜索引擎。使用过互联网和浏览器的人都知道，网页中除了供用户阅读的文字信息之外，还包含一些超链接。网络爬虫系统正是通过网页中的超链接信息不断获得网络上的其它页面。正因如此，网络数据采集的过程就像一个爬虫或者蜘蛛在网络上漫游，所以才被形象的称为网络爬虫或者网络蜘蛛。\n\n#### 爬虫的应用领域\n\n在理想的状态下，所有ICP（Internet Content Provider）都应该为自己的网站提供API接口来共享它们允许其他程序获取的数据，在这种情况下爬虫就不是必需品，国内比较有名的电商平台（如淘宝、京东等）、社交平台（如腾讯微博等）等网站都提供了自己的Open API，但是这类Open API通常会对可以抓取的数据以及抓取数据的频率进行限制。对于大多数的公司而言，及时的获取行业相关数据是企业生存的重要环节之一，然而大部分企业在行业数据方面的匮乏是其与生俱来的短板，合理的利用爬虫来获取数据并从中提取出有商业价值的信息是至关重要的。当然爬虫还有很多重要的应用领域，下面列举了其中的一部分：\n\n1. 搜索引擎\n2. 新闻聚合\n3. 社交应用\n4. 舆情监控\n5. 行业数据\n\n### 合法性和背景调研\n\n#### 爬虫合法性探讨\n\n1. 网络爬虫领域目前还属于拓荒阶段，虽然互联网世界已经通过自己的游戏规则建立起一定的道德规范(Robots协议，全称是“网络爬虫排除标准”)，但法律部分还在建立和完善中，也就是说，现在这个领域暂时还是灰色地带。\n2. “法不禁止即为许可”，如果爬虫就像浏览器一样获取的是前端显示的数据（网页上的公开信息）而不是网站后台的私密敏感信息，就不太担心法律法规的约束，因为目前大数据产业链的发展速度远远超过了法律的完善程度。\n3. 在爬取网站的时候，需要限制自己的爬虫遵守Robots协议，同时控制网络爬虫程序的抓取数据的速度；在使用数据的时候，必须要尊重网站的知识产权（从Web 2.0时代开始，虽然Web上的数据很多都是由用户提供的，但是网站平台是投入了运营成本的，当用户在注册和发布内容时，平台通常就已经获得了对数据的所有权、使用权和分发权）。如果违反了这些规定，在打官司的时候败诉几率相当高。\n\n#### Robots.txt文件\n\n大多数网站都会定义robots.txt文件，下面以淘宝的[robots.txt](http://www.taobao.com/robots.txt)文件为例，看看该网站对爬虫有哪些限制。\n\n```\n\nUser-agent:  Baiduspider\nAllow:  /article\nAllow:  /oshtml\nDisallow:  /product/\nDisallow:  /\n\nUser-Agent:  Googlebot\nAllow:  /article\nAllow:  /oshtml\nAllow:  /product\nAllow:  /spu\nAllow:  /dianpu\nAllow:  /oversea\nAllow:  /list\nDisallow:  /\n\nUser-agent:  Bingbot\nAllow:  /article\nAllow:  /oshtml\nAllow:  /product\nAllow:  /spu\nAllow:  /dianpu\nAllow:  /oversea\nAllow:  /list\nDisallow:  /\n\nUser-Agent:  360Spider\nAllow:  /article\nAllow:  /oshtml\nDisallow:  /\n\nUser-Agent:  Yisouspider\nAllow:  /article\nAllow:  /oshtml\nDisallow:  /\n\nUser-Agent:  Sogouspider\nAllow:  /article\nAllow:  /oshtml\nAllow:  /product\nDisallow:  /\n\nUser-Agent:  Yahoo!  Slurp\nAllow:  /product\nAllow:  /spu\nAllow:  /dianpu\nAllow:  /oversea\nAllow:  /list\nDisallow:  /\n\nUser-Agent:  *\nDisallow:  /\n```\n\n注意上面robots.txt第一段的最后一行，通过设置“Disallow: /”禁止百度爬虫访问除了“Allow”规定页面外的其他所有页面。因此当你在百度搜索“淘宝”的时候，搜索结果下方会出现：“由于该网站的robots.txt文件存在限制指令（限制搜索引擎抓取），系统无法提供该页面的内容描述”。百度作为一个搜索引擎，至少在表面上遵守了淘宝网的robots.txt协议，所以用户不能从百度上搜索到淘宝内部的产品信息。\n\n![](./res/baidu-search-taobao.png) \n\n### 相关工具介绍\n\n#### HTTP协议\n\n在开始讲解爬虫之前，我们稍微对HTTP（超文本传输协议）做一些回顾，因为我们在网页上看到的内容通常是浏览器执行HTML语言得到的结果，而HTTP就是传输HTML数据的协议。HTTP和其他很多应用级协议一样是构建在TCP（传输控制协议）之上的，它利用了TCP提供的可靠的传输服务实现了Web应用中的数据交换。按照维基百科上的介绍，设计HTTP最初的目的是为了提供一种发布和接收[HTML](https://zh.wikipedia.org/wiki/HTML)页面的方法，也就是说这个协议是浏览器和Web服务器之间传输的数据的载体。关于这个协议的详细信息以及目前的发展状况，大家可以阅读阮一峰老师的[《HTTP 协议入门》](http://www.ruanyifeng.com/blog/2016/08/http.html)、[《互联网协议入门》](http://www.ruanyifeng.com/blog/2012/05/internet_protocol_suite_part_i.html)系列以及[《图解HTTPS协议》](http://www.ruanyifeng.com/blog/2014/09/illustration-ssl.html)进行了解，下图是我在四川省网络通信技术重点实验室工作期间用开源协议分析工具Ethereal（抓包工具WireShark的前身）截取的访问百度首页时的HTTP请求和响应的报文（协议数据），由于Ethereal截取的是经过网络适配器的数据，因此可以清晰的看到从物理链路层到应用层的协议数据。\n\nHTTP请求（请求行+请求头+空行+[消息体]）：\n\n![](./res/http-request.png)\n\nHTTP响应（响应行+响应头+空行+消息体）：\n\n![](./res/http-response.png)\n\n> 说明：但愿这两张如同泛黄的照片般的截图帮助你大概的了解到HTTP是一个怎样的协议。 \n\n#### 相关工具\n\n1. Chrome Developer Tools：谷歌浏览器内置的开发者工具。\n\n   ![](./res/chrome-developer-tools.png)\n\n2. POSTMAN：功能强大的网页调试与RESTful请求工具。\n\n   ![](./res/postman.png)\n\n3. HTTPie：命令行HTTP客户端。\n\n   ```Shell\n   \n   $ http --header http://www.scu.edu.cn\n   HTTP/1.1 200 OK\n   Accept-Ranges: bytes\n   Cache-Control: private, max-age=600\n   Connection: Keep-Alive\n   Content-Encoding: gzip\n   Content-Language: zh-CN\n   Content-Length: 14403\n   Content-Type: text/html\n   Date: Sun, 27 May 2018 15:38:25 GMT\n   ETag: \"e6ec-56d3032d70a32-gzip\"\n   Expires: Sun, 27 May 2018 15:48:25 GMT\n   Keep-Alive: timeout=5, max=100\n   Last-Modified: Sun, 27 May 2018 13:44:22 GMT\n   Server: VWebServer\n   Vary: User-Agent,Accept-Encoding\n   X-Frame-Options: SAMEORIGIN\n   ```\n\n4. BuiltWith：识别网站所用技术的工具。\n\n   ```Python\n   \n   >>>\n   >>> import builtwith\n   >>> builtwith.parse('http://www.bootcss.com/')\n   {'web-servers': ['Nginx'], 'font-scripts': ['Font Awesome'], 'javascript-frameworks': ['Lo-dash', 'Underscore.js', 'Vue.js', 'Zepto', 'jQuery'], 'web-frameworks': ['Twitter Bootstrap']}\n   >>>\n   >>> import ssl\n   >>> ssl._create_default_https_context = ssl._create_unverified_context\n   >>> builtwith.parse('https://www.jianshu.com/')\n   {'web-servers': ['Tengine'], 'web-frameworks': ['Twitter Bootstrap', 'Ruby on Rails'], 'programming-languages': ['Ruby']}\n   ```\n\n5. python-whois：查询网站所有者的工具。\n\n   ```Python\n   \n   >>>\n   >>> import whois\n   >>> whois.whois('baidu.com')\n   {'domain_name': ['BAIDU.COM', 'baidu.com'], 'registrar': 'MarkMonitor, Inc.', 'whois_server': 'whois.markmonitor.com', 'referral_url': None, 'updated_date': [datetime.datetime(2017, 7, 28, 2, 36, 28), datetime.datetime(2017, 7, 27, 19, 36, 28)], 'creation_date': [datetime.datetime(1999, 10, 11, 11, 5, 17), datetime.datetime(1999, 10, 11, 4, 5, 17)], 'expiration_date': [datetime.datetime(2026, 10, 11, 11, 5, 17), datetime.datetime(2026, 10, 11, 0, 0)], 'name_servers': ['DNS.BAIDU.COM', 'NS2.BAIDU.COM', 'NS3.BAIDU.COM', 'NS4.BAIDU.COM', 'NS7.BAIDU.COM', 'dns.baidu.com', 'ns4.baidu.com', 'ns3.baidu.com', 'ns7.baidu.com', 'ns2.baidu.com'], 'status': ['clientDeleteProhibited https://icann.org/epp#clientDeleteProhibited', 'clientTransferProhibited https://icann.org/epp#clientTransferProhibited', 'clientUpdateProhibited https://icann.org/epp#clientUpdateProhibited', 'serverDeleteProhibited https://icann.org/epp#serverDeleteProhibited', 'serverTransferProhibited https://icann.org/epp#serverTransferProhibited', 'serverUpdateProhibited https://icann.org/epp#serverUpdateProhibited', 'clientUpdateProhibited (https://www.icann.org/epp#clientUpdateProhibited)', 'clientTransferProhibited (https://www.icann.org/epp#clientTransferProhibited)', 'clientDeleteProhibited (https://www.icann.org/epp#clientDeleteProhibited)', 'serverUpdateProhibited (https://www.icann.org/epp#serverUpdateProhibited)', 'serverTransferProhibited (https://www.icann.org/epp#serverTransferProhibited)', 'serverDeleteProhibited (https://www.icann.org/epp#serverDeleteProhibited)'], 'emails': ['abusecomplaints@markmonitor.com', 'whoisrelay@markmonitor.com'], 'dnssec': 'unsigned', 'name': None, 'org': 'Beijing Baidu Netcom Science Technology Co., Ltd.', 'address': None, 'city': None, 'state': 'Beijing', 'zipcode': None, 'country': 'CN'}\n   ```\n\n6. robotparser：解析robots.txt的工具。\n\n   ```Python\n   \n   >>> from urllib import robotparser\n   >>> parser = robotparser.RobotFileParser()\n   >>> parser.set_url('https://www.taobao.com/robots.txt')\n   >>> parser.read()\n   >>> parser.can_fetch('Hellokitty', 'http://www.taobao.com/article')\n   False\n   >>> parser.can_fetch('Baiduspider', 'http://www.taobao.com/article')\n   True\n   >>> parser.can_fetch('Baiduspider', 'http://www.taobao.com/product')\n   False\n   ```\n\n### 一个简单的爬虫\n\n一个基本的爬虫通常分为数据采集（网页下载）、数据处理（网页解析）和数据存储（将有用的信息持久化）三个部分的内容，当然更为高级的爬虫在数据采集和处理时会使用并发编程或分布式技术，这就需要有调度器（安排线程或进程执行对应的任务）、后台管理程序（监控爬虫的工作状态以及检查数据抓取的结果）等的参与。\n\n![](./res/crawler-workflow.png)\n\n一般来说，爬虫的工作流程包括以下几个步骤：\n\n1. 设定抓取目标（种子页面/起始页面）并获取网页。\n2. 当服务器无法访问时，按照指定的重试次数尝试重新下载页面。\n3. 在需要的时候设置用户代理或隐藏真实IP，否则可能无法访问页面。\n4. 对获取的页面进行必要的解码操作然后抓取出需要的信息。\n5. 在获取的页面中通过某种方式（如正则表达式）抽取出页面中的链接信息。\n6. 对链接进行进一步的处理（获取页面并重复上面的动作）。\n7. 将有用的信息进行持久化以备后续的处理。\n\n下面的例子给出了一个从“搜狐体育”上获取NBA新闻标题和链接的爬虫。\n\n```Python\n\nfrom urllib.error import URLError\nfrom urllib.request import urlopen\n\nimport re\nimport pymysql\nimport ssl\n\nfrom pymysql import Error\n\n\n# 通过指定的字符集对页面进行解码(不是每个网站都将字符集设置为utf-8)\ndef decode_page(page_bytes, charsets=('utf-8',)):\n    page_html = None\n    for charset in charsets:\n        try:\n            page_html = page_bytes.decode(charset)\n            break\n        except UnicodeDecodeError:\n            pass\n            # logging.error('Decode:', error)\n    return page_html\n\n\n# 获取页面的HTML代码(通过递归实现指定次数的重试操作)\ndef get_page_html(seed_url, *, retry_times=3, charsets=('utf-8',)):\n    page_html = None\n    try:\n        page_html = decode_page(urlopen(seed_url).read(), charsets)\n    except URLError:\n        # logging.error('URL:', error)\n        if retry_times > 0:\n            return get_page_html(seed_url, retry_times=retry_times - 1,\n                                 charsets=charsets)\n    return page_html\n\n\n# 从页面中提取需要的部分(通常是链接也可以通过正则表达式进行指定)\ndef get_matched_parts(page_html, pattern_str, pattern_ignore_case=re.I):\n    pattern_regex = re.compile(pattern_str, pattern_ignore_case)\n    return pattern_regex.findall(page_html) if page_html else []\n\n\n# 开始执行爬虫程序并对指定的数据进行持久化操作\ndef start_crawl(seed_url, match_pattern, *, max_depth=-1):\n    conn = pymysql.connect(host='localhost', port=3306,\n                           database='crawler', user='root',\n                           password='123456', charset='utf8')\n    try:\n        with conn.cursor() as cursor:\n            url_list = [seed_url]\n            # 通过下面的字典避免重复抓取并控制抓取深度\n            visited_url_list = {seed_url: 0}\n            while url_list:\n                current_url = url_list.pop(0)\n                depth = visited_url_list[current_url]\n                if depth != max_depth:\n                    # 尝试用utf-8/gbk/gb2312三种字符集进行页面解码\n                    page_html = get_page_html(current_url, charsets=('utf-8', 'gbk', 'gb2312'))\n                    links_list = get_matched_parts(page_html, match_pattern)\n                    param_list = []\n                    for link in links_list:\n                        if link not in visited_url_list:\n                            visited_url_list[link] = depth + 1\n                            page_html = get_page_html(link, charsets=('utf-8', 'gbk', 'gb2312'))\n                            headings = get_matched_parts(page_html, r'<h1>(.*)<span')\n                            if headings:\n                                param_list.append((headings[0], link))\n                    cursor.executemany('insert into tb_result values (default, %s, %s)',\n                                       param_list)\n                    conn.commit()\n    except Error:\n        pass\n        # logging.error('SQL:', error)\n    finally:\n        conn.close()\n\n\ndef main():\n    ssl._create_default_https_context = ssl._create_unverified_context\n    start_crawl('http://sports.sohu.com/nba_a.shtml',\n                r'<a[^>]+test=a\\s[^>]*href=[\"\\'](.*?)[\"\\']',\n                max_depth=2)\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n由于使用了MySQL实现持久化操作，所以要先启动MySQL服务器再运行该程序。\n\n### 爬虫注意事项\n\n通过上面的例子，我们对爬虫已经有了一个感性的认识，在编写爬虫时有以下一些注意事项：\n\n1. 处理相对链接。有的时候我们从页面中获取的链接不是一个完整的绝对链接而是一个相对链接，这种情况下需要将其与URL前缀进行拼接（`urllib.parse`中的`urljoin()`函数可以完成此项操作）。\n\n2. 设置代理服务。有些网站会限制访问的区域（例如美国的Netflix屏蔽了很多国家的访问），有些爬虫需要隐藏自己的身份，在这种情况下可以设置使用代理服务器，代理服务器有免费（如[西刺代理](http://www.xicidaili.com/)、[快代理](https://www.kuaidaili.com/free/)）和付费两种（如[讯代理](http://www.xdaili.cn/)、[阿布云代理](https://www.abuyun.com/))，付费的一般稳定性和可用性都更好，可以通过`urllib.request`中的`ProxyHandler`来为请求设置代理。\n\n3. 限制下载速度。如果我们的爬虫获取网页的速度过快，可能就会面临被封禁或者产生“损害动产”的风险（这个可能会导致吃官司且败诉），可以在两次下载之间添加延时从而对爬虫进行限速。\n\n4. 避免爬虫陷阱。有些网站会动态生成页面内容，这会导致产生无限多的页面（例如在线万年历通常会有无穷无尽的链接）。可以通过记录到达当前页面经过了多少个链接（链接深度）来解决该问题，当达到事先设定的最大深度时爬虫就不再像队列中添加该网页中的链接了。\n\n5. SSL相关问题。在使用`urlopen`打开一个HTTPS链接时会验证一次SSL证书，如果不做出处理会产生错误提示“SSL: CERTIFICATE_VERIFY_FAILED”，可以通过以下两种方式加以解决：\n\n   - 使用未经验证的上下文\n\n     ```Python\n     \n     import ssl\n     \n     request = urllib.request.Request(url='...', headers={...}) \n     context = ssl._create_unverified_context()\n     web_page = urllib.request.urlopen(request, context=context)\n     ```\n\n   - 设置全局的取消证书验证\n\n     ```Python\n     \n     import ssl\n     \n     ssl._create_default_https_context = ssl._create_unverified_context\n     ```\n\n     \n"
  },
  {
    "path": "Day66-75/02.数据采集和解析.md",
    "content": "## 数据采集和解析\n\n通过[《网络爬虫和相关工具》](./01.网络爬虫和相关工具.md)一文，我们已经了解到了开发一个爬虫需要做的工作以及一些常见的问题，至此我们可以对爬虫开发需要做的工作以及相关的技术做一个简单的汇总，这其中可能会有一些我们之前没有使用过的第三方库，不过别担心，这些内容我们稍后都会一一讲到。\n\n1. 下载数据 - urllib / requests / aiohttp。\n2. 解析数据 - re / lxml / beautifulsoup4（bs4）/ pyquery。\n3. 缓存和持久化 - pymysql / sqlalchemy / peewee/ redis / pymongo。\n4. 生成数字签名 - hashlib。\n5. 序列化和压缩 - pickle / json / zlib。\n6. 调度器 - 进程（multiprocessing） / 线程（threading） / 协程（coroutine）。\n\n### HTML页面分析\n\n```HTML\n\n<!DOCTYPE html>\n<html lang=\"en\">\n    <head>\n        <meta charset=\"UTF-8\">\n        <title>首页</title>\n    </head>\n    <body>\n        <h1>Hello, world!</h1>\n        <p>这是一个神奇的网站！</p>\n        <hr>\n        <div>\n            <h2>这是一个例子程序</h2>\n            <p>静夜思</p>\n            <p class=\"foo\">床前明月光</p>\n            <p id=\"bar\">疑似地上霜</p>\n            <p class=\"foo\">举头望明月</p>\n            <div><a href=\"http://www.baidu.com\"><p>低头思故乡</p></a></div>\n        </div>\n        <a class=\"foo\" href=\"http://www.qq.com\">腾讯网</a>\n        <img src=\"./img/pretty-girl.png\" alt=\"美女\">\n        <img src=\"./img/hellokitty.png\" alt=\"凯蒂猫\">\n        <img src=\"/static/img/pretty-girl.png\" alt=\"美女\">\n        <table>\n            <tr>\n                <th>姓名</th>\n                <th>上场时间</th>\n                <th>得分</th>\n                <th>篮板</th>\n                <th>助攻</th>\n            </tr>\n        </table>\n    </body>\n</html>\n```\n\n如果你对上面的代码并不感到陌生，那么你一定知道HTML页面通常由三部分构成，分别是用来承载内容的Tag（标签）、负责渲染页面的CSS（层叠样式表）以及控制交互式行为的JavaScript。通常，我们可以在浏览器的右键菜单中通过“查看网页源代码”的方式获取网页的代码并了解页面的结构；当然，我们也可以通过浏览器提供的开发人员工具来了解网页更多的信息。\n\n#### 使用requests获取页面\n\n1. GET请求和POST请求。\n\n   ```Python\n   \n   \n   ```\n\n2. URL参数和请求头。\n\n   ```Python\n   \n   \n   ```\n\n3. 复杂的POST请求（文件上传）。\n\n   ```Python\n   \n   \n   ```\n\n4. 操作Cookie。\n\n   ```Python\n   \n   \n   ```\n\n5. 设置代理服务器。\n\n   ```Python\n   \n   \n   ```\n\n> 说明：关于requests的详细用法可以参考它的[官方文档](http://docs.python-requests.org/zh_CN/latest/user/quickstart.html)。\n\n### 四种采集方式\n\n#### 四种采集方式的比较\n\n| 抓取方法   | 速度                      | 使用难度 | 备注                                       |\n| ---------- | ------------------------- | -------- | ------------------------------------------ |\n| 正则表达式 | 快                        | 困难     | 常用正则表达式<br>在线正则表达式测试       |\n| lxml       | 快                        | 一般     | 需要安装C语言依赖库<br>唯一支持XML的解析器 |\n| Beautiful  | 较快/较慢（取决于解析器） | 简单     |                                            |\n| PyQuery    | 较快                      | 简单     | Python版的jQuery                           |\n\n> 说明：Beautiful的解析器包括：Python标准库（html.parser）、lxml的HTML解析器、lxml的XML解析器和html5lib。\n\n#### 使用正则表达式\n\n如果你对正则表达式没有任何的概念，那么推荐先阅读[《正则表达式30分钟入门教程》]()，然后再阅读我们之前讲解在Python中如何使用正则表达式一文。\n\n#### 使用XPath和Lxml\n\n\n\n#### BeautifulSoup的使用\n\nBeautifulSoup是一个可以从HTML或XML文件中提取数据的Python库。它能够通过你喜欢的转换器实现惯用的文档导航、查找、修改文档的方式。\n\n1. 遍历文档树\n   - 获取标签\n   - 获取标签属性\n   - 获取标签内容\n   - 获取子（孙）节点\n   - 获取父节点/祖先节点\n   - 获取兄弟节点\n2. 搜索树节点\n   - find / find_all：字符串、正则表达式、列表、True、函数或Lambda。\n   - select_one / select：CSS选择器\n\n> 说明：更多内容可以参考BeautifulSoup的[官方文档](https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html)。\n\n#### PyQuery的使用\n\npyquery相当于jQuery的Python实现，可以用于解析HTML网页。\n\n\n\n### 实例 - 获取知乎发现上的问题链接\n\n```Python\n\nfrom urllib.parse import urljoin\n\nimport re\nimport requests\n\nfrom bs4 import BeautifulSoup\n\n\ndef main():\n    headers = {'user-agent': 'Baiduspider'}\n    proxies = {\n        'http': 'http://122.114.31.177:808'\n    }\n    base_url = 'https://www.zhihu.com/'\n    seed_url = urljoin(base_url, 'explore')\n    resp = requests.get(seed_url,\n                        headers=headers,\n                        proxies=proxies)\n    soup = BeautifulSoup(resp.text, 'lxml')\n    href_regex = re.compile(r'^/question')\n    link_set = set()\n    for a_tag in soup.find_all('a', {'href': href_regex}):\n        if 'href' in a_tag.attrs:\n            href = a_tag.attrs['href']\n            full_url = urljoin(base_url, href)\n            link_set.add(full_url)\n    print('Total %d question pages found.' % len(link_set))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n"
  },
  {
    "path": "Day66-75/03.存储数据.md",
    "content": "## 存储数据\n\n### 数据缓存\n\n通过[《网络数据采集和解析》](./02.数据采集和解析.md)一文，我们已经知道了如何从指定的页面中抓取数据，以及如何保存抓取的结果，但是我们没有考虑过这么一种情况，就是我们可能需要从已经抓取过的页面中提取出更多的数据，重新去下载这些页面对于规模不大的网站倒是问题也不大，但是如果能够把这些页面缓存起来，对应用的性能会有明显的改善。\n\n### 使用NoSQL\n\n#### Redis简介\n\nRedis是REmote DIctionary Server的缩写，它是一个用ANSI C编写的高性能的key-value存储系统，与其他的key-value存储系统相比，Redis有以下一些特点（也是优点）：\n\n- Redis的读写性能极高，并且有丰富的特性（发布/订阅、事务、通知等）。\n- Redis支持数据的持久化（RDB和AOF两种方式），可以将内存中的数据保存在磁盘中，重启的时候可以再次加载进行使用。\n- Redis不仅仅支持简单的key-value类型的数据，同时还提供hash、list、set，zset、hyperloglog、geo等数据类型。\n- Redis支持主从复制（实现读写分析）以及哨兵模式（监控master是否宕机并调整配置）。\n\n#### Redis的安装和配置\n\n可以使用Linux系统的包管理工具（如yum）来安装Redis，也可以通过在Redis的[官方网站](https://redis.io/)下载Redis的[源代码](http://download.redis.io/releases/redis-3.2.11.tar.gz)解压缩解归档之后进行构件安装。\n\n```Shell\n\n# wget http://download.redis.io/releases/redis-3.2.11.tar.gz\n# gunzip redis-3.2.11.tar.gz\n# tar -xvf redis-3.2.11.tar\n# cd redis-3.2.11\n# make && make install\n```\n\n接下来我们将redis-3.2.11目录下的redis.conf配置文件复制到用户主目录下并修改配置文件（如果你对配置文件不是很有把握就不要直接修改而是先复制一份再修改这个副本）。\n\n```Shell\n\n# cd ..\n# cp redis-3.2.11/redis.conf redis.conf\n# vim redis.conf\n```\n\n配置将Redis服务绑定到指定的IP地址和端口。\n\n![](./res/redis-bind.png)\n\n![](./res/redis-port.png)\n\n配置底层有多少个数据库。\n\n![](./res/redis-database.png)\n\n配置Redis的持久化机制 - RDB。\n\n![](./res/redis-save.png)\n\n![](./res/redis-rdb.png)\n\n配置Redis的持久化机制 - AOF。\n\n![](./res/redis-aof.png)\n\n配置访问Redis服务器的验证口令。\n\n![](./res/redis-security.png)\n\n配置Redis的主从复制，通过主从复制可以实现读写分离。\n\n![](./res/redis-replication.png)\n\n配置慢查询日志。\n\n![](./res/redis-slow-log.png)\n\n这样我们就完成了Redis的基本配置，如果对上面的东西感到困惑，可以先系统的了解一下Redis，[《Redis开发与运维》](https://item.jd.com/12121730.html)是一本不错的入门读物，而[《Redis实战》](https://item.jd.com/11791607.html)是不错的进阶读物。\n\n#### Redis的服务器和客户端\n\n接下来启动Redis服务器，可以将服务器放在后台去运行。\n\n```Shell\n\n# redis-server redis.conf &\n\n           _.-``__ ''-._\n      _.-``    `.  `_.  ''-._           Redis 3.2.11 (00000000/0) 64 bit\n  .-`` .-```.  ```\\/    _.,_ ''-._\n (    '      ,       .-`  | `,    )     Running in standalone mode\n |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379\n |    `-._   `._    /     _.-'    |     PID: 12345\n  `-._    `-._  `-./  _.-'    _.-'\n |`-._`-._    `-.__.-'    _.-'_.-'|\n |    `-._`-._        _.-'_.-'    |           http://redis.io\n  `-._    `-._`-.__.-'_.-'    _.-'\n |`-._`-._    `-.__.-'    _.-'_.-'|\n |    `-._`-._        _.-'_.-'    |\n  `-._    `-._`-.__.-'_.-'    _.-'\n      `-._    `-.__.-'    _.-'\n          `-._        _.-'\n              `-.__.-'\n```\n\n接下来，我们尝试用Redis客户端去连接服务器。\n\n```Shell\n\n# redis-cli -h 172.18.61.250 -p 6379\n172.18.61.250:6379> auth 1qaz2wsx\nOK\n172.18.61.250:6379> ping\nPONG\n172.18.61.250:6379>\n```\n\nRedis有着非常丰富的数据类型，也有很多的命令来操作这些数据，具体的内容可以查看[Redis命令参考](http://redisdoc.com/)，在这个网站上，除了Redis的命令参考，还有Redis的详细文档，其中包括了通知、事务、主从复制、持久化、哨兵、集群等内容。\n\n```Shell\n\n172.18.61.250:6379> set username admin\nOK\n172.18.61.250:6379> get username\n\"admin\"\n172.18.61.250:6379> hset student1 name hao\n(integer) 0\n172.18.61.250:6379> hset student1 age 38\n(integer) 1\n172.18.61.250:6379> hset student1 gender male\n(integer) 1\n172.18.61.250:6379> hgetall student1\n1) \"name\"\n2) \"hao\"\n3) \"age\"\n4) \"38\"\n5) \"gender\"\n6) \"male\"\n172.18.61.250:6379> lpush num 1 2 3 4 5\n(integer) 5\n172.18.61.250:6379> lrange num 0 -1\n1) \"5\"\n2) \"4\"\n3) \"3\"\n4) \"2\"\n5) \"1\"\n172.18.61.250:6379> sadd fruits apple banana orange apple grape grape\n(integer) 4\n172.18.61.250:6379> scard fruits\n(integer) 4\n172.18.61.250:6379> smembers fruits\n1) \"grape\"\n2) \"orange\"\n3) \"banana\"\n4) \"apple\"\n172.18.61.250:6379> zadd scores 90 zhao 78 qian 66 sun 95 lee\n(integer) 4\n172.18.61.250:6379> zrange scores 0 -1\n1) \"sun\"\n2) \"qian\"\n3) \"zhao\"\n4) \"lee\"\n172.18.61.250:6379> zrevrange scores 0 -1\n1) \"lee\"\n2) \"zhao\"\n3) \"qian\"\n4) \"sun\"\n```\n\n#### 在Python程序中使用Redis\n\n可以使用pip安装redis模块。redis模块的核心是名为Redis的类，该类的对象代表一个Redis客户端，通过该客户端可以向Redis服务器发送命令并获取执行的结果。上面我们在Redis客户端中使用的命令基本上就是Redis对象可以接收的消息，所以如果了解了Redis的命令就可以在Python中玩转Redis。\n\n```Shell\n\n$ pip3 install redis\n$ python3\n```\n\n```Python\n\n>>> import redis\n>>> client = redis.Redis(host='1.2.3.4', port=6379, password='1qaz2wsx')\n>>> client.set('username', 'admin')\nTrue\n>>> client.hset('student', 'name', 'hao')\n1\n>>> client.hset('student', 'age', 38)\n1\n>>> client.keys('*')\n[b'username', b'student']\n>>> client.get('username')\nb'admin'\n>>> client.hgetall('student')\n{b'name': b'hao', b'age': b'38'}\n```\n\n#### MongoDB简介\n\nMongoDB是2009年问世的一个面向文档的数据库管理系统，由C++语言编写，旨在为Web应用提供可扩展的高性能数据存储解决方案。虽然在划分类别的时候后，MongoDB被认为是NoSQL的产品，但是它更像一个介于关系数据库和非关系数据库之间的产品，在非关系数据库中它功能最丰富，最像关系数据库。\n\nMongoDB将数据存储为一个文档，一个文档由一系列的“键值对”组成，其文档类似于JSON对象，但是MongoDB对JSON进行了二进制处理（能够更快的定位key和value），因此其文档的存储格式称为BSON。关于JSON和BSON的差别大家可以看看MongoDB官方网站的文章[《JSON and BSON》](https://www.mongodb.com/json-and-bson)。\n\n目前，MongoDB已经提供了对Windows、MacOS、Linux、Solaris等多个平台的支持，而且也提供了多种开发语言的驱动程序，Python当然是其中之一。\n\n#### MongoDB的安装和配置\n\n可以从MongoDB的[官方下载链接](https://www.mongodb.com/download-center#community)下载MongoDB，官方为Windows系统提供了一个Installer程序，而Linux和MacOS则提供了压缩文件。下面简单说一下Linux系统如何安装和配置MongoDB。\n\n```Shell\n\n# wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-amazon-3.6.5.tgz\n# gunzip mongodb-linux-x86_64-amazon-3.6.5.tgz\n# mkdir mongodb-3.6.5\n# tar -xvf mongodb-linux-x86_64-amazon-3.6.5.tar --strip-components 1 -C mongodb-3.6.5/\n# export PATH=$PATH:~/mongodb-3.6.5/bin\n# mkdir -p /data/db\n# mongod --bind_ip 172.18.61.250\n2018-06-03T18:03:28.232+0800 I CONTROL  [initandlisten] MongoDB starting : pid=1163 port=27017 dbpath=/data/db 64-bit host=iZwz97tbgo9lkabnat2lo8Z\n2018-06-03T18:03:28.232+0800 I CONTROL  [initandlisten] db version v3.6.5\n2018-06-03T18:03:28.232+0800 I CONTROL  [initandlisten] git version: a20ecd3e3a174162052ff99913bc2ca9a839d618\n2018-06-03T18:03:28.232+0800 I CONTROL  [initandlisten] OpenSSL version: OpenSSL 1.0.0-fips29 Mar 2010\n...\n2018-06-03T18:03:28.945+0800 I NETWORK  [initandlisten] waiting for connections on port 27017\n```\n\n> 说明：上面的操作中，export命令是设置PATH环境变量，这样可以在任意路径下执行mongod来启动MongoDB服务器。MongoDB默认保存数据的路径是/data/db目录，为此要提前创建该目录。此外，在使用mongod启动MongoDB服务器时，—bind_ip参数用来将服务绑定到指定的IP地址，也可以用—port参数来指定端口，默认端口为27017。\n\n#### MongoDB基本概念\n\n我们通过与关系型数据库进行对照的方式来说明MongoDB中的一些概念。\n\n| SQL         | MongoDB     | 解释（SQL/MongoDB）    |\n| ----------- | ----------- | ---------------------- |\n| database    | database    | 数据库/数据库          |\n| table       | collection  | 二维表/集合            |\n| row         | document    | 记录（行）/文档        |\n| column      | field       | 字段（列）/域          |\n| index       | index       | 索引/索引              |\n| table joins | ---         | 表连接/嵌套文档        |\n| primary key | primary key | 主键/主键（`_id`字段） |\n\n#### 通过Shell操作MongoDB\n\n启动服务器后可以使用交互式环境跟服务器通信，如下所示。\n\n```shell\n# mongo --host 172.18.61.250\nMongoDB shell version v3.6.5\nconnecting to: mongodb://172.18.61.250:27017/\n...\n> \n```\n\n1. 查看、创建和删除数据库。\n\n   ```JavaScript\n   \n   > // 显示所有数据库\n   > show dbs\n   admin   0.000GB\n   config  0.000GB\n   local   0.000GB\n   > // 创建并切换到school数据库\n   > use school\n   switched to db school\n   > // 删除当前数据库\n   > db.dropDatabase()\n   { \"ok\" : 1 }\n   >\n   ```\n\n2. 创建、删除和查看集合。\n\n   ```JavaScript\n   \n   > // 创建并切换到school数据库\n   > use school\n   switched to db school\n   > // 创建colleges集合\n   > db.createCollection('colleges')\n   { \"ok\" : 1 }\n   > // 创建students集合\n   > db.createCollection('students')\n   { \"ok\" : 1 }\n   > // 查看所有集合\n   > show collections\n   colleges\n   students\n   > // 删除colleges集合\n   > db.colleges.drop()\n   true\n   > \n   ```\n\n   > 说明：在MongoDB中插入文档时如果集合不存在会自动创建集合，所以也可以按照下面的方式通过创建文档来创建集合。\n\n3. 文档的CRUD操作。\n\n   ```JavaScript\n   \n   > // 向students集合插入文档\n   > db.students.insert({stuid: 1001, name: '骆昊', age: 38})\n   WriteResult({ \"nInserted\" : 1 })\n   > // 向students集合插入文档\n   > db.students.save({stuid: 1002, name: '王大锤', tel: '13012345678', gender: '男'})\n   WriteResult({ \"nInserted\" : 1 })\n   > // 查看所有文档\n   > db.students.find()\n   { \"_id\" : ObjectId(\"5b13c72e006ad854460ee70b\"), \"stuid\" : 1001, \"name\" : \"骆昊\", \"age\" : 38 }\n   { \"_id\" : ObjectId(\"5b13c790006ad854460ee70c\"), \"stuid\" : 1002, \"name\" : \"王大锤\", \"tel\" : \"13012345678\", \"gender\" : \"男\" }\n   > // 更新stuid为1001的文档\n   > db.students.update({stuid: 1001}, {'$set': {tel: '13566778899', gender: '男'}})\n   WriteResult({ \"nMatched\" : 1, \"nUpserted\" : 0, \"nModified\" : 1 })\n   > // 插入或更新stuid为1003的文档\n   > db.students.update({stuid: 1003}, {'$set': {name: '白元芳', tel: '13022223333', gender: '男'}},  upsert=true)\n   WriteResult({\n           \"nMatched\" : 0,\n           \"nUpserted\" : 1,\n           \"nModified\" : 0,\n           \"_id\" : ObjectId(\"5b13c92dd185894d7283efab\")\n   })\n   > // 查询所有文档\n   > db.students.find().pretty()\n   {\n           \"_id\" : ObjectId(\"5b13c72e006ad854460ee70b\"),\n           \"stuid\" : 1001,\n           \"name\" : \"骆昊\",\n           \"age\" : 38,\n           \"gender\" : \"男\",\n           \"tel\" : \"13566778899\"\n   }\n   {\n           \"_id\" : ObjectId(\"5b13c790006ad854460ee70c\"),\n           \"stuid\" : 1002,\n           \"name\" : \"王大锤\",\n           \"tel\" : \"13012345678\",\n           \"gender\" : \"男\"\n   }\n   {\n           \"_id\" : ObjectId(\"5b13c92dd185894d7283efab\"),\n           \"stuid\" : 1003,\n           \"gender\" : \"男\",\n           \"name\" : \"白元芳\",\n           \"tel\" : \"13022223333\"\n   }\n   > // 查询stuid大于1001的文档\n   > db.students.find({stuid: {'$gt': 1001}}).pretty()\n   {\n           \"_id\" : ObjectId(\"5b13c790006ad854460ee70c\"),\n           \"stuid\" : 1002,\n           \"name\" : \"王大锤\",\n           \"tel\" : \"13012345678\",\n           \"gender\" : \"男\"\n   }\n   {\n           \"_id\" : ObjectId(\"5b13c92dd185894d7283efab\"),\n           \"stuid\" : 1003,\n           \"gender\" : \"男\",\n           \"name\" : \"白元芳\",\n           \"tel\" : \"13022223333\"\n   }\n   > // 查询stuid大于1001的文档只显示name和tel字段\n   > db.students.find({stuid: {'$gt': 1001}}, {_id: 0, name: 1, tel: 1}).pretty()\n   { \"name\" : \"王大锤\", \"tel\" : \"13012345678\" }\n   { \"name\" : \"白元芳\", \"tel\" : \"13022223333\" }\n   > // 查询name为“骆昊”或者tel为“13022223333”的文档\n   > db.students.find({'$or': [{name: '骆昊'}, {tel: '13022223333'}]}, {_id: 0, name: 1, tel: 1}).pretty()\n   { \"name\" : \"骆昊\", \"tel\" : \"13566778899\" }\n   { \"name\" : \"白元芳\", \"tel\" : \"13022223333\" }\n   > // 查询学生文档跳过第1条文档只查1条文档\n   > db.students.find().skip(1).limit(1).pretty()\n   {\n           \"_id\" : ObjectId(\"5b13c790006ad854460ee70c\"),\n           \"stuid\" : 1002,\n           \"name\" : \"王大锤\",\n           \"tel\" : \"13012345678\",\n           \"gender\" : \"男\"\n   }\n   > // 对查询结果进行排序(1表示升序，-1表示降序)\n   > db.students.find({}, {_id: 0, stuid: 1, name: 1}).sort({stuid: -1})\n   { \"stuid\" : 1003, \"name\" : \"白元芳\" }\n   { \"stuid\" : 1002, \"name\" : \"王大锤\" }\n   { \"stuid\" : 1001, \"name\" : \"骆昊\" }\n   > // 在指定的一个或多个字段上创建索引\n   > db.students.ensureIndex({name: 1})\n   {\n           \"createdCollectionAutomatically\" : false,\n           \"numIndexesBefore\" : 1,\n           \"numIndexesAfter\" : 2,\n           \"ok\" : 1\n   }\n   > \n   ```\n\n使用MongoDB可以非常方便的配置数据复制，通过冗余数据来实现数据的高可用以及灾难恢复，也可以通过数据分片来应对数据量迅速增长的需求。关于MongoDB更多的操作可以查阅[官方文档](https://mongodb-documentation.readthedocs.io/en/latest/) ，同时推荐大家阅读Kristina Chodorow写的[《MongoDB权威指南》](http://www.ituring.com.cn/book/1172)。\n\n####在Python程序中操作MongoDB\n\n可以通过pip安装pymongo来实现对MongoDB的操作。\n\n```Shell\n\n$ pip3 install pymongo\n$ python3\n```\n\n```Python\n\n>>> from pymongo import MongoClient\n>>> client = MongoClient('mongodb://120.77.222.217:27017') \n>>> db = client.school\n>>> for student in db.students.find():\n...     print('学号:', student['stuid'])\n...     print('姓名:', student['name'])\n...     print('电话:', student['tel'])\n... \n学号: 1001.0\n姓名: 骆昊\n电话: 13566778899\n学号: 1002.0\n姓名: 王大锤\n电话: 13012345678\n学号: 1003.0\n姓名: 白元芳\n电话: 13022223333\n>>> db.students.find().count()\n3\n>>> db.students.remove()\n{'n': 3, 'ok': 1.0}\n>>> db.students.find().count()\n0\n>>> coll = db.students\n>>> from pymongo import ASCENDING\n>>> coll.create_index([('name', ASCENDING)], unique=True)\n'name_1'\n>>> coll.insert_one({'stuid': int(1001), 'name': '骆昊', 'gender': True})\n<pymongo.results.InsertOneResult object at 0x1050cc6c8>\n>>> coll.insert_many([{'stuid': int(1002), 'name': '王大锤', 'gender': False}, {'stuid': int(1003), 'name': '白元芳', 'gender': True}])\n<pymongo.results.InsertManyResult object at 0x1050cc8c8>\n>>> for student in coll.find({'gender': True}):\n...     print('学号:', student['stuid'])\n...     print('姓名:', student['name'])\n...     print('性别:', '男' if student['gender'] else '女')\n... \n学号: 1001\n姓名: 骆昊\n性别: 男\n学号: 1003\n姓名: 白元芳\n性别: 男\n>>> \n```\n\n关于PyMongo更多的知识可以通过它的[官方文档](https://api.mongodb.com/python/current/tutorial.html)进行了解。\n\n### 实例 - 缓存知乎发现上的链接和页面代码\n\n```Python\n\nfrom hashlib import sha1\nfrom urllib.parse import urljoin\n\nimport pickle\nimport re\nimport requests\nimport zlib\n\nfrom bs4 import BeautifulSoup\nfrom redis import Redis\n\n\ndef main():\n    # 指定种子页面\n    base_url = 'https://www.zhihu.com/'\n    seed_url = urljoin(base_url, 'explore')\n    # 创建Redis客户端\n    client = Redis(host='1.2.3.4', port=6379, password='1qaz2wsx')\n    # 设置用户代理(否则访问会被拒绝)\n    headers = {'user-agent': 'Baiduspider'}\n    # 通过requests模块发送GET请求并指定用户代理\n    resp = requests.get(seed_url, headers=headers)\n    # 创建BeautifulSoup对象并指定使用lxml作为解析器\n    soup = BeautifulSoup(resp.text, 'lxml')\n    href_regex = re.compile(r'^/question')\n    # 将URL处理成SHA1摘要(长度固定更简短)\n    hasher_proto = sha1()\n    # 查找所有href属性以/question打头的a标签\n    for a_tag in soup.find_all('a', {'href': href_regex}):\n        # 获取a标签的href属性值并组装完整的URL\n        href = a_tag.attrs['href']\n        full_url = urljoin(base_url, href)\n        # 传入URL生成SHA1摘要\n        hasher = hasher_proto.copy()\n        hasher.update(full_url.encode('utf-8'))\n        field_key = hasher.hexdigest()\n        # 如果Redis的键'zhihu'对应的hash数据类型中没有URL的摘要就访问页面并缓存\n        if not client.hexists('zhihu', field_key):\n            html_page = requests.get(full_url, headers=headers).text\n            # 对页面进行序列化和压缩操作\n            zipped_page = zlib.compress(pickle.dumps(html_page))\n            # 使用hash数据类型保存URL摘要及其对应的页面代码\n            client.hset('zhihu', field_key, zipped_page)\n    # 显示总共缓存了多少个页面\n    print('Total %d question pages found.' % client.hlen('zhihu'))\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n\n\n\n\n\n\n"
  },
  {
    "path": "Day66-75/04.并发下载.md",
    "content": "## 并发下载\n\n### 多线程和多进程回顾\n\n在前面的[《进程和线程》](../Day01-15/Day13/进程和线程.md)一文中，我们已经对在Python中使用多进程和多线程实现并发编程进行了简明的讲解，在此我们补充几个知识点。\n\n#### threading.local类\n\n使用线程时最不愿意遇到的情况就是多个线程竞争资源，在这种情况下为了保证资源状态的正确性，我们可能需要对资源进行加锁保护的处理，这一方面会导致程序失去并发性，另外如果多个线程竞争多个资源时，还有可能因为加锁方式的不当导致[死锁](https://zh.wikipedia.org/wiki/%E6%AD%BB%E9%94%81)。要解决多个线程竞争资源的问题，其中一个方案就是让每个线程都持有资源的副本（拷贝），这样每个线程可以操作自己所持有的资源，从而规避对资源的竞争。\n\n要实现将资源和持有资源的线程进行绑定的操作，最简单的做法就是使用threading模块的local类，在网络爬虫开发中，就可以使用local类为每个线程绑定一个MySQL数据库连接或Redis客户端对象，这样通过线程可以直接获得这些资源，既解决了资源竞争的问题，又避免了在函数和方法调用时传递这些资源。具体的请参考本章多线程爬取“手机搜狐网”（Redis版）的实例代码。\n\n#### concurrent.futures模块\n\nPython3.2带来了`concurrent.futures` 模块，这个模块包含了线程池和进程池、管理并行编程任务、处理非确定性的执行流程、进程/线程同步等功能。关于这部分的内容推荐大家阅读[《Python并行编程》](http://python-parallel-programmning-cookbook.readthedocs.io/zh_CN/latest/index.html)。\n\n#### 分布式进程 \n\n使用多进程的时候，可以将进程部署在多个主机节点上，Python的`multiprocessing`模块不但支持多进程，其中`managers`子模块还支持把多进程部署到多个节点上。当然，要部署分布式进程，首先需要一个服务进程作为调度者，进程之间通过网络进行通信来实现对进程的控制和调度，由于`managers`模块已经对这些做出了很好的封装，因此在无需了解网络通信细节的前提下，就可以编写分布式多进程应用。具体的请参照本章分布式多进程爬取“手机搜狐网”的实例代码。\n\n### 协程和异步I/O\n\n#### 协程的概念\n\n协程（coroutine）通常又称之为微线程或纤程，它是相互协作的一组子程序（函数）。所谓相互协作指的是在执行函数A时，可以随时中断去执行函数B，然后又中断继续执行函数A。注意，这一过程并不是函数调用（因为没有调用语句），整个过程看似像多线程，然而协程只有一个线程执行。协程通过`yield`关键字和 `send()`操作来转移执行权，协程之间不是调用者与被调用者的关系。\n\n协程的优势在于以下两点：\n\n1. 执行效率极高，因为子程序（函数）切换不是线程切换，由程序自身控制，没有切换线程的开销。\n2. 不需要多线程的锁机制，因为只有一个线程，也不存在竞争资源的问题，当然也就不需要对资源加锁保护，因此执行效率高很多。\n\n> 说明：协程适合处理的是I/O密集型任务，处理CPU密集型任务并不是它的长处，如果要提升CPU的利用率可以考虑“多进程+协程”的模式。\n\n#### 历史回顾\n\n1. Python 2.2：第一次提出了生成器（最初称之为迭代器）的概念（PEP 255）。\n2. Python 2.5：引入了将对象发送回暂停了的生成器这一特性即生成器的`send()`方法（PEP 342）。\n3. Python 3.3：添加了`yield from`特性，允许从迭代器中返回任何值（注意生成器本身也是迭代器），这样我们就可以串联生成器并且重构出更好的生成器。\n4. Python 3.4：引入`asyncio.coroutine`装饰器用来标记作为协程的函数，协程函数和`asyncio`及其事件循环一起使用，来实现异步I/O操作。\n5. Python 3.5：引入了`async`和`await`，可以使用`async def`来定义一个协程函数，这个函数中不能包含任何形式的`yield`语句，但是可以使用`return`或`await`从协程中返回值。\n\n#### 示例代码\n\n1. 生成器 - 数据的生产者。\n\n   ```Python\n   \n   from time import sleep\n   \n   \n   # 倒计数生成器\n   def countdown(n):\n       while n > 0:\n           yield n\n           n -= 1\n   \n   \n   def main():\n       for num in countdown(5):\n           print(f'Countdown: {num}')\n           sleep(1)\n       print('Countdown Over!')\n   \n   \n   if __name__ == '__main__':\n       main()\n   \n   ```\n\n   生成器还可以叠加来组成生成器管道，代码如下所示。\n\n   ```Python\n   \n   # Fibonacci数生成器\n   def fib():\n       a, b = 0, 1\n       while True:\n           a, b = b, a + b\n           yield a\n   \n   \n   # 偶数生成器\n   def even(gen):\n       for val in gen:\n           if val % 2 == 0:\n               yield val\n   \n   \n   def main():\n       gen = even(fib())\n       for _ in range(10):\n           print(next(gen))\n   \n   \n   if __name__ == '__main__':\n       main()\n   \n   ```\n\n2. 协程 - 数据的消费者。\n\n   ```Python\n   \n   from time import sleep\n   \n   \n   # 生成器 - 数据生产者\n   def countdown_gen(n, consumer):\n       consumer.send(None)\n       while n > 0:\n           consumer.send(n)\n           n -= 1\n       consumer.send(None)\n   \n   \n   # 协程 - 数据消费者\n   def countdown_con():\n       while True:\n           n = yield\n           if n:\n               print(f'Countdown {n}')\n               sleep(1)\n           else:\n               print('Countdown Over!')\n   \n   \n   def main():\n       countdown_gen(5, countdown_con())\n   \n   \n   if __name__ == '__main__':\n       main()\n   \n   ```\n\n   > 说明：上面代码中countdown_gen函数中的第1行consumer.send(None)是为了激活生成器，通俗的说就是让生成器执行到有yield关键字的地方挂起，当然也可以通过next(consumer)来达到同样的效果。如果不愿意每次都用这样的代码来“预激”生成器，可以写一个包装器来完成该操作，代码如下所示。\n\n   ```Python\n   \n   from functools import wraps\n   \n   \n   def coroutine(fn):\n   \n       @wraps(fn)\n       def wrapper(*args, **kwargs):\n           gen = fn(*args, **kwargs)\n           next(gen)\n           return gen\n   \n       return wrapper\n   ```\n\n   这样就可以使用`@coroutine`装饰器对协程进行预激操作，不需要再写重复代码来激活协程。\n\n3. 异步I/O - 非阻塞式I/O操作。\n\n   ```Python\n   \n   import asyncio\n   \n   \n   @asyncio.coroutine\n   def countdown(name, n):\n       while n > 0:\n           print(f'Countdown[{name}]: {n}')\n           yield from asyncio.sleep(1)\n           n -= 1\n   \n   \n   def main():\n       loop = asyncio.get_event_loop()\n       tasks = [\n           countdown(\"A\", 10), countdown(\"B\", 5),\n       ]\n       loop.run_until_complete(asyncio.wait(tasks))\n       loop.close()\n   \n   \n   if __name__ == '__main__':\n       main()\n   \n   ```\n\n4.  `async`和`await`。\n\n   ```Python\n   \n   import asyncio\n   import aiohttp\n   \n   \n   async def download(url):\n       print('Fetch:', url)\n       async with aiohttp.ClientSession() as session:\n           async with session.get(url) as resp:\n               print(url, '--->', resp.status)\n               print(url, '--->', resp.cookies)\n               print('\\n\\n', await resp.text())\n   \n   \n   def main():\n       loop = asyncio.get_event_loop()\n       urls = [\n           'https://www.baidu.com',\n           'http://www.sohu.com/',\n           'http://www.sina.com.cn/',\n           'https://www.taobao.com/',\n           'https://www.jd.com/'\n       ]\n       tasks = [download(url) for url in urls]\n       loop.run_until_complete(asyncio.wait(tasks))\n       loop.close()\n   \n   \n   if __name__ == '__main__':\n       main()\n   \n   ```\n\n   上面的代码使用了[AIOHTTP](https://github.com/aio-libs/aiohttp)这个非常著名的第三方库，它实现了HTTP客户端和HTTP服务器的功能，对异步操作提供了非常好的支持，有兴趣可以阅读它的[官方文档](https://aiohttp.readthedocs.io/en/stable/)。\n\n### 实例 - 多线程爬取“手机搜狐网”所有页面\n\n下面我们把之间讲的所有知识结合起来，用面向对象的方式实现一个爬取“手机搜狐网”的多线程爬虫。\n\n```Python\n\nimport pickle\nimport zlib\nfrom enum import Enum, unique\nfrom hashlib import sha1\nfrom random import random\nfrom threading import Thread, current_thread, local\nfrom time import sleep\nfrom urllib.parse import urlparse\n\nimport pymongo\nimport redis\nimport requests\nfrom bs4 import BeautifulSoup\nfrom bson import Binary\n\n\n@unique\nclass SpiderStatus(Enum):\n    IDLE = 0\n    WORKING = 1\n\n\ndef decode_page(page_bytes, charsets=('utf-8',)):\n    page_html = None\n    for charset in charsets:\n        try:\n            page_html = page_bytes.decode(charset)\n            break\n        except UnicodeDecodeError:\n            pass\n    return page_html\n\n\nclass Retry(object):\n\n    def __init__(self, *, retry_times=3,\n                 wait_secs=5, errors=(Exception, )):\n        self.retry_times = retry_times\n        self.wait_secs = wait_secs\n        self.errors = errors\n\n    def __call__(self, fn):\n\n        def wrapper(*args, **kwargs):\n            for _ in range(self.retry_times):\n                try:\n                    return fn(*args, **kwargs)\n                except self.errors as e:\n                    print(e)\n                    sleep((random() + 1) * self.wait_secs)\n            return None\n\n        return wrapper\n\n\nclass Spider(object):\n\n    def __init__(self):\n        self.status = SpiderStatus.IDLE\n\n    @Retry()\n    def fetch(self, current_url, *, charsets=('utf-8', ),\n              user_agent=None, proxies=None):\n        thread_name = current_thread().name\n        print(f'[{thread_name}]: {current_url}')\n        headers = {'user-agent': user_agent} if user_agent else {}\n        resp = requests.get(current_url,\n                            headers=headers, proxies=proxies)\n        return decode_page(resp.content, charsets) \\\n            if resp.status_code == 200 else None\n\n    def parse(self, html_page, *, domain='m.sohu.com'):\n        soup = BeautifulSoup(html_page, 'lxml')\n        for a_tag in soup.body.select('a[href]'):\n            parser = urlparse(a_tag.attrs['href'])\n            scheme = parser.scheme or 'http'\n            netloc = parser.netloc or domain\n            if scheme != 'javascript' and netloc == domain:\n                path = parser.path\n                query = '?' + parser.query if parser.query else ''\n                full_url = f'{scheme}://{netloc}{path}{query}'\n                redis_client = thread_local.redis_client\n                if not redis_client.sismember('visited_urls', full_url):\n                    redis_client.rpush('m_sohu_task', full_url)\n\n    def extract(self, html_page):\n        pass\n\n    def store(self, data_dict):\n        # redis_client = thread_local.redis_client\n        # mongo_db = thread_local.mongo_db\n        pass\n\n\nclass SpiderThread(Thread):\n\n    def __init__(self, name, spider):\n        super().__init__(name=name, daemon=True)\n        self.spider = spider\n\n    def run(self):\n        redis_client = redis.Redis(host='1.2.3.4', port=6379, password='1qaz2wsx')\n        mongo_client = pymongo.MongoClient(host='1.2.3.4', port=27017)\n        thread_local.redis_client = redis_client\n        thread_local.mongo_db = mongo_client.msohu \n        while True:\n            current_url = redis_client.lpop('m_sohu_task')\n            while not current_url:\n                current_url = redis_client.lpop('m_sohu_task')\n            self.spider.status = SpiderStatus.WORKING\n            current_url = current_url.decode('utf-8')\n            if not redis_client.sismember('visited_urls', current_url):\n                redis_client.sadd('visited_urls', current_url)\n                html_page = self.spider.fetch(current_url)\n                if html_page not in [None, '']:\n                    hasher = hasher_proto.copy()\n                    hasher.update(current_url.encode('utf-8'))\n                    doc_id = hasher.hexdigest()\n                    sohu_data_coll = mongo_client.msohu.webpages\n                    if not sohu_data_coll.find_one({'_id': doc_id}):\n                        sohu_data_coll.insert_one({\n                            '_id': doc_id,\n                            'url': current_url,\n                            'page': Binary(zlib.compress(pickle.dumps(html_page)))\n                        })\n                    self.spider.parse(html_page)\n            self.spider.status = SpiderStatus.IDLE\n\n\ndef is_any_alive(spider_threads):\n    return any([spider_thread.spider.status == SpiderStatus.WORKING\n                for spider_thread in spider_threads])\n\n\nthread_local = local()\nhasher_proto = sha1()\n\n\ndef main():\n    redis_client = redis.Redis(host='1.2.3.4', port=6379, password='1qaz2wsx')\n    if not redis_client.exists('m_sohu_task'):\n        redis_client.rpush('m_sohu_task', 'http://m.sohu.com/')\n\n    spider_threads = [SpiderThread('thread-%d' % i, Spider())\n                      for i in range(10)]\n    for spider_thread in spider_threads:\n        spider_thread.start()\n\n    while redis_client.exists('m_sohu_task') or is_any_alive(spider_threads):\n        sleep(5)\n\n    print('Over!')\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\n"
  },
  {
    "path": "Day66-75/05.解析动态内容.md",
    "content": "## 解析动态内容\n\n### JavaScript逆向工程\n\n\n\n### 使用Selenium\n\n\n"
  },
  {
    "path": "Day66-75/06.表单交互和验证码处理.md",
    "content": "## 表单交互和验证码处理\n\n### 提交表单\n\n#### 手动提交\n\n\n\n#### 自动提交\n\n\n\n### 验证码处理\n\n#### 加载验证码\n\n\n\n#### 光学字符识别\n\n光学字符识别（OCR）是从图像中抽取文本的工具，可以应用于公安、电信、物流、金融等诸多行业，例如识别车牌，身份证扫描识别、名片信息提取等。在爬虫开发中，如果遭遇了有文字验证码的表单，就可以利用OCR来进行验证码处理。Tesseract-OCR引擎最初是由惠普公司开发的光学字符识别系统，目前发布在Github上，由Google赞助开发。\n\n![](./res/tesseract.gif)\n\n#### 改善OCR\n\n\n\n#### 处理更复杂的验证码\n\n\n\n#### 验证码处理服务\n\n"
  },
  {
    "path": "Day66-75/Scrapy爬虫框架入门.md",
    "content": "## Scrapy爬虫框架入门\n\n### Scrapy概述\n\nScrapy是Python开发的一个非常流行的网络爬虫框架，可以用来抓取Web站点并从页面中提取结构化的数据，被广泛的用于数据挖掘、数据监测和自动化测试等领域。下图展示了Scrapy的基本架构，其中包含了主要组件和系统的数据处理流程（图中带数字的红色箭头）。\n\n![](./res/scrapy-architecture.png)\n\n#### 组件\n\n1. Scrapy引擎（Engine）：Scrapy引擎是用来控制整个系统的数据处理流程。\n2. 调度器（Scheduler）：调度器从Scrapy引擎接受请求并排序列入队列，并在Scrapy引擎发出请求后返还给它们。\n3. 下载器（Downloader）：下载器的主要职责是抓取网页并将网页内容返还给蜘蛛（Spiders）。\n4. 蜘蛛（Spiders）：蜘蛛是有Scrapy用户自定义的用来解析网页并抓取特定URL返回的内容的类，每个蜘蛛都能处理一个域名或一组域名，简单的说就是用来定义特定网站的抓取和解析规则。\n5. 条目管道（Item Pipeline）：条目管道的主要责任是负责处理有蜘蛛从网页中抽取的数据条目，它的主要任务是清理、验证和存储数据。当页面被蜘蛛解析后，将被发送到条目管道，并经过几个特定的次序处理数据。每个条目管道组件都是一个Python类，它们获取了数据条目并执行对数据条目进行处理的方法，同时还需要确定是否需要在条目管道中继续执行下一步或是直接丢弃掉不处理。条目管道通常执行的任务有：清理HTML数据、验证解析到的数据（检查条目是否包含必要的字段）、检查是不是重复数据（如果重复就丢弃）、将解析到的数据存储到数据库（关系型数据库或NoSQL数据库）中。\n6. 中间件（Middlewares）：中间件是介于Scrapy引擎和其他组件之间的一个钩子框架，主要是为了提供自定义的代码来拓展Scrapy的功能，包括下载器中间件和蜘蛛中间件。\n\n#### 数据处理流程\n\nScrapy的整个数据处理流程由Scrapy引擎进行控制，通常的运转流程包括以下的步骤：\n\n1. 引擎询问蜘蛛需要处理哪个网站，并让蜘蛛将第一个需要处理的URL交给它。\n\n2. 引擎让调度器将需要处理的URL放在队列中。\n\n3. 引擎从调度那获取接下来进行爬取的页面。\n\n4. 调度将下一个爬取的URL返回给引擎，引擎将它通过下载中间件发送到下载器。\n\n5. 当网页被下载器下载完成以后，响应内容通过下载中间件被发送到引擎；如果下载失败了，引擎会通知调度器记录这个URL，待会再重新下载。\n\n6. 引擎收到下载器的响应并将它通过蜘蛛中间件发送到蜘蛛进行处理。\n\n7. 蜘蛛处理响应并返回爬取到的数据条目，此外还要将需要跟进的新的URL发送给引擎。\n\n8. 引擎将抓取到的数据条目送入条目管道，把新的URL发送给调度器放入队列中。\n\n上述操作中的2-8步会一直重复直到调度器中没有需要请求的URL，爬虫停止工作。\n\n### 安装和使用Scrapy\n\n可以先创建虚拟环境并在虚拟环境下使用pip安装scrapy。\n\n```Shell\n\n$ \n```\n\n项目的目录结构如下图所示。\n\n```Shell\n\n(venv) $ tree\n.\n|____ scrapy.cfg\n|____ douban\n| |____ spiders\n| | |____ __init__.py\n| | |____ __pycache__\n| |____ __init__.py\n| |____ __pycache__\n| |____ middlewares.py\n| |____ settings.py\n| |____ items.py\n| |____ pipelines.py\n```\n\n> 说明：Windows系统的命令行提示符下有tree命令，但是Linux和MacOS的终端是没有tree命令的，可以用下面给出的命令来定义tree命令，其实是对find命令进行了定制并别名为tree。 \n>\n> `alias tree=\"find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g'\"`\n>\n> Linux系统也可以通过yum或其他的包管理工具来安装tree。\n>\n> `yum install tree`\n\n根据刚才描述的数据处理流程，基本上需要我们做的有以下几件事情：\n\n1. 在items.py文件中定义字段，这些字段用来保存数据，方便后续的操作。\n\n   ```Python\n   \n   # -*- coding: utf-8 -*-\n   \n   # Define here the models for your scraped items\n   #\n   # See documentation in:\n   # https://doc.scrapy.org/en/latest/topics/items.html\n   \n   import scrapy\n   \n   \n   class DoubanItem(scrapy.Item):\n   \n       name = scrapy.Field()\n       year = scrapy.Field()\n       score = scrapy.Field()\n       director = scrapy.Field()\n       classification = scrapy.Field()\n       actor = scrapy.Field()\n   ```\n\n2. 在spiders文件夹中编写自己的爬虫。\n\n   ```Shell\n   \n   (venv) $ scrapy genspider movie movie.douban.com --template=crawl\n   ```\n\n   ```Python\n   \n   # -*- coding: utf-8 -*-\n   import scrapy\n   from scrapy.selector import Selector\n   from scrapy.linkextractors import LinkExtractor\n   from scrapy.spiders import CrawlSpider, Rule\n   \n   from douban.items import DoubanItem\n   \n   \n   class MovieSpider(CrawlSpider):\n       name = 'movie'\n       allowed_domains = ['movie.douban.com']\n       start_urls = ['https://movie.douban.com/top250']\n       rules = (\n           Rule(LinkExtractor(allow=(r'https://movie.douban.com/top250\\?start=\\d+.*'))),\n           Rule(LinkExtractor(allow=(r'https://movie.douban.com/subject/\\d+')), callback='parse_item'),\n       )\n   \n       def parse_item(self, response):\n           sel = Selector(response)\n           item = DoubanItem()\n           item['name']=sel.xpath('//*[@id=\"content\"]/h1/span[1]/text()').extract()\n           item['year']=sel.xpath('//*[@id=\"content\"]/h1/span[2]/text()').re(r'\\((\\d+)\\)')\n           item['score']=sel.xpath('//*[@id=\"interest_sectl\"]/div/p[1]/strong/text()').extract()\n           item['director']=sel.xpath('//*[@id=\"info\"]/span[1]/a/text()').extract()\n           item['classification']= sel.xpath('//span[@property=\"v:genre\"]/text()').extract()\n           item['actor']= sel.xpath('//*[@id=\"info\"]/span[3]/a[1]/text()').extract()\n           return item\n   \n   ```\n   > 说明：上面我们通过Scrapy提供的爬虫模板创建了Spider，其中的rules中的LinkExtractor对象会自动完成对新的链接的解析，该对象中有一个名为extract_link的回调方法。Scrapy支持用XPath语法和CSS选择器进行数据解析，对应的方法分别是xpath和css，上面我们使用了XPath语法对页面进行解析，如果不熟悉XPath语法可以看看后面的补充说明。\n\n   到这里，我们已经可以通过下面的命令让爬虫运转起来。\n\n   ```Shell\n   \n   (venv)$ scrapy crawl movie\n   ```\n\n   可以在控制台看到爬取到的数据，如果想将这些数据保存到文件中，可以通过`-o`参数来指定文件名，Scrapy支持我们将爬取到的数据导出成JSON、CSV、XML、pickle、marshal等格式。\n\n   ```Shell\n   \n   (venv)$ scrapy crawl moive -o result.json\n   ```\n\n3. 在pipelines.py中完成对数据进行持久化的操作。\n\n   ```Python\n   \n   # -*- coding: utf-8 -*-\n   \n   # Define your item pipelines here\n   #\n   # Don't forget to add your pipeline to the ITEM_PIPELINES setting\n   # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html\n   import pymongo\n   \n   from scrapy.exceptions import DropItem\n   from scrapy.conf import settings\n   from scrapy import log\n   \n   \n   class DoubanPipeline(object):\n   \n       def __init__(self):\n           connection = pymongo.MongoClient(settings['MONGODB_SERVER'], settings['MONGODB_PORT'])\n           db = connection[settings['MONGODB_DB']]\n           self.collection = db[settings['MONGODB_COLLECTION']]\n   \n       def process_item(self, item, spider):\n           #Remove invalid data\n           valid = True\n           for data in item:\n             if not data:\n               valid = False\n               raise DropItem(\"Missing %s of blogpost from %s\" %(data, item['url']))\n           if valid:\n           #Insert data into database\n               new_moive=[{\n                   \"name\":item['name'][0],\n                   \"year\":item['year'][0],\n                   \"score\":item['score'],\n                   \"director\":item['director'],\n                   \"classification\":item['classification'],\n                   \"actor\":item['actor']\n               }]\n               self.collection.insert(new_moive)\n               log.msg(\"Item wrote to MongoDB database %s/%s\" %\n               (settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),\n               level=log.DEBUG, spider=spider) \n           return item\n   \n   ```\n   利用Pipeline我们可以完成以下操作：\n\n   - 清理HTML数据，验证爬取的数据。\n   - 丢弃重复的不必要的内容。\n   - 将爬取的结果进行持久化操作。\n\n4. 修改settings.py文件对项目进行配置。\n\n   ```Python\n   \n   # -*- coding: utf-8 -*-\n   \n   # Scrapy settings for douban project\n   #\n   # For simplicity, this file contains only settings considered important or\n   # commonly used. You can find more settings consulting the documentation:\n   #\n   #     https://doc.scrapy.org/en/latest/topics/settings.html\n   #     https://doc.scrapy.org/en/latest/topics/downloader-middleware.html\n   #     https://doc.scrapy.org/en/latest/topics/spider-middleware.html\n   \n   BOT_NAME = 'douban'\n   \n   SPIDER_MODULES = ['douban.spiders']\n   NEWSPIDER_MODULE = 'douban.spiders'\n   \n   \n   # Crawl responsibly by identifying yourself (and your website) on the user-agent\n   USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'\n   \n   # Obey robots.txt rules\n   ROBOTSTXT_OBEY = True\n   \n   # Configure maximum concurrent requests performed by Scrapy (default: 16)\n   # CONCURRENT_REQUESTS = 32\n   \n   # Configure a delay for requests for the same website (default: 0)\n   # See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay\n   # See also autothrottle settings and docs\n   DOWNLOAD_DELAY = 3\n   RANDOMIZE_DOWNLOAD_DELAY = True\n   # The download delay setting will honor only one of:\n   # CONCURRENT_REQUESTS_PER_DOMAIN = 16\n   # CONCURRENT_REQUESTS_PER_IP = 16\n   \n   # Disable cookies (enabled by default)\n   COOKIES_ENABLED = True\n   \n   MONGODB_SERVER = '120.77.222.217'\n   MONGODB_PORT = 27017\n   MONGODB_DB = 'douban'\n   MONGODB_COLLECTION = 'movie'\n   \n   # Disable Telnet Console (enabled by default)\n   # TELNETCONSOLE_ENABLED = False\n   \n   # Override the default request headers:\n   # DEFAULT_REQUEST_HEADERS = {\n   #   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\n   #   'Accept-Language': 'en',\n   # }\n   \n   # Enable or disable spider middlewares\n   # See https://doc.scrapy.org/en/latest/topics/spider-middleware.html\n   # SPIDER_MIDDLEWARES = {\n   #    'douban.middlewares.DoubanSpiderMiddleware': 543,\n   # }\n   \n   # Enable or disable downloader middlewares\n   # See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html\n   # DOWNLOADER_MIDDLEWARES = {\n   #    'douban.middlewares.DoubanDownloaderMiddleware': 543,\n   # }\n   \n   # Enable or disable extensions\n   # See https://doc.scrapy.org/en/latest/topics/extensions.html\n   # EXTENSIONS = {\n   #    'scrapy.extensions.telnet.TelnetConsole': None,\n   # }\n   \n   # Configure item pipelines\n   # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html\n   ITEM_PIPELINES = {\n       'douban.pipelines.DoubanPipeline': 400,\n   }\n   \n   LOG_LEVEL = 'DEBUG'\n   \n   # Enable and configure the AutoThrottle extension (disabled by default)\n   # See https://doc.scrapy.org/en/latest/topics/autothrottle.html\n   #AUTOTHROTTLE_ENABLED = True\n   # The initial download delay\n   #AUTOTHROTTLE_START_DELAY = 5\n   # The maximum download delay to be set in case of high latencies\n   #AUTOTHROTTLE_MAX_DELAY = 60\n   # The average number of requests Scrapy should be sending in parallel to\n   # each remote server\n   #AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0\n   # Enable showing throttling stats for every response received:\n   #AUTOTHROTTLE_DEBUG = False\n   \n   # Enable and configure HTTP caching (disabled by default)\n   # See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings\n   HTTPCACHE_ENABLED = True\n   HTTPCACHE_EXPIRATION_SECS = 0\n   HTTPCACHE_DIR = 'httpcache'\n   HTTPCACHE_IGNORE_HTTP_CODES = []\n   HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'\n   ```\n\n### 补充说明\n\n#### XPath语法\n\n1. XPath路径表达式：XPath使用路径表达式来选取XML文档中的节点或者节点集。\n\n2. XPath节点：元素、属性、文本、命名空间、处理指令、注释、根节点。\n\n3. XPath语法。（注：下面的例子来自于[菜鸟教程](http://www.runoob.com/)网站的[XPath教程](http://www.runoob.com/xpath/xpath-syntax.html)。)\n\n   XML文件。\n\n   ```XML\n   \n   <?xml version=\"1.0\" encoding=\"UTF-8\"?>\n   \n   <bookstore>\n   \n       <book>\n         <title lang=\"eng\">Harry Potter</title>\n         <price>29.99</price>\n       </book>\n   \n       <book>\n         <title lang=\"eng\">Learning XML</title>\n         <price>39.95</price>\n       </book>\n   \n   </bookstore>\n   ```\n   XPath语法。\n\n   | 路径表达式      | 结果                                                         |\n   | --------------- | ------------------------------------------------------------ |\n   | bookstore       | 选取 bookstore 元素的所有子节点。                            |\n   | /bookstore      | 选取根元素 bookstore。注释：假如路径起始于正斜杠( / )，则此路径始终代表到某元素的绝对路径！ |\n   | bookstore/book  | 选取属于 bookstore 的子元素的所有 book 元素。                |\n   | //book          | 选取所有 book 子元素，而不管它们在文档中的位置。             |\n   | bookstore//book | 选择属于 bookstore 元素的后代的所有 book 元素，而不管它们位于 bookstore 之下的什么位置。 |\n   | //@lang         | 选取名为 lang 的所有属性。                                   |\n\n   XPath谓词。\n\n   | 路径表达式                         | 结果                                                         |\n   | ---------------------------------- | ------------------------------------------------------------ |\n   | /bookstore/book[1]                 | 选取属于 bookstore 子元素的第一个 book 元素。                |\n   | /bookstore/book[last()]            | 选取属于 bookstore 子元素的最后一个 book 元素。              |\n   | /bookstore/book[last()-1]          | 选取属于 bookstore 子元素的倒数第二个 book 元素。            |\n   | /bookstore/book[position()<3]      | 选取最前面的两个属于 bookstore 元素的子元素的 book 元素。    |\n   | //title[@lang]                     | 选取所有拥有名为 lang 的属性的 title 元素。                  |\n   | //title[@lang='eng']               | 选取所有 title 元素，且这些元素拥有值为 eng 的 lang 属性。   |\n   | /bookstore/book[price>35.00]       | 选取 bookstore 元素的所有 book 元素，且其中的 price 元素的值须大于 35.00。 |\n   | /bookstore/book[price>35.00]/title | 选取 bookstore 元素中的 book 元素的所有 title 元素，且其中的 price 元素的值须大于 35.00。 |\n\n   通配符用法。\n\n   | 路径表达式   | 结果                              |\n   | ------------ | --------------------------------- |\n   | /bookstore/* | 选取 bookstore 元素的所有子元素。 |\n   | //*          | 选取文档中的所有元素。            |\n   | //title[@*]  | 选取所有带有属性的 title 元素。   |\n\n   选取多个路径。\n\n   | 路径表达式                       | 结果                                                         |\n   | -------------------------------- | ------------------------------------------------------------ |\n   | //book/title \\| //book/price     | 选取 book 元素的所有 title 和 price 元素。                   |\n   | //title \\| //price               | 选取文档中的所有 title 和 price 元素。                       |\n   | /bookstore/book/title \\| //price | 选取属于 bookstore 元素的 book 元素的所有 title 元素，以及文档中所有的 price 元素。 |\n\n#### 在Chrome浏览器中查看元素XPath语法\n\n![](./res/douban-xpath.png)\n\n"
  },
  {
    "path": "Day66-75/Scrapy爬虫框架分布式实现.md",
    "content": "## Scrapy爬虫框架分布式实现\n\n### 分布式爬虫原理\n\n\n\n### Scrapy分布式实现\n\n1. 安装Scrapy-Redis。\n2. 配置Redis服务器。\n3. 修改配置文件。\n   - SCHEDULER = 'scrapy_redis.scheduler.Scheduler'\n   - DUPEFILTER_CLASS = 'scrapy_redis.dupefilter.RFPDupeFilter'\n   - REDIS_HOST = '1.2.3.4'\n   - REDIS_PORT = 6379\n   - REDIS_PASSWORD = '1qaz2wsx'\n   - SCHEDULER_QUEUE_CLASS = 'scrapy_redis.queue.FifoQueue'\n   - SCHEDULER_PERSIST = True（通过持久化支持接续爬取）\n   - SCHEDULER_FLUSH_ON_START = True（每次启动时重新爬取）\n\n### Scrapyd分布式部署\n\n1. 安装Scrapyd\n2. 修改配置文件\n   - mkdir /etc/scrapyd\n   - vim /etc/scrapyd/scrapyd.conf\n3. 安装Scrapyd-Client\n   - 将项目打包成Egg文件。\n   - 将打包的Egg文件通过addversion.json接口部署到Scrapyd上。\n\n"
  },
  {
    "path": "Day66-75/Scrapy爬虫框架高级应用.md",
    "content": "## Scrapy爬虫框架高级应用\n\n### Spider的用法\n\n在Scrapy框架中，我们自定义的蜘蛛都继承自scrapy.spiders.Spider，这个类有一系列的属性和方法，具体如下所示：\n\n1. name：爬虫的名字。\n2. allowed_domains：允许爬取的域名，不在此范围的链接不会被跟进爬取。\n3. start_urls：起始URL列表，当我们没有重写start_requests()方法时，就会从这个列表开始爬取。\n4. custom_settings：用来存放蜘蛛专属配置的字典，这里的设置会覆盖全局的设置。\n5. crawler：由from_crawler()方法设置的和蜘蛛对应的Crawler对象，Crawler对象包含了很多项目组件，利用它我们可以获取项目的配置信息，如调用crawler.settings.get()方法。\n6. settings：用来获取爬虫全局设置的变量。\n7. start_requests()：此方法用于生成初始请求，它返回一个可迭代对象。该方法默认是使用GET请求访问起始URL，如果起始URL需要使用POST请求来访问就必须重写这个方法。\n8. parse()：当Response没有指定回调函数时，该方法就会被调用，它负责处理Response对象并返回结果，从中提取出需要的数据和后续的请求，该方法需要返回类型为Request或Item的可迭代对象（生成器当前也包含在其中，因此根据实际需要可以用return或yield来产生返回值）。\n9. closed()：当蜘蛛关闭时，该方法会被调用，通常用来做一些释放资源的善后操作。\n\n### 中间件的应用\n\n#### 下载中间件\n\n\n\n#### 蜘蛛中间件\n\n\n\n### Scrapy对接Selenium\n\n\n\n### Scrapy部署到Docker\n\n"
  },
  {
    "path": "Day66-75/code/asyncio01.py",
    "content": "import asyncio\n\n\n@asyncio.coroutine\ndef countdown(name, num):\n    while num > 0:\n        print(f'Countdown[{name}]: {num}')\n        yield from asyncio.sleep(1)\n        num -= 1\n\n\ndef main():\n    loop = asyncio.get_event_loop()\n    tasks = [\n        countdown(\"A\", 10), countdown(\"B\", 5),\n    ]\n    loop.run_until_complete(asyncio.wait(tasks))\n    loop.close()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/asyncio02.py",
    "content": "import asyncio\nimport aiohttp\n\n\nasync def download(url):\n    print('Fetch:', url)\n    async with aiohttp.ClientSession() as session:\n        async with session.get(url) as resp:\n            print(url, '--->', resp.status)\n            print(url, '--->', resp.cookies)\n            print('\\n\\n', await resp.text())\n\n\ndef main():\n    loop = asyncio.get_event_loop()\n    urls = [\n        'https://www.baidu.com',\n        'http://www.sohu.com/',\n        'http://www.sina.com.cn/',\n        'https://www.taobao.com/',\n        'https://www.jd.com/'\n    ]\n    tasks = [download(url) for url in urls]\n    loop.run_until_complete(asyncio.wait(tasks))\n    loop.close()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/coroutine01.py",
    "content": "from time import sleep\n\n\ndef countdown_gen(n, consumer):\n    consumer.send(None)\n    while n > 0:\n        consumer.send(n)\n        n -= 1\n    consumer.send(None)\n\n\ndef countdown_con():\n    while True:\n        n = yield\n        if n:\n            print(f'Countdown {n}')\n            sleep(1)\n        else:\n            print('Countdown Over!')\n\n\ndef main():\n    countdown_gen(5, countdown_con())\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/coroutine02.py",
    "content": "from time import sleep\n\nfrom myutils import coroutine\n\n\n@coroutine\ndef create_delivery_man(name, capacity=1):\n    buffer = []\n    while True:\n        size = 0\n        while size < capacity:\n            pkg_name = yield\n            if pkg_name:\n                size += 1\n                buffer.append(pkg_name)\n                print('%s正在接受%s' % (name, pkg_name))\n            else:\n                break\n        print('=====%s正在派送%d件包裹=====' % (name, len(buffer)))\n        sleep(3)\n        buffer.clear()\n\n\ndef create_package_center(consumer, max_packages):\n    num = 0\n    while num <= max_packages:\n        print('快递中心准备派送%d号包裹' % num)\n        consumer.send('包裹-%d' % num)\n        num += 1\n        if num % 10 == 0:\n            sleep(5)\n    consumer.send(None)\n\n\ndef main():\n    print(create_delivery_man.__name__)\n    dm = create_delivery_man('王大锤', 7)\n    create_package_center(dm, 25)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/douban/douban/__init__.py",
    "content": ""
  },
  {
    "path": "Day66-75/code/douban/douban/items.py",
    "content": "# -*- coding: utf-8 -*-\n\n# Define here the models for your scraped items\n#\n# See documentation in:\n# https://doc.scrapy.org/en/latest/topics/items.html\n\nimport scrapy\n\n\nclass DoubanItem(scrapy.Item):\n\n    name = scrapy.Field()\n    year = scrapy.Field()\n    score = scrapy.Field()\n    director = scrapy.Field()\n    classification = scrapy.Field()\n    actor = scrapy.Field()\n"
  },
  {
    "path": "Day66-75/code/douban/douban/middlewares.py",
    "content": "# -*- coding: utf-8 -*-\n\n# Define here the models for your spider middleware\n#\n# See documentation in:\n# https://doc.scrapy.org/en/latest/topics/spider-middleware.html\n\nfrom scrapy import signals\n\n\nclass DoubanSpiderMiddleware(object):\n    # Not all methods need to be defined. If a method is not defined,\n    # scrapy acts as if the spider middleware does not modify the\n    # passed objects.\n\n    @classmethod\n    def from_crawler(cls, crawler):\n        # This method is used by Scrapy to create your spiders.\n        s = cls()\n        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)\n        return s\n\n    def process_spider_input(self, response, spider):\n        # Called for each response that goes through the spider\n        # middleware and into the spider.\n\n        # Should return None or raise an exception.\n        return None\n\n    def process_spider_output(self, response, result, spider):\n        # Called with the results returned from the Spider, after\n        # it has processed the response.\n\n        # Must return an iterable of Request, dict or Item objects.\n        for i in result:\n            yield i\n\n    def process_spider_exception(self, response, exception, spider):\n        # Called when a spider or process_spider_input() method\n        # (from other spider middleware) raises an exception.\n\n        # Should return either None or an iterable of Response, dict\n        # or Item objects.\n        pass\n\n    def process_start_requests(self, start_requests, spider):\n        # Called with the start requests of the spider, and works\n        # similarly to the process_spider_output() method, except\n        # that it doesn’t have a response associated.\n\n        # Must return only requests (not items).\n        for r in start_requests:\n            yield r\n\n    def spider_opened(self, spider):\n        spider.logger.info('Spider opened: %s' % spider.name)\n\n\nclass DoubanDownloaderMiddleware(object):\n    # Not all methods need to be defined. If a method is not defined,\n    # scrapy acts as if the downloader middleware does not modify the\n    # passed objects.\n\n    @classmethod\n    def from_crawler(cls, crawler):\n        # This method is used by Scrapy to create your spiders.\n        s = cls()\n        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)\n        return s\n\n    def process_request(self, request, spider):\n        # Called for each request that goes through the downloader\n        # middleware.\n\n        # Must either:\n        # - return None: continue processing this request\n        # - or return a Response object\n        # - or return a Request object\n        # - or raise IgnoreRequest: process_exception() methods of\n        #   installed downloader middleware will be called\n        return None\n\n    def process_response(self, request, response, spider):\n        # Called with the response returned from the downloader.\n\n        # Must either;\n        # - return a Response object\n        # - return a Request object\n        # - or raise IgnoreRequest\n        return response\n\n    def process_exception(self, request, exception, spider):\n        # Called when a download handler or a process_request()\n        # (from other downloader middleware) raises an exception.\n\n        # Must either:\n        # - return None: continue processing this exception\n        # - return a Response object: stops process_exception() chain\n        # - return a Request object: stops process_exception() chain\n        pass\n\n    def spider_opened(self, spider):\n        spider.logger.info('Spider opened: %s' % spider.name)\n"
  },
  {
    "path": "Day66-75/code/douban/douban/pipelines.py",
    "content": "# -*- coding: utf-8 -*-\n\n# Define your item pipelines here\n#\n# Don't forget to add your pipeline to the ITEM_PIPELINES setting\n# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html\nimport pymongo\n\nfrom scrapy.exceptions import DropItem\nfrom scrapy.conf import settings\nfrom scrapy import log\n\n\nclass DoubanPipeline(object):\n\n    def __init__(self):\n        connection = pymongo.MongoClient(settings['MONGODB_SERVER'], settings['MONGODB_PORT'])\n        db = connection[settings['MONGODB_DB']]\n        self.collection = db[settings['MONGODB_COLLECTION']]\n\n    def process_item(self, item, spider):\n        #Remove invalid data\n        valid = True\n        for data in item:\n          if not data:\n            valid = False\n            raise DropItem(\"Missing %s of blogpost from %s\" %(data, item['url']))\n        if valid:\n        #Insert data into database\n            new_moive=[{\n                \"name\":item['name'][0],\n                \"year\":item['year'][0],\n                \"score\":item['score'],\n                \"director\":item['director'],\n                \"classification\":item['classification'],\n                \"actor\":item['actor']\n            }]\n            self.collection.insert(new_moive)\n            log.msg(\"Item wrote to MongoDB database %s/%s\" %\n            (settings['MONGODB_DB'], settings['MONGODB_COLLECTION']),\n            level=log.DEBUG, spider=spider) \n        return item\n\n"
  },
  {
    "path": "Day66-75/code/douban/douban/settings.py",
    "content": "# -*- coding: utf-8 -*-\n\n# Scrapy settings for douban project\n#\n# For simplicity, this file contains only settings considered important or\n# commonly used. You can find more settings consulting the documentation:\n#\n#     https://doc.scrapy.org/en/latest/topics/settings.html\n#     https://doc.scrapy.org/en/latest/topics/downloader-middleware.html\n#     https://doc.scrapy.org/en/latest/topics/spider-middleware.html\n\nBOT_NAME = 'douban'\n\nSPIDER_MODULES = ['douban.spiders']\nNEWSPIDER_MODULE = 'douban.spiders'\n\n\n# Crawl responsibly by identifying yourself (and your website) on the user-agent\nUSER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'\n\n# Obey robots.txt rules\nROBOTSTXT_OBEY = True\n\n# Configure maximum concurrent requests performed by Scrapy (default: 16)\n#CONCURRENT_REQUESTS = 32\n\n# Configure a delay for requests for the same website (default: 0)\n# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay\n# See also autothrottle settings and docs\nDOWNLOAD_DELAY = 3\nRANDOMIZE_DOWNLOAD_DELAY = True\n# The download delay setting will honor only one of:\n#CONCURRENT_REQUESTS_PER_DOMAIN = 16\n#CONCURRENT_REQUESTS_PER_IP = 16\n\n# Disable cookies (enabled by default)\nCOOKIES_ENABLED = True\n\nMONGODB_SERVER = '120.77.222.217'\nMONGODB_PORT = 27017\nMONGODB_DB = 'douban'\nMONGODB_COLLECTION = 'movie'\n\n# Disable Telnet Console (enabled by default)\n#TELNETCONSOLE_ENABLED = False\n\n# Override the default request headers:\n#DEFAULT_REQUEST_HEADERS = {\n#   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\n#   'Accept-Language': 'en',\n#}\n\n# Enable or disable spider middlewares\n# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html\n#SPIDER_MIDDLEWARES = {\n#    'douban.middlewares.DoubanSpiderMiddleware': 543,\n#}\n\n# Enable or disable downloader middlewares\n# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html\n#DOWNLOADER_MIDDLEWARES = {\n#    'douban.middlewares.DoubanDownloaderMiddleware': 543,\n#}\n\n# Enable or disable extensions\n# See https://doc.scrapy.org/en/latest/topics/extensions.html\n#EXTENSIONS = {\n#    'scrapy.extensions.telnet.TelnetConsole': None,\n#}\n\n# Configure item pipelines\n# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html\nITEM_PIPELINES = {\n    'douban.pipelines.DoubanPipeline': 400,\n}\n\nLOG_LEVEL = 'DEBUG'\n\n# Enable and configure the AutoThrottle extension (disabled by default)\n# See https://doc.scrapy.org/en/latest/topics/autothrottle.html\n#AUTOTHROTTLE_ENABLED = True\n# The initial download delay\n#AUTOTHROTTLE_START_DELAY = 5\n# The maximum download delay to be set in case of high latencies\n#AUTOTHROTTLE_MAX_DELAY = 60\n# The average number of requests Scrapy should be sending in parallel to\n# each remote server\n#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0\n# Enable showing throttling stats for every response received:\n#AUTOTHROTTLE_DEBUG = False\n\n# Enable and configure HTTP caching (disabled by default)\n# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings\n#HTTPCACHE_ENABLED = True\n#HTTPCACHE_EXPIRATION_SECS = 0\n#HTTPCACHE_DIR = 'httpcache'\n#HTTPCACHE_IGNORE_HTTP_CODES = []\n#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'\n"
  },
  {
    "path": "Day66-75/code/douban/douban/spiders/__init__.py",
    "content": "# This package will contain the spiders of your Scrapy project\n#\n# Please refer to the documentation for information on how to create and manage\n# your spiders.\n"
  },
  {
    "path": "Day66-75/code/douban/douban/spiders/movie.py",
    "content": "# -*- coding: utf-8 -*-\nimport scrapy\nfrom scrapy.selector import Selector\nfrom scrapy.linkextractors import LinkExtractor\nfrom scrapy.spiders import CrawlSpider, Rule\n\nfrom douban.items import DoubanItem\n\n\nclass MovieSpider(CrawlSpider):\n    name = 'movie'\n    allowed_domains = ['movie.douban.com']\n    start_urls = ['https://movie.douban.com/top250']\n    rules = (\n        Rule(LinkExtractor(allow=(r'https://movie.douban.com/top250\\?start=\\d+.*'))),\n        Rule(LinkExtractor(allow=(r'https://movie.douban.com/subject/\\d+')), callback='parse_item'),\n    )\n\n    def parse_item(self, response):\n        sel = Selector(response)\n        item = DoubanItem()\n        item['name']=sel.xpath('//*[@id=\"content\"]/h1/span[1]/text()').extract()\n        item['year']=sel.xpath('//*[@id=\"content\"]/h1/span[2]/text()').re(r'\\((\\d+)\\)')\n        item['score']=sel.xpath('//*[@id=\"interest_sectl\"]/div/p[1]/strong/text()').extract()\n        item['director']=sel.xpath('//*[@id=\"info\"]/span[1]/a/text()').extract()\n        item['classification']= sel.xpath('//span[@property=\"v:genre\"]/text()').extract()\n        item['actor']= sel.xpath('//*[@id=\"info\"]/span[3]/a[1]/text()').extract()\n        #i['domain_id'] = response.xpath('//input[@id=\"sid\"]/@value').extract()\n        #i['name'] = response.xpath('//div[@id=\"name\"]').extract()\n        #i['description'] = response.xpath('//div[@id=\"description\"]').extract()\n        return item\n\n"
  },
  {
    "path": "Day66-75/code/douban/scrapy.cfg",
    "content": "# Automatically created by: scrapy startproject\n#\n# For more information about the [deploy] section see:\n# https://scrapyd.readthedocs.io/en/latest/deploy.html\n\n[settings]\ndefault = douban.settings\n\n[deploy]\n#url = http://localhost:6800/\nproject = douban\n"
  },
  {
    "path": "Day66-75/code/example01.py",
    "content": "from urllib.error import URLError\nfrom urllib.request import urlopen\n\nimport re\nimport pymysql\nimport ssl\n\nfrom pymysql import Error\n\n\n# 通过指定的字符集对页面进行解码(不是每个网站都将字符集设置为utf-8)\ndef decode_page(page_bytes, charsets=('utf-8',)):\n    page_html = None\n    for charset in charsets:\n        try:\n            page_html = page_bytes.decode(charset)\n            break\n        except UnicodeDecodeError:\n            pass\n            # logging.error('Decode:', error)\n    return page_html\n\n\n# 获取页面的HTML代码(通过递归实现指定次数的重试操作)\ndef get_page_html(seed_url, *, retry_times=3, charsets=('utf-8',)):\n    page_html = None\n    try:\n        page_html = decode_page(urlopen(seed_url).read(), charsets)\n    except URLError:\n        # logging.error('URL:', error)\n        if retry_times > 0:\n            return get_page_html(seed_url, retry_times=retry_times - 1,\n                                 charsets=charsets)\n    return page_html\n\n\n# 从页面中提取需要的部分(通常是链接也可以通过正则表达式进行指定)\ndef get_matched_parts(page_html, pattern_str, pattern_ignore_case=re.I):\n    pattern_regex = re.compile(pattern_str, pattern_ignore_case)\n    return pattern_regex.findall(page_html) if page_html else []\n\n\n# 开始执行爬虫程序并对指定的数据进行持久化操作\ndef start_crawl(seed_url, match_pattern, *, max_depth=-1):\n    conn = pymysql.connect(host='localhost', port=3306,\n                           database='crawler', user='root',\n                           password='123456', charset='utf8')\n    try:\n        with conn.cursor() as cursor:\n            url_list = [seed_url]\n            visited_url_list = {seed_url: 0}\n            while url_list:\n                current_url = url_list.pop(0)\n                depth = visited_url_list[current_url]\n                if depth != max_depth:\n                    page_html = get_page_html(current_url, charsets=('utf-8', 'gbk', 'gb2312'))\n                    links_list = get_matched_parts(page_html, match_pattern)\n                    param_list = []\n                    for link in links_list:\n                        if link not in visited_url_list:\n                            visited_url_list[link] = depth + 1\n                            page_html = get_page_html(link, charsets=('utf-8', 'gbk', 'gb2312'))\n                            headings = get_matched_parts(page_html, r'<h1>(.*)<span')\n                            if headings:\n                                param_list.append((headings[0], link))\n                    cursor.executemany('insert into tb_result values (default, %s, %s)',\n                                       param_list)\n                    conn.commit()\n    except Error:\n        pass\n        # logging.error('SQL:', error)\n    finally:\n        conn.close()\n\n\ndef main():\n    ssl._create_default_https_context = ssl._create_unverified_context\n    start_crawl('http://sports.sohu.com/nba_a.shtml',\n                r'<a[^>]+test=a\\s[^>]*href=[\"\\'](.*?)[\"\\']',\n                max_depth=2)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example02.py",
    "content": "from bs4 import BeautifulSoup\n\nimport re\n\n\ndef main():\n    html = \"\"\"\n    <!DOCTYPE html>\n    <html lang=\"en\">\n        <head>\n            <meta charset=\"UTF-8\">\n            <title>首页</title>\n        </head>\n        <body>\n            <h1>Hello, world!</h1>\n            <p>这是一个<em>神奇</em>的网站！</p>\n            <hr>\n            <div>\n                <h2>这是一个例子程序</h2>\n                <p>静夜思</p>\n                <p class=\"foo\">床前明月光</p>\n                <p id=\"bar\">疑似地上霜</p>\n                <p class=\"foo\">举头望明月</p>\n                <div><a href=\"http://www.baidu.com\"><p>低头思故乡</p></a></div>\n            </div>\n            <a class=\"foo\" href=\"http://www.qq.com\">腾讯网</a>\n            <img src=\"./img/pretty-girl.png\" alt=\"美女\">\n            <img src=\"./img/hellokitty.png\" alt=\"凯蒂猫\">\n            <img src=\"/static/img/pretty-girl.png\" alt=\"美女\">\n            <table>\n                <tr>\n                    <th>姓名</th>\n                    <th>上场时间</th>\n                    <th>得分</th>\n                    <th>篮板</th>\n                    <th>助攻</th>\n                </tr>\n            </table>\n        </body>\n    </html>\n    \"\"\"\n    soup = BeautifulSoup(html, 'lxml')\n    # JavaScript - document.title\n    print(soup.title)\n    # JavaScript - document.body.h1\n    print(soup.body.h1)\n    print(soup.p)\n    print(soup.body.p.text)\n    print(soup.body.p.contents)\n    for p_child in soup.body.p.children:\n        print(p_child)\n    print(len([elem for elem in soup.body.children]))\n    print(len([elem for elem in soup.body.descendants]))\n    print(soup.findAll(re.compile(r'^h[1-6]')))\n    print(soup.body.find_all(r'^h'))\n    print(soup.body.div.find_all(re.compile(r'^h')))\n    print(soup.find_all(re.compile(r'r$')))\n    print(soup.find_all('img', {'src': re.compile(r'\\./img/\\w+.png')}))\n    print(soup.find_all(lambda x: len(x.attrs) == 2))\n    print(soup.find_all(foo))\n    print(soup.find_all('p', {'class': 'foo'}))\n    for elem in soup.select('a[href]'):\n        print(elem.attrs['href'])\n\n\ndef foo(elem):\n    return len(elem.attrs) == 2\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example03.py",
    "content": "from bs4 import BeautifulSoup\n\nimport requests\n\nimport re\n\n\ndef main():\n    # 通过requests第三方库的get方法获取页面\n    resp = requests.get('http://sports.sohu.com/nba_a.shtml')\n    # 对响应的字节串(bytes)进行解码操作(搜狐的部分页面使用了GBK编码)\n    html = resp.content.decode('gbk')\n    # 创建BeautifulSoup对象来解析页面(相当于JavaScript的DOM)\n    bs = BeautifulSoup(html, 'lxml')\n    # 通过CSS选择器语法查找元素并通过循环进行处理\n    # for elem in bs.find_all(lambda x: 'test' in x.attrs):\n    for elem in bs.select('a[test]'):\n        # 通过attrs属性(字典)获取元素的属性值\n        link_url = elem.attrs['href']\n        resp = requests.get(link_url)\n        bs_sub = BeautifulSoup(resp.text, 'lxml')\n        # 使用正则表达式对获取的数据做进一步的处理\n        print(re.sub(r'[\\r\\n]', '', bs_sub.find('h1').text))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example04.py",
    "content": "from urllib.parse import urljoin\n\nimport re\nimport requests\n\nfrom bs4 import BeautifulSoup\n\n\ndef main():\n    headers = {'user-agent': 'Baiduspider'}\n    proxies = {\n        'http': 'http://122.114.31.177:808'\n    }\n    base_url = 'https://www.zhihu.com/'\n    seed_url = urljoin(base_url, 'explore')\n    resp = requests.get(seed_url,\n                        headers=headers,\n                        proxies=proxies)\n    soup = BeautifulSoup(resp.text, 'lxml')\n    href_regex = re.compile(r'^/question')\n    link_set = set()\n    for a_tag in soup.find_all('a', {'href': href_regex}):\n        if 'href' in a_tag.attrs:\n            href = a_tag.attrs['href']\n            full_url = urljoin(base_url, href)\n            link_set.add(full_url)\n    print('Total %d question pages found.' % len(link_set))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example05.py",
    "content": "from urllib.error import URLError\nfrom urllib.request import urlopen\n\nimport re\nimport redis\nimport ssl\nimport hashlib\nimport logging\nimport pickle\nimport zlib\n\n# Redis有两种持久化方案\n# 1. RDB\n# 2. AOF\n\n\n# 通过指定的字符集对页面进行解码(不是每个网站都将字符集设置为utf-8)\ndef decode_page(page_bytes, charsets=('utf-8',)):\n    page_html = None\n    for charset in charsets:\n        try:\n            page_html = page_bytes.decode(charset)\n            break\n        except UnicodeDecodeError:\n            pass\n            # logging.error('[Decode]', err)\n    return page_html\n\n\n# 获取页面的HTML代码(通过递归实现指定次数的重试操作)\ndef get_page_html(seed_url, *, retry_times=3, charsets=('utf-8',)):\n    page_html = None\n    try:\n        if seed_url.startswith('http://') or \\\n                seed_url.startswith('https://'):\n            page_html = decode_page(urlopen(seed_url).read(), charsets)\n    except URLError as err:\n        logging.error('[URL]', err)\n        if retry_times > 0:\n            return get_page_html(seed_url, retry_times=retry_times - 1,\n                                 charsets=charsets)\n    return page_html\n\n\n# 从页面中提取需要的部分(通常是链接也可以通过正则表达式进行指定)\ndef get_matched_parts(page_html, pattern_str, pattern_ignore_case=re.I):\n    pattern_regex = re.compile(pattern_str, pattern_ignore_case)\n    return pattern_regex.findall(page_html) if page_html else []\n\n\n# 开始执行爬虫程序\ndef start_crawl(seed_url, match_pattern, *, max_depth=-1):\n    client = redis.Redis(host='1.2.3.4', port=6379, password='1qaz2wsx')\n    charsets = ('utf-8', 'gbk', 'gb2312')\n    logging.info('[Redis ping]', client.ping())\n    url_list = [seed_url]\n    visited_url_list = {seed_url: 0}\n    while url_list:\n        current_url = url_list.pop(0)\n        depth = visited_url_list[current_url]\n        if depth != max_depth:\n            page_html = get_page_html(current_url, charsets=charsets)\n            links_list = get_matched_parts(page_html, match_pattern)\n            for link in links_list:\n                if link not in visited_url_list:\n                    visited_url_list[link] = depth + 1\n                    page_html = get_page_html(link, charsets=charsets)\n                    if page_html:\n                        hasher = hashlib.md5()\n                        hasher.update(link.encode('utf-8'))\n                        zipped_page = zlib.compress(pickle.dumps(page_html))\n                        client.set(hasher.hexdigest(), zipped_page)\n\n\ndef main():\n    ssl._create_default_https_context = ssl._create_unverified_context\n    start_crawl('http://sports.sohu.com/nba_a.shtml',\n                r'<a[^>]+test=a\\s[^>]*href=[\"\\'](.*?)[\"\\']',\n                max_depth=2)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example06.py",
    "content": "\nfrom hashlib import sha1\nfrom urllib.parse import urljoin\n\nimport pickle\nimport re\nimport requests\nimport zlib\n\nfrom bs4 import BeautifulSoup\nfrom redis import Redis\n\n\ndef main():\n    # 指定种子页面\n    base_url = 'https://www.zhihu.com/'\n    seed_url = urljoin(base_url, 'explore')\n    # 创建Redis客户端\n    client = Redis(host='1.2.3.4', port=6379, password='1qaz2wsx')\n    # 设置用户代理(否则访问会被拒绝)\n    headers = {'user-agent': 'Baiduspider'}\n    # 通过requests模块发送GET请求并指定用户代理\n    resp = requests.get(seed_url, headers=headers)\n    # 创建BeautifulSoup对象并指定使用lxml作为解析器\n    soup = BeautifulSoup(resp.text, 'lxml')\n    href_regex = re.compile(r'^/question')\n    # 将URL处理成SHA1摘要(长度固定更简短)\n    hasher_proto = sha1()\n    # 查找所有href属性以/question打头的a标签\n    for a_tag in soup.find_all('a', {'href': href_regex}):\n        # 获取a标签的href属性值并组装完整的URL\n        href = a_tag.attrs['href']\n        full_url = urljoin(base_url, href)\n        # 传入URL生成SHA1摘要\n        hasher = hasher_proto.copy()\n        hasher.update(full_url.encode('utf-8'))\n        field_key = hasher.hexdigest()\n        # 如果Redis的键'zhihu'对应的hash数据类型中没有URL的摘要就访问页面并缓存\n        if not client.hexists('zhihu', field_key):\n            html_page = requests.get(full_url, headers=headers).text\n            # 对页面进行序列化和压缩操作\n            zipped_page = zlib.compress(pickle.dumps(html_page))\n            # 使用hash数据类型保存URL摘要及其对应的页面代码\n            client.hset('zhihu', field_key, zipped_page)\n    # 显示总共缓存了多少个页面\n    print('Total %d question pages found.' % client.hlen('zhihu'))\n\n\nif __name__ == '__main__':\n    main()\n\n"
  },
  {
    "path": "Day66-75/code/example07.py",
    "content": "import pymongo\n\n\n# BSON - Binary JSON - dict\ndef main():\n    # client = pymongo.MongoClient('mongodb://120.77.222.217:27017')\n    client = pymongo.MongoClient(host='120.77.222.217', port=27017)\n    db = client.zhihu\n    pages_cache = db.webpages\n    \"\"\"\n    pages_cache.insert_many([\n        {'_id': 1, 'url': 'http://www.baidu.com', 'content': 'shit'},\n        {'_id': 2, 'url': 'http://www.qq.com', 'content': 'another shit'},\n        {'_id': 3, 'url': 'http://www.qfedu.com', 'content': 'biggest shit'}\n    ])\n    \n    print(pages_cache.update({'_id': 5}, {'$set': {'content': 'hello, world!'}}, upsert=True))\n    # page_id = pages_cache.insert_one({'url': 'http://www.baidu.com', 'content': '<html></html>'})\n    # print(page_id.inserted_id)\n    # print(pages_cache.remove({'url': 'http://www.baidu.com'}))\n    print(pages_cache.find().count())\n    for doc in pages_cache.find().sort('_id'):\n        print(doc)\n    \"\"\"\n    pages_cache.insert_one({\n        'url': 'http://www.baidu.com',\n        'content': 'bull shit!',\n        'owner': {\n            'name': 'Lee Yanhong',\n            'age': 50,\n            'idcard': '110220196804091203'\n        }\n    })\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example08.py",
    "content": "import requests\nfrom bs4 import BeautifulSoup\n\n\ndef main():\n    resp = requests.get('https://github.com/login')\n    if resp.status_code != 200:\n        return\n    cookies = resp.cookies.get_dict()\n    print(cookies)\n    soup = BeautifulSoup(resp.text, 'lxml')\n    utf8_value = \\\n        soup.select_one('form input[name=utf8]').attrs['value']\n    authenticity_token_value = \\\n        soup.select_one('form input[name=authenticity_token]').attrs['value']\n    data = {\n        'utf8': utf8_value,\n        'authenticity_token': authenticity_token_value,\n        'login': 'jackfrued@gmail.com',\n        'password': 'yourpassword'\n    }\n    resp = requests.post('https://github.com/session',\n                         data=data, cookies=cookies)\n    print(resp.text)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example09.py",
    "content": "import robobrowser\n\n\ndef main():\n    b = robobrowser.RoboBrowser(parser='lxml')\n    b.open('https://github.com/login')\n    f = b.get_form(action='/session')\n    f['login'].value = 'jackfrued@gmail.com'\n    f['password'].value = 'yourpassword'\n    b.submit_form(f)\n    for a_tag in b.select('a[href]'):\n        print(a_tag.attrs['href'])\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example10.py",
    "content": "import robobrowser\n\n\ndef main():\n    b = robobrowser.RoboBrowser(parser='lxml')\n    b.open('https://v.taobao.com/v/content/live?catetype=704&from=taonvlang')\n    for img_tag in b.select('img[src]'):\n        print(img_tag.attrs['src'])\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example11.py",
    "content": "from bs4 import BeautifulSoup\nfrom selenium import webdriver\nfrom selenium.webdriver.common.keys import Keys\n\n\ndef main():\n    driver = webdriver.Chrome()\n    driver.get('https://v.taobao.com/v/content/live?catetype=704&from=taonvlang')\n    elem = driver.find_element_by_css_selector('input[placeholder=输入关键词搜索]')\n    elem.send_keys('运动')\n    elem.send_keys(Keys.ENTER)\n    soup = BeautifulSoup(driver.page_source, 'lxml')\n    for img_tag in soup.body.select('img[src]'):\n        print(img_tag.attrs['src'])\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/example12.py",
    "content": "import base64\n\nfrom PIL import Image, ImageFilter\nfrom pytesseract import image_to_string\n\nimport requests\nfrom io import BytesIO\n\n\ndef main():\n    guido_img = Image.open(open('guido.jpg', 'rb'))\n    guido2_img = guido_img.filter(ImageFilter.GaussianBlur)\n    guido2_img.save(open('guido2.jpg', 'wb'))\n\n    img1 = Image.open(open('tesseract.png', 'rb'))\n    img2 = img1.point(lambda x: 0 if x < 128 else 255)\n    img2.save(open('tesseract2.png', 'wb'))\n\n    print(image_to_string(img2))\n\n    resp = requests.get('https://pin2.aliyun.com/get_img?type=150_40&identity=mailsso.mxhichina.com&sessionid=k0xHyBxU3K3dGXb59mP9cdeTXxL9gLHSTKhRZCryHxpOoyk4lAVuJhgw==')\n    img3 = Image.open(BytesIO(resp.content))\n    img3.save('captcha.jpg')\n    print(image_to_string(img3))\n    print(base64.b64encode(resp.content))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/generator01.py",
    "content": "def fib():\n    a, b = 0, 1\n    while True:\n        a, b = b, a + b\n        yield a\n\n\ndef even(gen):\n    for val in gen:\n        if val % 2 == 0:\n            yield val\n\n\ndef main():\n    gen = even(fib())\n    for _ in range(10):\n        print(next(gen))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/generator02.py",
    "content": "from time import sleep\n\n\ndef countdown(n):\n    while n > 0:\n        yield n\n        n -= 1\n\n\ndef main():\n    for num in countdown(5):\n        print(f'Countdown: {num}')\n        sleep(1)\n    print('Countdown Over!')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/image360/image360/__init__.py",
    "content": ""
  },
  {
    "path": "Day66-75/code/image360/image360/items.py",
    "content": "# -*- coding: utf-8 -*-\n\n# Define here the models for your scraped items\n#\n# See documentation in:\n# https://doc.scrapy.org/en/latest/topics/items.html\n\nimport scrapy\n\n\nclass GoodsItem(scrapy.Item):\n\n    price = scrapy.Field()\n    deal = scrapy.Field()\n    title = scrapy.Field()\n\n\nclass BeautyItem(scrapy.Item):\n\n    title = scrapy.Field()\n    tag = scrapy.Field()\n    width = scrapy.Field()\n    height = scrapy.Field()\n    url = scrapy.Field()\n"
  },
  {
    "path": "Day66-75/code/image360/image360/middlewares.py",
    "content": "# -*- coding: utf-8 -*-\n\n# Define here the models for your spider middleware\n#\n# See documentation in:\n# https://doc.scrapy.org/en/latest/topics/spider-middleware.html\n\nfrom scrapy import signals\nfrom scrapy.http import HtmlResponse\n\nfrom selenium import webdriver\nfrom selenium.common.exceptions import TimeoutException\n\n\nclass Image360SpiderMiddleware(object):\n    # Not all methods need to be defined. If a method is not defined,\n    # scrapy acts as if the spider middleware does not modify the\n    # passed objects.\n\n    @classmethod\n    def from_crawler(cls, crawler):\n        # This method is used by Scrapy to create your spiders.\n        s = cls()\n        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)\n        return s\n\n    def process_spider_input(self, response, spider):\n        # Called for each response that goes through the spider\n        # middleware and into the spider.\n\n        # Should return None or raise an exception.\n        return None\n\n    def process_spider_output(self, response, result, spider):\n        # Called with the results returned from the Spider, after\n        # it has processed the response.\n\n        # Must return an iterable of Request, dict or Item objects.\n        for i in result:\n            yield i\n\n    def process_spider_exception(self, response, exception, spider):\n        # Called when a spider or process_spider_input() method\n        # (from other spider middleware) raises an exception.\n\n        # Should return either None or an iterable of Response, dict\n        # or Item objects.\n        pass\n\n    def process_start_requests(self, start_requests, spider):\n        # Called with the start requests of the spider, and works\n        # similarly to the process_spider_output() method, except\n        # that it doesn’t have a response associated.\n\n        # Must return only requests (not items).\n        for r in start_requests:\n            yield r\n\n    def spider_opened(self, spider):\n        spider.logger.info('Spider opened: %s' % spider.name)\n\n\nclass Image360DownloaderMiddleware(object):\n    # Not all methods need to be defined. If a method is not defined,\n    # scrapy acts as if the downloader middleware does not modify the\n    # passed objects.\n\n    @classmethod\n    def from_crawler(cls, crawler):\n        # This method is used by Scrapy to create your spiders.\n        s = cls()\n        crawler.signals.connect(s.spider_opened, signal=signals.spider_opened)\n        return s\n\n    def process_request(self, request, spider):\n        # Called for each request that goes through the downloader\n        # middleware.\n\n        # Must either:\n        # - return None: continue processing this request\n        # - or return a Response object\n        # - or return a Request object\n        # - or raise IgnoreRequest: process_exception() methods of\n        #   installed downloader middleware will be called\n        return None\n\n    def process_response(self, request, response, spider):\n        # Called with the response returned from the downloader.\n\n        # Must either;\n        # - return a Response object\n        # - return a Request object\n        # - or raise IgnoreRequest\n        return response\n\n    def process_exception(self, request, exception, spider):\n        # Called when a download handler or a process_request()\n        # (from other downloader middleware) raises an exception.\n\n        # Must either:\n        # - return None: continue processing this exception\n        # - return a Response object: stops process_exception() chain\n        # - return a Request object: stops process_exception() chain\n        pass\n\n    def spider_opened(self, spider):\n        spider.logger.info('Spider opened: %s' % spider.name)\n\n\nclass TaobaoDownloaderMiddleWare(object):\n\n    def __init__(self, timeout=None):\n        self.timeout = timeout\n        self.browser = webdriver.Chrome()\n        self.browser.set_window_size(1000, 600)\n        self.browser.set_page_load_timeout(self.timeout)\n\n    def __del__(self):\n        self.browser.close()\n\n    def process_request(self, request, spider):\n        try:\n            self.browser.get(request.url)\n            return HtmlResponse(url=request.url, body=self.browser.page_source,\n                                request=request, encoding='utf-8', status=200)\n        except TimeoutException:\n            return HtmlResponse(url=request.url, status=500, request=request)\n\n    def process_response(self, request, response, spider):\n        return response\n\n    def process_exception(self, request, exception, spider):\n        pass\n\n    @classmethod\n    def from_crawler(cls, crawler):\n        return cls(timeout=10)\n"
  },
  {
    "path": "Day66-75/code/image360/image360/pipelines.py",
    "content": "# -*- coding: utf-8 -*-\n\n# Define your item pipelines here\n#\n# Don't forget to add your pipeline to the ITEM_PIPELINES setting\n# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html\nimport logging\n\nfrom pymongo import MongoClient\nfrom scrapy import Request\nfrom scrapy.exceptions import DropItem\nfrom scrapy.pipelines.images import ImagesPipeline\n\n\nlogger = logging.getLogger('SaveImagePipeline')\n\n\nclass SaveImagePipeline(ImagesPipeline):\n\n    def get_media_requests(self, item, info):\n        yield Request(url=item['url'])\n\n    def item_completed(self, results, item, info):\n        logger.debug('图片下载完成!')\n        if not results[0][0]:\n            raise DropItem('下载失败')\n        return item\n\n    def file_path(self, request, response=None, info=None):\n        return request.url.split('/')[-1]\n\n\nclass SaveToMongoPipeline(object):\n\n    def __init__(self, mongo_url, db_name):\n        self.mongo_url = mongo_url\n        self.db_name = db_name\n        self.client = None\n        self.db = None\n\n    def process_item(self, item, spider):\n        return item\n\n    def open_spider(self, spider):\n        self.client = MongoClient(self.mongo_url)\n        self.db = self.client[self.db_name]\n\n    def close_spider(self, spider):\n        self.client.close()\n\n    @classmethod\n    def from_crawler(cls, crawler):\n        return cls(crawler.settings.get('MONGO_URL'),\n                   crawler.settings.get('MONGO_DB'))\n\n"
  },
  {
    "path": "Day66-75/code/image360/image360/settings.py",
    "content": "# -*- coding: utf-8 -*-\n\n# Scrapy settings for image360 project\n#\n# For simplicity, this file contains only settings considered important or\n# commonly used. You can find more settings consulting the documentation:\n#\n#     https://doc.scrapy.org/en/latest/topics/settings.html\n#     https://doc.scrapy.org/en/latest/topics/downloader-middleware.html\n#     https://doc.scrapy.org/en/latest/topics/spider-middleware.html\n\nBOT_NAME = 'image360'\n\nSPIDER_MODULES = ['image360.spiders']\nNEWSPIDER_MODULE = 'image360.spiders'\n\nMONGO_URL = 'mongodb://120.77.222.217:27017'\nMONGO_DB = 'image360'\n\n\n# Crawl responsibly by identifying yourself (and your website) on the user-agent\nUSER_AGENT = 'Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19'\n\n# Obey robots.txt rules\nROBOTSTXT_OBEY = False\n\n# Configure maximum concurrent requests performed by Scrapy (default: 16)\nCONCURRENT_REQUESTS = 2\n\n# Configure a delay for requests for the same website (default: 0)\n# See https://doc.scrapy.org/en/latest/topics/settings.html#download-delay\n# See also autothrottle settings and docs\nDOWNLOAD_DELAY = 3\nRANDOMIZE_DOWNLOAD_DELAY = True\n# The download delay setting will honor only one of:\n#CONCURRENT_REQUESTS_PER_DOMAIN = 16\n#CONCURRENT_REQUESTS_PER_IP = 16\n\n# Disable cookies (enabled by default)\n#COOKIES_ENABLED = False\n\n# Disable Telnet Console (enabled by default)\n#TELNETCONSOLE_ENABLED = False\n\n# Override the default request headers:\n#DEFAULT_REQUEST_HEADERS = {\n#   'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',\n#   'Accept-Language': 'en',\n#}\n\n# Enable or disable spider middlewares\n# See https://doc.scrapy.org/en/latest/topics/spider-middleware.html\n#SPIDER_MIDDLEWARES = {\n#    'image360.middlewares.Image360SpiderMiddleware': 543,\n#}\n\n# Enable or disable downloader middlewares\n# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html\nDOWNLOADER_MIDDLEWARES = {\n    # 'image360.middlewares.Image360DownloaderMiddleware': 543,\n    'image360.middlewares.TaobaoDownloaderMiddleWare': 500,\n}\n\n# Enable or disable extensions\n# See https://doc.scrapy.org/en/latest/topics/extensions.html\n#EXTENSIONS = {\n#    'scrapy.extensions.telnet.TelnetConsole': None,\n#}\n\nIMAGES_STORE = './resources/'\n\n# Configure item pipelines\n# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html\n# ITEM_PIPELINES = {\n#     'image360.pipelines.SaveImagePipeline': 300,\n#     'image360.pipelines.SaveToMongoPipeline': 301,\n# }\n\nLOG_LEVEL = 'DEBUG'\n\n# Enable and configure the AutoThrottle extension (disabled by default)\n# See https://doc.scrapy.org/en/latest/topics/autothrottle.html\n#AUTOTHROTTLE_ENABLED = True\n# The initial download delay\n#AUTOTHROTTLE_START_DELAY = 5\n# The maximum download delay to be set in case of high latencies\n#AUTOTHROTTLE_MAX_DELAY = 60\n# The average number of requests Scrapy should be sending in parallel to\n# each remote server\n#AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0\n# Enable showing throttling stats for every response received:\n#AUTOTHROTTLE_DEBUG = False\n\n# Enable and configure HTTP caching (disabled by default)\n# See https://doc.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings\n#HTTPCACHE_ENABLED = True\n#HTTPCACHE_EXPIRATION_SECS = 0\n#HTTPCACHE_DIR = 'httpcache'\n#HTTPCACHE_IGNORE_HTTP_CODES = []\n#HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'\n"
  },
  {
    "path": "Day66-75/code/image360/image360/spiders/__init__.py",
    "content": "# This package will contain the spiders of your Scrapy project\n#\n# Please refer to the documentation for information on how to create and manage\n# your spiders.\n"
  },
  {
    "path": "Day66-75/code/image360/image360/spiders/image.py",
    "content": "# -*- coding: utf-8 -*-\nfrom json import loads\nfrom urllib.parse import urlencode\n\nimport scrapy\n\nfrom image360.items import BeautyItem\n\n\nclass ImageSpider(scrapy.Spider):\n    name = 'image'\n    allowed_domains = ['image.so.com']\n\n    def start_requests(self):\n        base_url = 'http://image.so.com/zj?'\n        param = {'ch': 'beauty', 'listtype': 'new', 'temp': 1}\n        for page in range(10):\n            param['sn'] = page * 30\n            full_url = base_url + urlencode(param)\n            yield scrapy.Request(url=full_url)\n\n    def parse(self, response):\n        model_dict = loads(response.text)\n        for elem in model_dict['list']:\n            item = BeautyItem()\n            item['title'] = elem['group_title']\n            item['tag'] = elem['tag']\n            item['width'] = elem['cover_width']\n            item['height'] = elem['cover_height']\n            item['url'] = elem['qhimg_url']\n            yield item\n"
  },
  {
    "path": "Day66-75/code/image360/image360/spiders/taobao.py",
    "content": "# -*- coding: utf-8 -*-\nfrom io import StringIO\nfrom urllib.parse import urlencode\nimport re\n\nimport scrapy\n\nfrom image360.items import GoodsItem\n\n\nclass TaobaoSpider(scrapy.Spider):\n    name = 'taobao'\n    allowed_domains = ['www.taobao.com']\n\n    def start_requests(self):\n        base_url = 'https://s.taobao.com/search?'\n        params = {}\n        for keyword in ['ipad', 'iphone', '小米手机']:\n            params['q'] = keyword\n            for page in range(10):\n                params['s'] = page * 44\n                full_url = base_url + urlencode(params)\n                yield scrapy.Request(url=full_url, callback=self.parse)\n\n    def parse(self, response):\n        goods_list = response.xpath('//*[@id=\"mainsrp-itemlist\"]/div/div/div[1]')\n        for goods in goods_list:\n            item = GoodsItem()\n            item['price'] = goods.xpath('div[5]/div[2]/div[1]/div[1]/strong/text()').extract_first()\n            item['deal'] = goods.xpath('div[5]/div[2]/div[1]/div[2]/text()').extract_first()\n            segments = goods.xpath('div[6]/div[2]/div[2]/a/text()').extract()\n            title = StringIO()\n            for segment in segments:\n                title.write(re.sub('\\s', '', segment))\n            item['title'] = title.getvalue()\n            yield item\n"
  },
  {
    "path": "Day66-75/code/image360/scrapy.cfg",
    "content": "# Automatically created by: scrapy startproject\n#\n# For more information about the [deploy] section see:\n# https://scrapyd.readthedocs.io/en/latest/deploy.html\n\n[settings]\ndefault = image360.settings\n\n[deploy]\n#url = http://localhost:6800/\nproject = image360\n"
  },
  {
    "path": "Day66-75/code/main.py",
    "content": "from enum import Enum, unique\nfrom queue import Queue\nfrom random import random\nfrom threading import Thread, current_thread\nfrom time import sleep\nfrom urllib.parse import urlparse\n\nimport requests\nfrom bs4 import BeautifulSoup\n\n\n@unique\nclass SpiderStatus(Enum):\n    IDLE = 0\n    WORKING = 1\n\n\ndef decode_page(page_bytes, charsets=('utf-8',)):\n    page_html = None\n    for charset in charsets:\n        try:\n            page_html = page_bytes.decode(charset)\n            break\n        except UnicodeDecodeError:\n            pass\n    return page_html\n\n\nclass Retry(object):\n\n    def __init__(self, *, retry_times=3,\n                 wait_secs=5, errors=(Exception, )):\n        self.retry_times = retry_times\n        self.wait_secs = wait_secs\n        self.errors = errors\n\n    def __call__(self, fn):\n\n        def wrapper(*args, **kwargs):\n            for _ in range(self.retry_times):\n                try:\n                    return fn(*args, **kwargs)\n                except self.errors as e:\n                    print(e)\n                    sleep((random() + 1) * self.wait_secs)\n            return None\n\n        return wrapper\n\n\nclass Spider(object):\n\n    def __init__(self):\n        self.status = SpiderStatus.IDLE\n\n    @Retry()\n    def fetch(self, current_url, *, charsets=('utf-8', ),\n              user_agent=None, proxies=None):\n        thread_name = current_thread().name\n        print(f'[{thread_name}]: {current_url}')\n        headers = {'user-agent': user_agent} if user_agent else {}\n        resp = requests.get(current_url,\n                            headers=headers, proxies=proxies)\n        return decode_page(resp.content, charsets) \\\n            if resp.status_code == 200 else None\n\n    def parse(self, html_page, *, domain='m.sohu.com'):\n        soup = BeautifulSoup(html_page, 'lxml')\n        url_links = []\n        for a_tag in soup.body.select('a[href]'):\n            parser = urlparse(a_tag.attrs['href'])\n            scheme = parser.scheme or 'http'\n            netloc = parser.netloc or domain\n            if scheme != 'javascript' and netloc == domain:\n                path = parser.path\n                query = '?' + parser.query if parser.query else ''\n                full_url = f'{scheme}://{netloc}{path}{query}'\n                if full_url not in visited_urls:\n                    url_links.append(full_url)\n        return url_links\n\n    def extract(self, html_page):\n        pass\n\n    def store(self, data_dict):\n        pass\n\n\nclass SpiderThread(Thread):\n\n    def __init__(self, name, spider, tasks_queue):\n        super().__init__(name=name, daemon=True)\n        self.spider = spider\n        self.tasks_queue = tasks_queue\n\n    def run(self):\n        while True:\n            current_url = self.tasks_queue.get()\n            visited_urls.add(current_url)\n            self.spider.status = SpiderStatus.WORKING\n            html_page = self.spider.fetch(current_url)\n            if html_page not in [None, '']:\n                url_links = self.spider.parse(html_page)\n                for url_link in url_links:\n                    self.tasks_queue.put(url_link)\n            self.spider.status = SpiderStatus.IDLE\n\n\ndef is_any_alive(spider_threads):\n    return any([spider_thread.spider.status == SpiderStatus.WORKING\n                for spider_thread in spider_threads])\n\n\nvisited_urls = set()\n\n\ndef main():\n    task_queue = Queue()\n    task_queue.put('http://m.sohu.com/')\n    spider_threads = [SpiderThread('thread-%d' % i, Spider(), task_queue)\n                      for i in range(10)]\n    for spider_thread in spider_threads:\n        spider_thread.start()\n\n    while not task_queue.empty() or is_any_alive(spider_threads):\n    \tsleep(5)\n\n    print('Over!')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/main_redis.py",
    "content": "import pickle\nimport zlib\nfrom enum import Enum, unique\nfrom hashlib import sha1\nfrom random import random\nfrom threading import Thread, current_thread, local\nfrom time import sleep\nfrom urllib.parse import urlparse\n\nimport pymongo\nimport redis\nimport requests\nfrom bs4 import BeautifulSoup\nfrom bson import Binary\n\n\n@unique\nclass SpiderStatus(Enum):\n    IDLE = 0\n    WORKING = 1\n\n\ndef decode_page(page_bytes, charsets=('utf-8',)):\n    page_html = None\n    for charset in charsets:\n        try:\n            page_html = page_bytes.decode(charset)\n            break\n        except UnicodeDecodeError:\n            pass\n    return page_html\n\n\nclass Retry(object):\n\n    def __init__(self, *, retry_times=3,\n                 wait_secs=5, errors=(Exception, )):\n        self.retry_times = retry_times\n        self.wait_secs = wait_secs\n        self.errors = errors\n\n    def __call__(self, fn):\n\n        def wrapper(*args, **kwargs):\n            for _ in range(self.retry_times):\n                try:\n                    return fn(*args, **kwargs)\n                except self.errors as e:\n                    print(e)\n                    sleep((random() + 1) * self.wait_secs)\n            return None\n\n        return wrapper\n\n\nclass Spider(object):\n\n    def __init__(self):\n        self.status = SpiderStatus.IDLE\n\n    @Retry()\n    def fetch(self, current_url, *, charsets=('utf-8', ),\n              user_agent=None, proxies=None):\n        thread_name = current_thread().name\n        print(f'[{thread_name}]: {current_url}')\n        headers = {'user-agent': user_agent} if user_agent else {}\n        resp = requests.get(current_url,\n                            headers=headers, proxies=proxies)\n        return decode_page(resp.content, charsets) \\\n            if resp.status_code == 200 else None\n\n    def parse(self, html_page, *, domain='m.sohu.com'):\n        soup = BeautifulSoup(html_page, 'lxml')\n        for a_tag in soup.body.select('a[href]'):\n            parser = urlparse(a_tag.attrs['href'])\n            scheme = parser.scheme or 'http'\n            netloc = parser.netloc or domain\n            if scheme != 'javascript' and netloc == domain:\n                path = parser.path\n                query = '?' + parser.query if parser.query else ''\n                full_url = f'{scheme}://{netloc}{path}{query}'\n                redis_client = thread_local.redis_client\n                if not redis_client.sismember('visited_urls', full_url):\n                    redis_client.rpush('m_sohu_task', full_url)\n\n    def extract(self, html_page):\n        pass\n\n    def store(self, data_dict):\n        # redis_client = thread_local.redis_client\n        # mongo_db = thread_local.mongo_db\n        pass\n\n\nclass SpiderThread(Thread):\n\n    def __init__(self, name, spider):\n        super().__init__(name=name, daemon=True)\n        self.spider = spider\n\n    def run(self):\n        redis_client = redis.Redis(host='1.2.3.4', port=6379, password='1qaz2wsx')\n        mongo_client = pymongo.MongoClient(host='1.2.3.4', port=27017)\n        thread_local.redis_client = redis_client\n        thread_local.mongo_db = mongo_client.msohu \n        while True:\n            current_url = redis_client.lpop('m_sohu_task')\n            while not current_url:\n                current_url = redis_client.lpop('m_sohu_task')\n            self.spider.status = SpiderStatus.WORKING\n            current_url = current_url.decode('utf-8')\n            if not redis_client.sismember('visited_urls', current_url):\n                redis_client.sadd('visited_urls', current_url)\n                html_page = self.spider.fetch(current_url)\n                if html_page not in [None, '']:\n                    hasher = hasher_proto.copy()\n                    hasher.update(current_url.encode('utf-8'))\n                    doc_id = hasher.hexdigest()\n                    sohu_data_coll = mongo_client.msohu.webpages\n                    if not sohu_data_coll.find_one({'_id': doc_id}):\n                        sohu_data_coll.insert_one({\n                            '_id': doc_id,\n                            'url': current_url,\n                            'page': Binary(zlib.compress(pickle.dumps(html_page)))\n                        })\n                    self.spider.parse(html_page)\n            self.spider.status = SpiderStatus.IDLE\n\n\ndef is_any_alive(spider_threads):\n    return any([spider_thread.spider.status == SpiderStatus.WORKING\n                for spider_thread in spider_threads])\n\n\nthread_local = local()\nhasher_proto = sha1()\n\n\ndef main():\n    redis_client = redis.Redis(host='1.2.3.4', port=6379, password='1qaz2wsx')\n    if not redis_client.exists('m_sohu_task'):\n        redis_client.rpush('m_sohu_task', 'http://m.sohu.com/')\n\n    spider_threads = [SpiderThread('thread-%d' % i, Spider())\n                      for i in range(10)]\n    for spider_thread in spider_threads:\n        spider_thread.start()\n\n    while redis_client.exists('m_sohu_task') or is_any_alive(spider_threads):\n        pass\n\n    print('Over!')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "Day66-75/code/myutils.py",
    "content": "from functools import wraps\n\n\ndef coroutine(fn):\n\n    @wraps(fn)\n    def wrapper(*args, **kwargs):\n        gen = fn(*args, **kwargs)\n        next(gen)\n        return gen\n\n    return wrapper\n"
  },
  {
    "path": "Day76-90/数据处理和可视化.md",
    "content": ""
  },
  {
    "path": "Day76-90/机器学习.md",
    "content": ""
  },
  {
    "path": "Day91-100/团队项目开发.md",
    "content": ""
  },
  {
    "path": "PEP 8风格指南.md",
    "content": "## PEP 8风格指南\n\nPEP是Python Enhancement Proposal的缩写，通常翻译为“Python增强提案”。每个PEP都是一份为Python社区提供的指导Python往更好的方向发展的技术文档，其中的第8号增提案即PEP 8是针对Python语言编订的代码风格指南。尽管我们可以在保证语法没有问题的前提下随意书写Python代码，但是在实际开发中，采用一致的风格书写出可读性强的代码是每个专业的程序员应该做到的事情，也是每个公司的编程规范中会提出的要求，这些在多人协作开发一个项目（团队开发）的时候显得尤为重要。我们可以从Python官方网站的[PEP 8链接](https://www.python.org/dev/peps/pep-0008/)中找到该文档，下面我们对该文档的关键部分做一个简单的总结。\n\n### 空格的使用\n\n1. **使用空格来表示缩进而不要用制表符（Tab）**。这一点对习惯了其他编程语言的人来说简直觉得不可理喻，因为绝大多数的程序员都会用Tab来表示缩进，但是要知道Python并没有像C/C++或Java那样的用花括号来构造一个代码块的语法，在Python中分支和循环结构都使用缩进来表示哪些代码属于同一个级别，鉴于此Python代码对缩进以及缩进宽度的依赖比其他很多语言都强得多。在不同的编辑器中，Tab的宽度可能是2、4或8个字符，甚至是其他更离谱的值，用Tab来表示缩进对Python代码来说可能是一场灾难。\n2. **和语法相关的每一层缩进都用4个空格来表示。**\n3. **每行的字符数不要超过79个字符，如果表达式因太长而占据了多行，除了首行之外的其余各行都应该在正常的缩进宽度上再加上4个空格。**\n4. **函数和类的定义，代码前后都要用两个空行进行分隔。**\n5. **在同一个类中，各个方法之间应该用一个空行进行分隔。**\n6. **二元运算符的左右两侧应该保留一个空格，而且只要一个空格就好。**\n\n### 标识符命名\n\nPEP 8倡导用不同的命名风格来命名Python中不同的标识符，以便在阅读代码时能够通过标识符的名称来确定该标识符在Python中扮演了怎样的角色（在这一点上，Python自己的内置模块以及某些第三方模块都做得并不是很好）。\n\n1. **变量、函数和属性应该使用小写字母来拼写，如果有多个单词就使用下划线进行连接。**\n2. **类中受保护的实例属性，应该以一个下划线开头。**\n3. **类中私有的实例属性，应该以两个下划线开头。**\n4. **类和异常的命名，应该每个单词首字母大写。**\n5. **模块级别的常量，应该采用全大写字母，如果有多个单词就用下划线进行连接。**\n6. **类的实例方法，应该把第一个参数命名为`self`以表示对象自身。**\n7. **类的类方法，应该把第一个参数命名为`cls`以表示该类自身。**\n\n### 表达式和语句\n\n在Python之禅（可以使用`import this`查看）中有这么一句名言：“There should be one-- and preferably only one --obvious way to do it.”，翻译成中文是“做一件事应该有而且最好只有一种确切的做法”，这句话传达的思想在PEP 8中也是无处不在的。\n\n1. **采用内联形式的否定词，而不要把否定词放在整个表达式的前面。**例如`if a is not b`就比`if not a is b`更容易让人理解。\n2. **不要用检查长度的方式来判断字符串、列表等是否为`None`或者没有元素，应该用`if not x`这样的写法来检查它。**\n3. **就算`if`分支、`for`循环、`except`异常捕获等中只有一行代码，也不要将代码和`if`、`for`、`except`等写在一起，分开写才会让代码更清晰。**\n4. **`import`语句总是放在文件开头的地方**。\n5. **引入模块的时候，`from math import sqrt`比`import math`更好。**\n6. **如果有多个`import`语句，应该将其分为三部分，从上到下分别是Python标准模块、第三方模块和自定义模块，每个部分内部应该按照模块名称的字母表顺序来排列。**\n\n"
  },
  {
    "path": "Python参考书籍.md",
    "content": "## Python参考书籍\n\n### 入门读物\n\n1. 《Python基础教程》（*Beginning Python From Novice to Professional*）\n2. 《Python学习手册》（*Learning Python*）\n3. 《Python编程》（*Programming Python*）\n4. 《Python Cookbook》\n5. 《Python程序设计》（*Python Programming: An Introduction to Computer Science*）\n6. 《Modern Python Cookbook》\n\n### 进阶读物\n\n1. 《Python核心编程》（*Core Python Applications Programming*）\n2. 《流畅的Python》（*Fluent Python*）\n3. 《Effective Python：编写高质量Python代码的59个有效方法》（*Effective Python 59 Specific Ways to Write Better Python*）\n4. 《Python设计模式》（*Learning Python Design Patterns*）\n5. 《Python高级编程》（*Expert Python Programming*）\n6. 《Python性能分析与优化》（*Mastering Python High Performance*）\n\n### Web框架\n\n1. 《Django基础教程》（*Tango with Django*）\n2. 《轻量级Django》（*Lightweight Django*）\n3. 《Python Web开发：测试驱动方法》（*Test-Driven Development with Python*）\n4. 《Web Development with Django Cookbook》\n5. 《Test-Driven Development with Django》\n6. 《Django Project Blueprints 》\n7. 《Flask Web开发：基于Python的Web应用开发实战》（*Flask Web Development: Developing Web Applications with Python*）\n8. 《深入理解Flask》（*Mastering Flask*）\n\n### 爬虫开发\n\n1. 《用Python写网络爬虫》（*Web Scraping with Python*）\n2. 《精通Python爬虫框架Scrapy》（*Learning Scrapy*）\n3. 《Python网络数据采集》（*Web Scraping with Python*）\n4. 《Python爬虫开发与项目实战》\n5. 《Python 3网络爬虫开发实战》\n\n### 数据分析\n\n1. 《利用Python进行数据分析》（*Python for Data Analysis*）\n2. 《Python数据科学手册》（*Python Data Science Handbook*）\n3. 《Python金融大数据分析》（*Python for Finance*）\n4. 《Python数据可视化编程实战》（*Python Data Visualization Cookbook*）\n5. 《Python数据处理》（*Data Wrangling with Python*）\n\n### 机器学习\n\n1. 《Python机器学习基础教程》（*Introduction to Machine Learning with Python*）\n2. 《Python机器学习实践指南》（*Python Machine Learning Blueprints*）\n3. 《Python Machine Learning Case Studies》\n4. 《Python机器学习实践：测试驱动的开发方法》（*Thoughtful Machine Learning with Python A Test Driven Approach*）\n5. 《Python机器学习经典实例》（*Python Machine Learning Cookbook*）\n6. 《TensorFlow：实战Google深度学习框架》"
  },
  {
    "path": "Python惯例.md",
    "content": "## Python惯例\n\n“惯例”这个词指的是“习惯的做法，常规的办法，一贯的做法”，与这个词对应的英文单词叫“idiom”。由于Python跟其他很多编程语言在语法和使用上还是有比较显著的差别，因此作为一个Python开发者如果不能掌握这些惯例，就无法写出“Pythonic”的代码。下面我们总结了一些在Python开发中的惯用的代码。\n\n1. 让代码既可以被导入又可以被执行。\n\n   ```Python\n   if __name__ == '__main__':\n   ```\n\n\n2. 用下面的方式判断逻辑“真”或“假”。\n\n   ```Python\n   if x:\n   if not x:\n   ```\n\n   **好**的代码：\n\n   ```Python\n   name = 'jackfrued'\n   fruits = ['apple', 'orange', 'grape']\n   owners = {'1001': '骆昊', '1002': '王大锤'}\n   if name and fruits and owners:\n       print('I love fruits!')\n   ```\n\n   **不好**的代码：\n\n   ```Python\n   name = 'jackfrued'\n   fruits = ['apple', 'orange', 'grape']\n   owners = {'1001': '骆昊', '1002': '王大锤'}\n   if name != '' and len(fruits) > 0 and owners != {}:\n       print('I love fruits!')\n   ```\n\n3. 善于使用in运算符。\n\n   ```Python\n   if x in items: # 包含\n   for x in items: # 迭代\n   ```\n\n   **好**的代码：\n\n   ```Python\n   name = 'Hao LUO'\n   if 'L' in name:\n       print('The name has an L in it.')\n   ```\n\n   **不好**的代码：\n\n   ```Python\n   name = 'Hao LUO'\n   if name.find('L') != -1:\n       print('This name has an L in it!')\n   ```\n\n4. 不使用临时变量交换两个值。\n\n   ```Python\n   a, b = b, a\n   ```\n\n5. 用序列构建字符串。\n\n   **好**的代码：\n\n   ```Python\n   chars = ['j', 'a', 'c', 'k', 'f', 'r', 'u', 'e', 'd']\n   name = ''.join(chars)\n   print(name)  # jackfrued\n   ```\n\n   **不好**的代码：\n\n   ```Python\n   chars = ['j', 'a', 'c', 'k', 'f', 'r', 'u', 'e', 'd']\n   name = ''\n   for char in chars:\n       name += char\n   print(name)  # jackfrued\n   ```\n\n6. EAFP优于LBYL。\n\n   EAFP - **E**asier to **A**sk **F**orgiveness than **P**ermission.\n\n   LBYL - **L**ook **B**efore **Y**ou **L**eap.\n\n   **好**的代码：\n\n   ```Python\n   d = {'x': '5'}\n   try:\n       value = int(d['x'])\n       print(value)\n   except (KeyError, TypeError, ValueError):\n       value = None\n   ```\n\n   **不好**的代码：\n\n   ```Python\n   d = {'x': '5'}\n   if 'x' in d and isinstance(d['x'], str) \\\n   \t\tand d['x'].isdigit():\n       value = int(d['x'])\n       print(value)\n   else:\n       value = None\n   ```\n\n7. 使用enumerate进行迭代。\n\n   **好**的代码：\n\n   ```Python\n   fruits = ['orange', 'grape', 'pitaya', 'blueberry']\n   for index, fruit in enumerate(fruits):\n   \tprint(index, ':', fruit)\n   ```\n\n   **不好**的代码：\n\n   ```Python\n   fruits = ['orange', 'grape', 'pitaya', 'blueberry']\n   index = 0\n   for fruit in fruits:\n       print(index, ':', fruit)\n       index += 1\n   ```\n\n8. 用生成式生成列表。\n\n   **好**的代码：\n\n   ```Python\n   data = [7, 20, 3, 15, 11]\n   result = [num * 3 for num in data if num > 10]\n   print(result)  # [60, 45, 33]\n   ```\n\n   **不好**的代码：\n\n   ```Python\n   data = [7, 20, 3, 15, 11]\n   result = []\n   for i in data:\n       if i > 10:\n           result.append(i * 3)\n   print(result)  # [60, 45, 33]\n   ```\n\n9. 用zip组合键和值来创建字典。\n\n   **好**的代码：\n\n   ```Python\n   keys = ['1001', '1002', '1003']\n   values = ['骆昊', '王大锤', '白元芳']\n   d = dict(zip(keys, values))\n   print(d)\n   ```\n\n   **不好**的代码：\n\n   ```Python\n   keys = ['1001', '1002', '1003']\n   values = ['骆昊', '王大锤', '白元芳']\n   d = {}\n   for i, key in enumerate(keys):\n       d[key] = values[i]\n   print(d)\n   ```\n\n> **说明**：这篇文章的内容来自于网络，有兴趣的读者可以阅读[原文](http://safehammad.com/downloads/python-idioms-2014-01-16.pdf)。\n\n"
  },
  {
    "path": "README.md",
    "content": "## Python - 100天从新手到大师\n\n### Python应用领域和就业形势分析\n\n简单的说，Python是一个“优雅”、“明确”、“简单”的编程语言。\n\n - 学习曲线低，适合非专业人士\n - 开源系统，拥有强大的生态圈\n - 解释型语言，完美的平台可移植性\n - 支持面向对象和函数式编程\n - 可扩展性，能调用C/C++代码\n - 代码规范程度高，可读性强\n\n目前几个比较流行的领域，Python都有用武之地。\n\n - 云基础设施 - Python / Java / Go\n - DevOps - Python / Shell / Ruby / Go\n - 网络爬虫 - Python / PHP / C++\n - 数据分析挖掘 - Python / R / Scala / Matlab\n - 机器学习 - Python / R / Java / Lisp\n\n作为一名Python开发者，主要的就业领域包括：\n\n- Python服务器后台开发 / 游戏服务器开发 / 数据接口开发工程师\n- Python自动化运维工程师\n- Python数据分析 / 数据可视化 / 科学计算 / 大数据工程师\n- Python爬虫工程师\n- Python聊天机器人开发 / 图像识别和视觉算法 / 深度学习工程师\n\n下图显示了主要城市Python招聘需求量及薪资待遇排行榜（截止到2018年5月）。\n\n![Python招聘需求及薪资待遇Top 10](./res/python-top-10.png)\n\n![](./res/python-bj-salary.png)\n\n![](./res/python-cd-salary.png)\n\n给初学者的几个建议（老司机的忠告）：\n\n- Make English as your working language.\n- Practice makes perfect.\n- All experience comes from mistakes.\n- Don't be one of the leeches.\n- Either stand out or kicked out.\n\n### Day01~15 - [Python语言基础](./Day01-15)\n\n#### Day01 - [初识Python](./Day01-15/Day01/初识Python.md)\n\n- Python简介 - Python的历史 / Python的优缺点 / Python的应用领域\n- 搭建编程环境 - Windows环境 / Linux环境 / MacOS环境\n- 从终端运行Python程序 - DOS命令 / Hello, world / print函数 / 运行程序\n- 使用IDLE - 交互式环境(REPL) / 编写多行代码 / 运行程序 / 退出IDLE\n- 注释 - 注释的作用 / 单行注释 / 多行注释\n\n#### Day02 - [语言元素](./Day01-15/Day02/语言元素.md)\n\n- 程序和进制 - 指令和程序 / 冯诺依曼机 / 二进制和十进制 / 八进制和十六进制\n- 变量和类型 - 变量的命名 / 变量的使用 / input函数 / 检查变量类型 / 类型转换\n- 数字和字符串 - 整数 / 浮点数 / 复数 / 字符串 / 字符串基本操作 / 字符编码\n- 运算符 - 数学运算符 / 赋值运算符 / 比较运算符 / 逻辑运算符 / 身份运算符 / 运算符的优先级\n- 应用案例 - 华氏温度转换成摄氏温度 / 输入圆的半径计算周长和面积 / 输入年份判断是否是闰年\n\n#### Day03 - [分支结构](./Day01-15/Day03/分支结构.md)\n\n- 分支结构的应用场景 - 条件 / 缩进 / 代码块 / 流程图\n- if语句 - 简单的if / if-else结构 / if-elif-else结构 / 嵌套的if\n- 应用案例 - 用户身份验证 / 英制单位与公制单位互换 / 掷骰子决定做什么 / 百分制成绩转等级制 / 分段函数求值 / 输入三条边的长度如果能构成三角形就计算周长和面积\n\n#### Day04 - [循环结构](./Day01-15/Day04/循环结构.md)\n\n- 循环结构的应用场景 - 条件 / 缩进 / 代码块 / 流程图\n- while循环 - 基本结构 / break语句 / continue语句\n- for循环 - 基本结构 / range类型 / 循环中的分支结构 / 嵌套的循环 / 提前结束程序 \n- 应用案例 - 1~100求和 / 判断素数 / 猜数字游戏 / 打印九九表 / 打印三角形图案 / 猴子吃桃 / 百钱百鸡\n\n#### Day05 - [总结和练习](./Day01-15/Day05/练习.md)\n\n- 基础练习 - 水仙花数 / 完美数 / 五人分鱼 / Fibonacci数列 / 回文素数 \n- 综合练习 - Craps赌博游戏\n\n#### Day06 - [函数和模块的使用](./Day01-15/Day06/函数和模块的使用.md)\n\n- 函数的作用 - 代码的坏味道 / 用函数封装功能模块\n- 定义函数 - def语句 / 函数名 / 参数列表 / return语句 / 调用自定义函数\n- 调用函数 - Python内置函数 /  导入模块和函数\n- 函数的参数 - 默认参数 / 可变参数 / 关键字参数(\\*) / 命名关键字参数(\\*)\n- 函数的返回值 - 没有返回值  / 返回单个值 / 返回多个值(\\*)\n- 作用域问题 - 局部作用域 / 嵌套作用域 / 全局作用域 / 内置作用域 / 和作用域相关的关键字\n- 用模块管理函数 - 模块的概念 / 用自定义模块管理函数 / 命名冲突的时候会怎样（同一个模块和不同的模块）\n\n#### Day07 - [字符串和常用数据结构](./Day01-15/Day07/字符串和常用数据结构.md)\n\n- 字符串的使用 - 计算长度 / 下标运算 / 切片 / 常用方法\n- 列表基本用法 - 定义列表 / 用下表访问元素 / 下标越界 / 添加元素 / 删除元素 / 修改元素 / 切片 / 循环遍历\n- 列表常用操作 - 连接 / 复制(复制元素和复制数组) / 长度 / 排序 / 倒转 / 查找\n- 生成列表 - 使用range创建数字列表 / 生成表达式 / 生成器\n- 元组的使用 - 定义元组 / 使用元组中的值 / 修改元组变量 / 元组和列表转换\n- 集合基本用法 - 集合和列表的区别 /  创建集合 / 添加元素 / 删除元素 /  清空\n- 集合常用操作 - 交集 / 并集 / 差集 / 对称差 / 子集 / 超集\n- 字典的基本用法 - 字典的特点 / 创建字典 / 添加元素 / 删除元素 / 取值 / 清空\n- 字典常用操作 - keys()方法 / values()方法 / items()方法 / setdefault()方法\n- 基础练习 - 跑马灯效果 / 列表找最大元素 / 统计考试成绩的平均分 / Fibonacci数列 / 杨辉三角\n- 综合案例 - 双色球选号 / 井字棋\n\n#### Day08 - [面向对象编程基础](./Day01-15/Day08/面向对象编程基础.md)\n\n- 类和对象 - 什么是类 / 什么是对象 / 面向对象其他相关概念\n- 定义类 - 基本结构 / 属性和方法 / 构造器 / 析构器 / \\_\\_str\\_\\_方法\n- 使用对象 - 创建对象 / 给对象发消息\n- 面向对象的四大支柱 - 抽象 / 封装 / 继承 / 多态\n- 基础练习 - 定义学生类 / 定义时钟类 / 定义图形类 / 定义汽车类\n\n#### Day09 - [面向对象进阶](./Day01-15/Day09/面向对象进阶.md)\n\n- 属性 - 类属性 / 实例属性 / 属性访问器 / 属性修改器 / 属性删除器 / 使用\\_\\_slots\\_\\_\n- 类中的方法 - 实例方法 / 类方法 / 静态方法\n- 运算符重载 - \\_\\_add\\_\\_ / \\_\\_sub\\_\\_ / \\_\\_or\\_\\_ /\\_\\_getitem\\_\\_ / \\_\\_setitem\\_\\_ / \\_\\_len\\_\\_ / \\_\\_repr\\_\\_ / \\_\\_gt\\_\\_ / \\_\\_lt\\_\\_ / \\_\\_le\\_\\_ / \\_\\_ge\\_\\_ / \\_\\_eq\\_\\_ / \\_\\_ne\\_\\_ / \\_\\_contains\\_\\_ \n- 类(的对象)之间的关系 - 关联 / 继承 / 依赖\n- 继承和多态 - 什么是继承 / 继承的语法 / 调用父类方法 / 方法重写 / 类型判定 / 多重继承 / 菱形继承(钻石继承)和C3算法\n- 综合案例 - 工资结算系统 / 图书自动折扣系统 / 自定义分数类\n\n#### Day10 - [图形用户界面和游戏开发](./Day01-15/Day10/图形用户界面和游戏开发.md)\n\n#### Day11 - [文件和异常](./Day01-15/Day11/文件和异常.md)\n\n- 读文件 - 读取整个文件 / 逐行读取 / 文件路径\n- 写文件 - 覆盖写入 / 追加写入 / 文本文件 / 二进制文件\n- 异常处理 - 异常机制的重要性 / try-except代码块 / else代码块 / finally代码块 / 内置异常类型 / 异常栈 / raise语句\n- 数据持久化 - CSV文件概述 / csv模块的应用 / JSON数据格式 / json模块的应用\n- 综合案例 - 歌词解析\n\n#### Day12 - [字符串和正则表达式](./Day01-15/Day12/字符串和正则表达式.md)\n\n- 字符串高级操作 - 转义字符 \\ 原始字符串 \\ 多行字符串 \\ in和 not in运算符 \\ is开头的方法 \\ join和split方法 \\ strip相关方法 \\ pyperclip模块 \\ 不变字符串和可变字符串 \\ StringIO的使用\n- 正则表达式入门 - 正则表达式的作用 \\ 元字符 \\ 转义 \\ 量词 \\ 分组 \\ 零宽断言 \\贪婪匹配与惰性匹配懒惰 \\ 使用re模块实现正则表达式操作（匹配、搜索、替换、捕获）\n- 使用正则表达式 - re模块 \\ compile函数 \\ group和groups方法 \\ match方法 \\ search方法 \\ findall和finditer方法 \\ sub和subn方法 \\ split方法\n- 应用案例 - 使用正则表达式验证输入的字符串\n\n#### Day13 - [进程和线程](./Day01-15/Day13/进程和线程入门.md)\n\n- 进程和线程的概念 - 什么是进程 / 什么是线程 / 多线程的应用场景\n- 使用进程 - fork函数 / multiprocessing模块 / 进程池 / 进程间通信\n- 使用线程 - thread模块 / threading模块 / Thread类 / Lock类\n\n#### Day14 - [网络编程入门](./Day01-15/Day14/网络编程入门.md)\n\n- 计算机网络基础 - 计算机网络发展史 / “TCP-IP”模型 / IP地址 / 端口 / 协议 / 其他相关概念\n- 网络应用架构 - “客户端-服务器”架构 / “浏览器-服务器”架构\n- Python网络编程 - 套接字的概念 / socket模块 /  socket函数 / 创建TCP服务器 / 创建TCP客户端 / 创建UDP服务器 / 创建UDP客户端 / SocketServer模块\n\n#### Day15 - [网络应用开发](./Day01-15/Day15/网络应用开发.md)\n\n- 访问网络API - 网络API概述 / 访问URL / requests模块 / 解析JSON格式数据\n- 文件传输 - FTP协议 / ftplib模块 / 交互式FTP应用\n- 电子邮件 - SMTP协议 / POP3协议 / IMAP协议 / smtplib模块 / poplib模块 / imaplib模块\n- 短信服务 - twilio模块 / 国内的短信服务\n\n### Day16~Day20 - [Python语言进阶 ](./Day16-20)\n\n\n\n### Day21~30 - [Web前端](./Day21-30)\n\n- 用HTML标签承载页面内容\n- 用CSS渲染页面\n- 用JavaScript处理交互式行为\n- jQuery入门和提高\n- Bootstrap在Web项目中的应用\n\n### Day31~35 - [Linux操作系统](./Day31-35)\n\n- 操作系统发展史和Linux概述\n- Linux基础命令\n- Linux中的实用程序\n- Linux的文件系统\n- Vim编辑器的应用\n- 环境变量和Shell编程\n- 软件的安装和服务的配置\n- 网络访问和管理\n- 其他相关内容\n\n### Day36~40 - [数据库基础和进阶](./Day36-40)\n\n- [关系型数据库MySQL](./Day36-40/关系型数据库MySQL.md)\n  - 关系型数据库概述\n  - MySQL的安装和使用\n  - SQL的使用\n    - DDL\n    - DML\n    - DQL\n    - DCL\n  - 在Python中操作MySQL\n  - MySQL高级知识\n- [NoSQL入门](./Day36-40/NoSQL入门.md)\n  - NoSQL概述\n  - 主流NoSQL数据库\n  - Redis概述\n  - Mongo概述\n\n### Day41~55 - [Django](./Day41-55)\n\n#### Day41 - [Django2实战(01) - 快速上手](./Day41-55/Django2实战01.md)\n\n#### Day42 - [Django2实战(02) - 深入模型](./Day41-55/Django2实战02.md)\n\n#### Day43 - [Django2实战(03) - 视图和模板](./Day41-55/Django2实战03.md)\n\n#### Day44 - [Django2实战(04) - 表单的应用](./Day41-55/Django2实战04.md)\n\n#### Day45 - [Django2实战(05) - Cookie和会话](./Day41-55/Django2实战05.md)\n\n#### Day46 - [Django2实战(06) - 日志和缓存](./Day41-55/Django2实战06.md)\n\n#### Day47 - [Django2实战(07) - 文件上传和通用视图](./Day41-55/Django2实战07.md)\n\n#### Day48 - [Django2实战(08) - 用户/角色/权限和中间件](./Day41-55/Django2实战08.md)\n\n#### Day49 - [Django2实战(09) - RESTful架构和应用(上)](./Day41-55/Django2实战09.md)\n\n#### Day50 - [Django2实战(10) - RESTful架构和应用(下)](./Day41-55/Django2实战10.md)\n\n#### Day51-55 - [Django2项目实战](./Day41-55/Django2项目实战.md)\n\n- 项目开发流程和相关工具\n- 生成非HTML内容\n- 项目部署和测试\n- 项目性能调优\n- Web应用安全保护\n\n\n### Day56~65 - [Flask](./Day56-65)\n\n#### Day56 - [Flask安装和入门](./Day56-65/Flash安装和入门.md) \n\n#### Day57 - [模板的使用](./Day56-65/模板的使用.md) \n\n#### Day58 - [表单的处理](./Day56-65/表单的处理.md) \n\n#### Day59 - [数据库操作](./Day56-65/数据库操作.md)\n\n#### Day60 - [使用Flask进行项目开发](./Day56-65/使用Flask进行项目开发.md)  \n\n#### Day61-65 - [Flask项目实战](./Day56-65/Flask项目实战.md)\n\n- 性能和测试\n- 项目部署\n\n### Day66~75 - [爬虫](./Day66-75)\n\n#### Day66 - [网络爬虫和相关工具](./Day66-75/01.网络爬虫和相关工具.md)\n\n#### Day67 - [数据采集和解析](./Day66-75/02.数据采集和解析.md)\n\n#### Day68 - [存储数据](./Day66-75/03.存储数据.md)\n\n#### Day69 - [并发下载](./Day66-75/04.并发下载.md)\n\n#### Day70 - [解析动态内容](./Day66-75/05.解析动态内容.md)\n\n#### Day71 - [表单交互和验证码处理](./Day66-75/06.表单交互和验证码处理.md)\n\n#### Day72 - [Scrapy爬虫框架入门](./Day66-75/Scrapy爬虫框架入门.md)\n\n#### Day73 - [Scrapy爬虫框架高级应用](./Day66-75/Scrapy爬虫框架高级应用.md)\n\n#### Day74 - [Scrapy爬虫框架分布式实现](./Day66-75/Scrapy爬虫框架分布式实现.md)\n\n### Day76~90 - [数据处理和机器学习](./Day76-90)\n\n#### Pandas的应用\n\n#### NumPy和SciPy的应用\n\n#### Matplotlib和数据可视化\n\n#### K最邻近分类算法(KNN)\n\n#### 线性回归和Logistic回归\n\n#### 支持向量机(SVM)和Kmeans聚类\n\n#### 决策树和贝叶斯分类\n\n#### Tensorflow实战01\n\n#### Tensorflow实战02\n\n#### Tensorflow实战03\n\n### Day91~100 - [团队项目开发](./Day91-100)\n\n#### 软件项目的过程模型\n\n#### 团队开发工具\n\n#### 模块分割设计与单元测试\n\n#### 用Jenkins实现持续集成\n\n#### 部署和自动化部署\n\n#### 性能测试和改善\n\n\n\n"
  },
  {
    "path": "玩转PyCharm(上).md",
    "content": "## 玩转PyCharm(上)\n\nPyCharm是由JetBrains公司开发的提供给Python专业的开发者的一个集成开发环境，它最大的优点是能够大大提升Python开发者的工作效率，为开发者集成了很多用起来非常顺手的功能，包括代码调试、高亮语法、代码跳转、智能提示、自动补全、单元测试、版本控制等等。此外，PyCharm还提供了对一些高级功能的支持，包括支持基于Django框架的Web开发、。\n\n### PyCharm的安装\n\n可以在[JetBrains公司的官方网站]()找到PyCharm的[下载链接](https://www.jetbrains.com/pycharm/download/)，有两个可供下载的版本一个是社区版一个是专业版，社区版在[Apache许可证](https://zh.wikipedia.org/wiki/Apache%E8%AE%B8%E5%8F%AF%E8%AF%81)下发布，专业版在专用许可证下发布（需要购买授权下载后可试用30天），其拥有许多额外功能。安装PyCharm需要有JRE（Java运行时环境）的支持，如果没有可以在安装过程中选择在线下载安装。\n\n> 说明：如果你是一名学生，希望购买PyCharm来使用，可以看看[教育优惠官方申请指南](https://sales.jetbrains.com/hc/zh-cn/articles/207154369)。\n\n### 首次使用的设置\n\n第一次使用PyCharm时，会有一个导入设置的向导，如果之前没有使用PyCharm或者没有保存过设置的就直接选择“Do not import settings”进入下一步即可。\n\n![](./res/pycharm-import-settings.png)\n\n专业版的PyCharm是需要激活的，**强烈建议为优秀的软件支付费用**，如果不用做商业用途，我们可以暂时选择试用30天或者使用社区版的PyCharm。\n\n![](./res/pycharm-activate.png)\n\n 接下来是选择UI主题，这个可以根据个人喜好进行选择。\n\n![](./res/pycharm-set-ui-theme.png)\n\n 再接下来是创建可以在终端（命令行）中使用PyCharm项目的启动脚本，当然也可以直接跳过这一步。\n\n![](./res/pycharm-create-launcher-script.png)\n\n然后可以选择需要安装哪些插件，我们可以暂时什么都不安装等需要的时候再来决定。\n\n![](./res/pycharm-plugins.png)\n\n### 用PyCharm创建项目\n\n点击上图中的“Start using PyCharm”按钮就可以开始使用PyCharm啦，首先来到的是一个欢迎页，在欢迎页上我们可以选择“创建新项目”、“打开已有项目”和“从版本控制系统中检出项目”。\n\n![](./res/pycharm-welcome.png)\n\n如果选择了“Create New Project”来创建新项目就会打一个创建项目的向导页。\n\n![](./res/pycharm-new-project.png)\n\n在如上图所示的界面中，我们可以选择创建项目的模板，包括了纯Python项目、基于各种不同框架的Web项目、Web前端项目、跨平台项目等各种不同的项目模板。如果选择Python的项目，那么有一个非常重要的设定是选择“New environment…”（创建新的虚拟环境）还是使用“Existing Interpreter”（已经存在的解释器）。前者肯定是更好的选择，因为新的虚拟环境不会对系统环境变量中配置的Python环境造成影响，简单举个例子就是你在虚拟环境下安装或者更新了任何三方库，它并不会对系统原有的Python解释器造成任何的影响，但代价是需要额外的存储空间来建立这个虚拟环境。\n\n项目创建完成后就可以开始新建各种文件来书写Python代码了。\n\n![](./res/pycharm-workspace.png)\n\n在工作窗口的右键菜单中可以找到“Run ...”和“Debug ...”菜单项，通过这两个菜单项我们就可以运行和调试我们的代码啦。建议关注一下菜单栏中的“Code”、“Refactor”和“Tools”菜单，这里面为编写Python代码提供了很多有用的帮助，我们在后面也会陆续为大家介绍这些功能。"
  },
  {
    "path": "用函数还是用复杂的表达式.md",
    "content": "## 要不要使用复杂表达式\n\nPerl语言的原作者Larry Wall曾经说过，伟大的程序员都有三个优点：懒惰、暴躁和自负。乍一看这三个词语没有一个是褒义词，但在程序员的世界里，这三个词有不同的意义。首先，懒惰会促使程序员去写一些省事儿的程序来辅助自己或别人更好的完成工作，这样我们就无需做那些重复和繁琐的劳动；同理能够用3行代码解决的事情，我们也绝不会写出10行代码来。其次，暴躁会让程序员主动的去完成一些你还没有提出的工作，去优化自己的代码让它更有效率，能够3秒钟完成的任务，我们绝不能容忍1分钟的等待。最后，自负会促使程序员写出可靠无误的代码，我们写代码不是为了接受批评和指责，而是为了让其他人来膜拜。\n\n那么接下来就有一个很有意思的问题值得探讨一下，我们需要一个程序从输入的三个数中找出最大的那个数。这个程序对任何会编程的人来说都是小菜一碟，甚至不会编程的人经过10分钟的学习也能搞定。下面是用来解决这个问题的Python代码。\n\n```Python\na = int(input('a = '))\nb = int(input('b = '))\nc = int(input('c = '))\nif a > b:\n\tthe_max = a\nelse:\n\tthe_max = b\nif c > the_max:\n\tthe_max = c\nprint('The max is:', the_max)\n\n```\n\n但是我们刚才说了，程序员都是懒惰的，很多程序员都会使用三元条件运算符来改写上面的代码。\n\n```Python\na = int(input('a = '))\nb = int(input('b = '))\nc = int(input('c = '))\nthe_max = a if a > b else b\nthe_max = c if c > the_max else the_max\nprint('The max is:', the_max)\n\n```\n\n需要说明的是，Python在2.5版本以前是没有上面代码第4行和第5行中使用的三元条件运算符的，究其原因是Guido van Rossum（Python之父）认为三元条件运算符并不能帮助 Python变得更加简洁，于是那些习惯了在C/C++或Java中使用三元条件运算符（在这些语言中，三元条件运算符也称为“Elvis运算符”，因为`?:`放在一起很像著名摇滚歌手猫王Elvis的大背头）的程序员试着用`and`和`or`运算符的短路特性来模拟出三元操作符，于是在那个年代，上面的代码是这样写的。\n\n```Python\na = int(input('a = '))\nb = int(input('b = '))\nc = int(input('c = '))\nthe_max = a > b and a or b\nthe_max = c > the_max and c or the_max\nprint('The max is:', the_max)\n\n```\n\n但是这种做法在某些场景下是不能成立的，且看下面的代码。\n\n```Python\na = 0\nb = -100\n# 下面的代码本来预期输出a的值，结果却得到了b的值\n# 因为a的值0在进行逻辑运算时会被视为False来处理\nprint(True and a or b)\n# print(a if True else b)\n```\n\n所以在Python 2.5以后引入了三元条件运算符来避免上面的风险（上面代码被注释掉的最后一句话）。那么，问题又来了，上面的代码还可以写得更简短吗？答案是肯定的。\n\n```Python\na = int(input('a = '))\nb = int(input('b = '))\nc = int(input('c = '))\nprint('The max is:', (a if a > b else b) if (a if a > b else b) > c else c)\n\n```\n\n但是，这样做真的好吗？如此复杂的表达式是不是让代码变得晦涩了很多呢？我们发现，在实际开发中很多开发者都喜欢过度的使用某种语言的特性或语法糖，于是简单的多行代码变成了复杂的单行表达式，这样做真的好吗？这个问题我也不止一次的问过自己，现在我能给出的答案是下面的代码，使用辅助函数。\n\n```Python\ndef the_max(x, y):\n\treturn x if x > y else y\n\n\na = int(input('a = '))\nb = int(input('b = '))\nc = int(input('c = '))\nprint('The max is:', the_max(the_max(a, b), c))\n\n```\n\n上面的代码中，我定义了一个辅助函数`the_max`用来找出参数传入的两个值中较大的那一个，于是下面的输出语句可以通过两次调用`the_max`函数来找出三个数中的最大值，现在代码的可读性是不是好了很多。用辅助函数来替代复杂的表达式真的是一个不错的选择，关键是比较大小的逻辑转移到这个辅助函数后不仅可以反复调用它，而且还可以进行级联操作。\n\n当然，很多语言中比较大小的函数根本没有必要自己来实现（通常都是内置函数），Python也是如此。Python内置的max函数利用了Python对可变参数的支持，允许一次性传入多个值或者一个迭代器并找出那个最大值，所以上面讨论的问题在Python中也就是一句话的事，但是从复杂表达式到使用辅助函数简化复杂表达式这个思想是非常值得玩味的，所以分享出来跟大家做一个交流。\n\n```Python\na = int(input('a = '))\nb = int(input('b = '))\nc = int(input('c = '))\nprint('The max is:', max(a, b, c))\n\n```\n\n"
  },
  {
    "path": "那些年我们踩过的那些坑.md",
    "content": "## 那些年我们踩过的那些坑\n\n### 坑01 - 整数比较的坑\n\n在 Python 中一切都是对象，整数也是对象，在比较两个整数时有两个运算符`==`和`is`，它们的区别是：\n\n- `is`比较的是两个整数对象的id值是否相等，也就是比较两个引用是否代表了内存中同一个地址。\n- `==`比较的是两个整数对象的内容是否相等，使用`==`时其实是调用了对象的`__eq__()`方法。\n\n知道了`is`和`==`的区别之后，我们可以来看看下面的代码，了解Python中整数比较有哪些坑：\n\n```Python\ndef main():\n\tx = y = -1\n\twhile True:\n\t\tx += 1\n\t\ty += 1\n\t\tif x is y:\n\t\t\tprint('%d is %d' % (x, y))\n\t\telse:\n\t\t\tprint('Attention! %d is not %d' % (x, y))\n\t\t\tbreak\n\t\t\t\n\tx = y = 0\n\twhile True:\n\t\tx -= 1\n\t\ty -= 1\n\t\tif x is y:\n\t\t\tprint('%d is %d' % (x, y))\n\t\telse:\n\t\t\tprint('Attention! %d is not %d' % (x, y))\n\t\t\tbreak\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n上面代码的部分运行结果如下图所示，出现这个结果的原因是Python出于对性能的考虑所做的一项优化。对于整数对象，Python把一些频繁使用的整数对象缓存起来，保存到一个叫`small_ints`的链表中，在Python的整个生命周期内，任何需要引用这些整数对象的地方，都不再重新创建新的对象，而是直接引用缓存中的对象。Python把频繁使用的整数对象的值定在[-5, 256]这个区间，如果需要这个范围的整数，就直接从`small_ints`中获取引用而不是临时创建新的对象。因为大于256或小于-5的整数不在该范围之内，所以就算两个整数的值是一样，但它们是不同的对象。\n\n![](./res/int-is-comparation.png)\n\n当然仅仅如此这个坑就不值一提了，如果你理解了上面的规则，我们就再看看下面的代码。\n\n```Python\nimport dis\na = 257\n\n\ndef main():\n\tb = 257  # 第6行\n\tc = 257  # 第7行\n\tprint(b is c)  # True\n\tprint(a is b)  # False\n\tprint(a is c)  # False\n\n\nif __name__ == \"__main__\":\n\tmain()\n\n```\n\n程序的执行结果已经用注释写在代码上了。够坑吧！看上去`a`、`b`和`c`的值都是一样的，但是`is`运算的结果却不一样。为什么会出现这样的结果，首先我们来说说Python程序中的代码块。所谓代码块是程序的一个最小的基本执行单位，一个模块文件、一个函数体、一个类、交互式命令中的单行代码都叫做一个代码块。上面的代码由两个代码块构成，`a = 257`是一个代码块，`main`函数是另外一个代码块。Python内部为了进一步提高性能，凡是在一个代码块中创建的整数对象，如果值不在`small_ints`缓存范围之内，但在同一个代码块中已经存在一个值与其相同的整数对象了，那么就直接引用该对象，否则创建一个新的对象出来，这条规则对不在`small_ints`范围的负数并不适用，对负数值浮点数也不适用，但对非负浮点数和字符串都是适用的，这一点读者可以自行证明。所以 `b is c`返回了`True`，而`a`和`b`不在同一个代码块中，虽然值都是257，但却是两个不同的对象，`is`运算的结果自然是`False`了。\n为了验证刚刚的结论，我们可以借用`dis`模块（听名字就知道是进行反汇编的模块）从字节码的角度来看看这段代码。如果不理解什么是字节码，可以先看看[《谈谈 Python 程序的运行原理》]((http://www.cnblogs.com/restran/p/4903056.html))这篇文章。可以先用`import dis`导入`dis`模块并按照如下所示的方式修改代码。\n\n```Python\nif __name__ == \"__main__\":\n\tmain()\n\tdis.dis(main)\n\n```\n\n代码的执行结果如下图所示。可以看出代码第6行和第7行，也就是`main`函数中的257是从同一个位置加载的，因此是同一个对象；而代码第9行的`a`明显是从不同的地方加载的，因此引用的是不同的对象。\n\n![](./res/result-of-dis.png)\n\n如果还想对这个问题进行进一步深挖，推荐大家阅读[《Python整数对象实现原理》](https://foofish.net/python_int_implement.html)这篇文章。\n\n### 坑02 - 嵌套列表的坑\n\nPython中有一种内置的数据类型叫列表，它是一种容器，可以用来承载其他的对象（准确的说是其他对象的引用），列表中的对象可以称为列表的元素，很明显我们可以把列表作为列表中的元素，这就是所谓的嵌套列表。嵌套列表可以模拟出现实中的表格、矩阵、2D游戏的地图（如植物大战僵尸的花园）、棋盘（如国际象棋、黑白棋）等。但是在使用嵌套的列表时要小心，否则很可能遭遇非常尴尬的情况，下面是一个小例子。\n\n```Python\ndef main():\n\tnames = ['关羽', '张飞', '赵云', '马超', '黄忠']\n\tsubjs = ['语文', '数学', '英语']\n\tscores = [[0] * 3] * 5\n\tfor row, name in enumerate(names):\n\t\tprint('请输入%s的成绩' % name)\n\t\tfor col, subj in enumerate(subjs):\n\t\t\tscores[row][col] = float(input(subj + ': '))\n\tprint(scores)\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n我们希望录入5个学生3门课程的成绩，于是定义了一个有5个元素的列表，而列表中的每个元素又是一个由3个元素构成的列表，这样一个列表的列表刚好跟一个表格是一致的，相当于有5行3列，接下来我们通过嵌套的for-in循环输入每个学生3门课程的成绩。程序执行完成后我们发现，每个学生3门课程的成绩是一模一样的，而且就是最后录入的那个学生的成绩。\n\n要想把这个坑填平，我们首先要区分对象和对象的引用这两个概念，而要区分这两个概念，还得先说说内存中的栈和堆。我们经常会听人说起“堆栈”这个词，但实际上“堆”和“栈”是两个不同的概念。众所周知，一个程序运行时需要占用一些内存空间来存储数据和代码，那么这些内存从逻辑上又可以做进一步的划分。对底层语言（如C语言）有所了解的程序大都知道，程序中可以使用的内存从逻辑上可以为五个部分，按照地址从高到低依次是：栈（stack）、堆（heap）、数据段（data segment）、只读数据段（static area）和代码段（code segment）。其中，栈用来存储局部、临时变量，以及函数调用时保存现场和恢复现场需要用到的数据，这部分内存在代码块开始执行时自动分配，代码块执行结束时自动释放，通常由编译器自动管理；堆的大小不固定，可以动态的分配和回收，因此如果程序中有大量的数据需要处理，这些数据通常都放在堆上，如果堆空间没有正确的被释放会引发内存泄露的问题，而像Python、Java等编程语言都使用了垃圾回收机制来实现自动化的内存管理（自动回收不再使用的堆空间）。所以下面的代码中，变量`a`并不是真正的对象，它是对象的引用，相当于记录了对象在堆空间的地址，通过这个地址我们可以访问到对应的对象；同理，变量`b`是列表容器的引用，它引用了堆空间上的列表容器，而列表容器中并没有保存真正的对象，它保存的也仅仅是对象的引用。\n\n ```Python\na = object()\nb = ['apple', 'pitaya', 'grape']\n ```\n\n知道了这一点，我们可以回过头看看刚才的程序，我们对列表进行`[[0] * 3] * 5`操作时，仅仅是将`[0, 0, 0]`这个列表的地址进行了复制，并没有创建新的列表对象，所以容器中虽然有5个元素，但是这5个元素引用了同一个列表对象，这一点可以通过`id`函数检查`scores[0]`和`scores[1]`的地址得到证实。所以正确的代码应该按照如下的方式进行修改。\n\n```Python\ndef main():\n\tnames = ['关羽', '张飞', '赵云', '马超', '黄忠']\n\tsubjs = ['语文', '数学', '英语']\n\tscores = [[]] * 5\n\tfor row, name in enumerate(names):\n\t\tprint('请输入%s的成绩' % name)\n\t\tscores[row] = [0] * 3\n\t\tfor col, subj in enumerate(subjs):\n\t\t\tscores[row][col] = float(input(subj + ': '))\n\tprint(scores)\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n或者\n\n```Python\ndef main():\n\tnames = ['关羽', '张飞', '赵云', '马超', '黄忠']\n\tsubjs = ['语文', '数学', '英语']\n\tscores = [[0] * 3 for _ in range(5)]\n\tfor row, name in enumerate(names):\n\t\tprint('请输入%s的成绩' % name)\n\t\tscores[row] = [0] * 3\n\t\tfor col, subj in enumerate(subjs):\n\t\t\tscores[row][col] = float(input(subj + ': '))\n\tprint(scores)\n\n\nif __name__ == '__main__':\n\tmain()\n\n```\n\n如果对内存的使用不是很理解，可以看看[PythonTutor网站](http://www.pythontutor.com/)上提供的代码可视化执行功能，通过可视化执行，我们可以看到内存是如何分配的，从而避免在使用嵌套列表或者复制对象时可能遇到的坑。\n\n![](./res/python-tutor-visualize.png)\n\n![](./res/python-tutor-visualize2.png)\n\n### 坑03 - 访问修饰符的坑\n\n用Python做过面向对象编程的人都知道，Python的类提供了两种访问控制权限，一种是公开，一种是私有（在属性或方法前加上双下划线）。而用惯了Java或C#这类编程语言的人都知道，类中的属性（数据抽象）通常都是私有的，其目的是为了将数据保护起来；而类中的方法（行为抽象）通常都是公开的，因为方法是对象向外界提供的服务。但是Python并没有从语法层面确保私有成员的私密性，因为它只是对类中所谓的私有成员进行了命名的变换，如果知道命名的规则照样可以直接访问私有成员，请看下面的代码。\n\n```Python\nclass Student(object):\n\n    def __init__(self, name, age):\n        self.__name = name\n        self.__age = age\n\n    def __str__(self):\n        return self.__name + ': ' + str(self.__age)\n\n\ndef main():\n    stu = Student('骆昊', 38)\n    # 'Student' object has no attribute '__name'\n    # print(stu.__name)\n    # 用下面的方式照样可以访问类中的私有成员\n    print(stu._Student__name)\n    print(stu._Student__age)\n\n\nif __name__ == '__main__':\n    main()\n\n```\n\nPython为什么要做出这样的设定呢？用一句广为流传的格言来解释这个问题：“We are all consenting adults here”（我们都是成年人）。这句话表达了很多Python程序员的一个共同观点，那就是开放比封闭要好，我们应该自己对自己的行为负责而不是从语言层面来限制对数据或方法的访问。\n\n所以在Python中我们实在没有必要将类中的属性或方法用双下划线开头的命名处理成私有的成员，因为这并没有任何实际的意义。如果想对属性或方法进行保护，我们建议用单下划线开头的受保护成员，虽然它也不能真正保护这些属性或方法，但是它相当于给调用者一个暗示，让调用者知道这是不应该直接访问的属性或方法，而且这样做并不影响子类去继承这些东西。\n\n需要提醒大家注意的是，Python类中的那些魔法方法，如\\_\\_str\\_\\_、\\_\\_repr\\_\\_等，这些方法并不是私有成员哦，虽然它们以双下划线开头，但是他们也是以双下划线结尾的，这种命名并不是私有成员的命名，这一点对初学者来说真的很坑。\n\n（未完待续） "
  }
]