第一章:Go构建链分层污染检测总览
Go 构建链中,依赖污染可能在多个层级悄然引入:模块代理缓存、go.mod 依赖图、vendor 目录、构建缓存(build cache)以及最终二进制产物中的符号与元数据。分层污染检测旨在对这些关键环节实施纵深防御,而非仅聚焦于源码层面的静态分析。
污染传播的典型路径
- 代理层:GOPROXY 指向的私有或公共模块代理若被投毒(如篡改 module.zip 或伪造 checksum),将导致所有下游项目拉取恶意版本;
- 依赖解析层:go mod tidy 可能因 indirect 依赖未显式约束而升级至含漏洞或后门的次要版本;
- 构建执行层:GOOS/GOARCH 环境变量组合异常、CGO_ENABLED=1 时链接非标准 C 库,均可能触发隐蔽行为;
- 产物层:go build -ldflags=”-s -w” 虽减小体积,但会剥离调试信息,掩盖非法符号注入痕迹。
核心检测维度对照表
| 层级 | 检测目标 | 推荐工具/方法 |
|---|---|---|
| 代理与校验 | checksum mismatch、proxy tampering | go list -m -f '{{.Dir}}' + sha256sum go.sum |
| 模块依赖图 | 不受控的 indirect 升级 | go list -json -m all | jq '.Indirect and .Version' |
| vendor 一致性 | vendor/ 与 go.mod 版本偏差 | diff -r vendor/ $(go list -m -f '{{.Dir}}')/vendor/ |
| 构建产物 | 非预期符号、调试段残留 | nm -C ./binary | grep -E '(_init|malicious_func)' |
快速验证本地构建链完整性
执行以下命令可一次性检查三类关键污染信号:
# 1. 验证 go.sum 完整性(需联网重计算远程 checksum)
go mod verify 2>/dev/null || echo "❌ go.sum 校验失败:存在未签名或篡改模块"
# 2. 列出所有间接依赖及其是否被显式约束
go list -m -json all | jq -r 'select(.Indirect == true) | "\(.Path)@\(.Version)"' | \
while read dep; do
grep -q "$dep" go.mod || echo "⚠️ 未约束间接依赖: $dep"
done
# 3. 检查二进制是否含调试段(-ldflags="-s -w" 应移除 .debug_* 段)
file ./main && readelf -S ./main | grep -q "\.debug" && echo "❌ 调试段未剥离"
该流程不依赖外部扫描器,仅使用 Go 原生命令链,适用于 CI 环境的轻量级准入检查。
第二章:go build 层:源码到中间表示的符号生成与污染初探
2.1 Go编译器前端(parser + type checker)对符号定义的静态捕获
Go 编译器前端在 cmd/compile/internal/syntax(parser)与 cmd/compile/internal/types2(type checker)中协同完成符号的声明可见性建模与作用域绑定验证。
符号捕获的核心阶段
- Lexer → Parser:生成 AST 节点(如
*syntax.Name),记录标识符原始拼写与位置; - Parser → TypeChecker:将
*syntax.Name绑定到types2.Object(含Kind,Name,Type,Scope); - 作用域链构建:嵌套块(
{})、函数体、包级作用域形成树状*types2.Scope,支持 O(1) 符号查找。
示例:变量声明的静态绑定
package main
func f() {
x := 42 // 声明:x 绑定至局部作用域
_ = x + y // 错误:y 未定义 → type checker 在 scope.Lookup("y") == nil 时报告
}
此处
x在f的作用域中被types2.NewVar创建并插入;y查找失败触发undeclared name: y。scope.Lookup是符号解析的原子操作,不依赖运行时。
符号对象关键字段对照表
| 字段 | 类型 | 说明 |
|---|---|---|
Name |
string |
标识符原始名称(如 "x") |
Kind |
objKind |
var, func, type 等 |
Type() |
types.Type |
推导出的具体类型(如 int) |
Parent() |
*Scope |
所属作用域(向上追溯链) |
graph TD
A[Source Code] --> B[Lexer]
B --> C[Parser: AST]
C --> D[TypeChecker: Scope + Object]
D --> E[Symbol Table: map[name]Object]
2.2 go build -gcflags=”-S” 实战:从AST到SSA中间代码的符号生命周期追踪
Go 编译器在 -gcflags="-S" 下输出汇编前的 SSA 形式注释汇编,实为窥探符号生命周期的黄金切口。
符号可见性演进阶段
- AST 阶段:变量声明即绑定作用域,但无内存布局
- IR 构建期:
ssa.Value生成,符号被分配ID并标记Addr/Value类型 - SSA 优化后:冗余定义被消除(如
v1 = add v0, 1; v2 = add v0, 1→ 合并为v1),符号生命周期收缩
关键调试命令
go build -gcflags="-S -l" main.go # -l 禁用内联,聚焦符号原始行为
-l 防止函数内联导致符号被提升或折叠,确保每个局部变量在 SSA 中独立成 Value 节点,便于追踪其 Def→Use 链。
SSA 符号状态对照表
| 状态 | 标志字段 | 示例 SSA 注释 |
|---|---|---|
| 活跃定义 | vXX (main.go:12) |
v5 = InitMem <mem> |
| 跨块使用 | vYY → vZZ |
v12 = Copy v5 |
| 生命周期结束 | dead: |
dead: v7(后续无 Use) |
graph TD
A[AST: var x int = 42] --> B[IR: x → ssa.Local{ID: 3}]
B --> C[SSA: v3 = Const64 <int> [42]]
C --> D[Opt: v3 inlined or dead if unused]
2.3 import path解析与vendor/module符号隔离机制的污染边界分析
Go 的 import path 解析在模块启用后不再仅依赖 $GOROOT/$GOPATH/src,而是由 go.mod 中的 module 声明和 replace/exclude 指令协同决定解析起点。
vendor 目录的隔离效力边界
当启用 GO111MODULE=on 且项目含 vendor/ 时,go build -mod=vendor 强制仅从 vendor/ 加载依赖——但不隔离符号导入路径:
// vendor/example.com/lib/v2/foo.go
package lib // 注意:实际包名仍为 'lib',非 'v2.lib'
→ 若主模块同时 import "example.com/lib" 和 import "example.com/lib/v2",二者共享同一包名空间,导致编译错误:duplicate package "lib"。
module 路径与包名解耦表
| import path | 实际包名 | 是否触发符号冲突 |
|---|---|---|
rsc.io/quote |
quote |
否 |
rsc.io/quote/v3 |
quote |
是(与 v1/v2 同名) |
github.com/user/pkg/v4 |
pkg |
是(若 v1 已存在) |
污染传播路径(mermaid)
graph TD
A[main.go import “A/B”] --> B{go.mod module A}
B --> C[解析为 A/B@v1.2.0]
C --> D[若 vendor/A/B 存在 → 跳过 checksum 校验]
D --> E[但包声明 package B 仍全局唯一]
E --> F[另一处 import “A/B/v2” → package B 冲突]
2.4 _cgo_imports、//go:linkname等伪符号在build阶段的注入行为验证
Go 构建系统在 go build 的 compile → link 阶段,会隐式注入若干伪符号以支撑跨语言交互与符号重绑定。
伪符号注入时机与角色
_cgo_imports:由cgo工具自动生成,声明 C 包依赖,在objfile中作为.data段符号存在,供链接器解析 C 函数引用;//go:linkname:编译器指令,绕过 Go 可见性检查,将 Go 符号强制绑定到指定(含未导出)运行时符号,仅在构建期生效。
验证注入行为
# 编译后提取符号表,观察注入痕迹
go build -o main.a -toolexec 'nm -C' ./main.go 2>&1 | grep -E '_cgo_imports|runtime\.memclrNoHeapPointers'
此命令触发
nm在编译中间对象生成阶段输出符号,可确认_cgo_imports位于.data段,而//go:linkname绑定的目标符号(如runtime.memclrNoHeapPointers)在链接时被强制解析——若目标不存在则报undefined reference错误。
关键约束对比
| 特性 | _cgo_imports |
//go:linkname |
|---|---|---|
| 注入阶段 | cgo 预处理后、编译前 | 编译期(需出现在函数体外) |
| 作用域 | 全局(每个 cgo 文件) | 单个符号对(src→dst) |
| 是否参与类型检查 | 否 | 是(dst 必须存在且类型兼容) |
graph TD
A[go build] --> B[cgo preprocessing]
B --> C[Inject _cgo_imports]
A --> D[Go compiler]
D --> E{Encounter //go:linkname?}
E -->|Yes| F[Bind src to dst symbol]
E -->|No| G[Normal compilation]
F --> H[Linker resolves extern symbols]
2.5 构建缓存(build cache)对符号污染传播的隐式放大效应实验
构建缓存虽加速重复构建,却在无形中固化并复用已被污染的中间产物——尤其当跨模块依赖未显式声明符号边界时。
数据同步机制
Gradle 的 build cache 默认启用 --build-cache,将 compileJava 输出的 .class 文件按输入哈希(源码+classpath+编译选项)缓存。若某模块 A 引入了非 api() 依赖的内部工具类 InternalUtils,而模块 B 通过缓存间接复用 A 的 class,则 InternalUtils 符号“越界泄漏”。
// build.gradle.kts(模块A)
dependencies {
implementation("com.example:utils:1.2") // 非 api(),本不应暴露
}
此配置下,
utils的字节码被纳入 A 的编译输出哈希;缓存命中后,B 模块即使未声明该依赖,仍可反射调用InternalUtils——污染通过缓存隐式传播。
实验对比数据
| 缓存状态 | B 模块能否解析 InternalUtils |
符号污染可见性 |
|---|---|---|
| 关闭 | 否(编译失败) | 隐蔽 |
| 开启 | 是(运行期才暴露) | 显性放大 |
传播路径示意
graph TD
A[模块A:引入 utils] -->|编译+缓存| C[Build Cache]
C -->|缓存命中| B[模块B:无声明依赖]
B --> D[反射调用 InternalUtils]
第三章:linker 层:全局符号表合并与重定位污染的关键跃迁
3.1 ldflag注入与-ldflags=”-X main.version=…”背后的符号覆盖原理
Go 链接器 ld 提供 -X 标志,用于在编译期将字符串值注入指定的包级变量(仅限 string 类型、未被内联或初始化为非零值的变量)。
符号覆盖的前提条件
- 变量必须声明为
var version string(不可是const或带初始值的var version = "dev") - 必须位于可导出包(如
main)中,且路径格式为importPath.name
工作机制示意
go build -ldflags="-X main.version=v1.2.3 -X 'main.buildTime=2024-06-15'" main.go
此命令指示链接器:在最终二进制中,将符号
main.version的.rodata段内容替换为"v1.2.3"字节序列。该操作发生在链接阶段,不涉及源码重写或 AST 修改。
关键限制表
| 限制项 | 说明 |
|---|---|
| 类型限定 | 仅支持 string,不支持 int/bool/结构体 |
| 初始化约束 | 若源码中 var version = "dev",则 -X 无效(已被初始化) |
| 包路径匹配 | main.version 必须与实际 import path 一致(区分大小写) |
graph TD
A[go build] --> B[编译 .o 对象文件]
B --> C[链接器 ld 扫描 -X 参数]
C --> D[定位未初始化的 string 符号地址]
D --> E[覆写对应 .rodata 段内存内容]
E --> F[生成最终可执行文件]
3.2 静态链接时符号弱定义(weak symbol)与强定义冲突导致的污染实测
当多个静态库提供同名符号,且一方为 __attribute__((weak)) 定义时,链接器优先选取强定义,但若强定义位于后链接的库中,前序库的弱定义可能被意外覆盖——引发运行时行为漂移。
复现环境构建
// liba.c —— 提供弱定义
int __attribute__((weak)) config_mode = 0;
// libb.c —— 提供强定义
int config_mode = 1;
编译命令:gcc -c liba.c -o liba.o && gcc -c libb.c -o libb.o && ar rcs libmy.a liba.o libb.o
链接顺序敏感性验证
| 链接顺序 | 最终 config_mode 值 |
原因 |
|---|---|---|
-lmy -lc |
1(强定义生效) |
libb.o 在归档中靠前,被选中 |
-lc -lmy |
(弱定义残留) |
liba.o 被首次解析,libb.o 因符号已定义被跳过 |
污染传播路径
graph TD
A[main.o 引用 config_mode] --> B[链接器扫描 -lmy]
B --> C{是否首次见该符号?}
C -->|是| D[载入 liba.o 中 weak config_mode=0]
C -->|否| E[忽略 libb.o 中强定义]
此机制使构建结果依赖归档内目标文件顺序,极易在 CI/CD 中引入非确定性。
3.3 internal/link 编译器后端中symtab.Sym结构体的污染标记传播路径
symtab.Sym 的 CgoExport 和 Reachable 字段共同构成污染标记载体,其传播始于 ld.(*Link).dodata 阶段。
标记注入点
// 在 ld/elf.go 中触发初始污染
sym.CgoExport = true // 显式导出符号即被标记为污染源
sym.Reachable = true // 由根符号(如 main.main)可达即激活传播
该赋值使符号进入污染传播图的起点;CgoExport 表示需跨语言边界,Reachable 控制传播范围。
传播机制
- 符号引用链:
Sym.Relocs→Reloc.Sym→ 递归标记目标符号 - 数据依赖:
.data段中*Sym字段写入触发sym.Mark() - 仅当
sym.Type == sym.SDATA || sym.Type == sym.SBSS时参与传播
关键传播路径(mermaid)
graph TD
A[main.main] -->|Reloc to| B[libc_printf]
B -->|CgoExport=true| C[unsafe.Pointer]
C -->|Reachable=true| D[global_buf]
| 字段 | 作用 | 是否参与传播 |
|---|---|---|
CgoExport |
标识污染源头 | 是 |
Reachable |
控制传播激活开关 | 是 |
External |
仅影响链接策略,不传播 | 否 |
第四章:assembler 层:汇编指令级符号绑定与底层污染固化
4.1 objdump -t 输出解析:.text/.data节中符号地址绑定与重定位项(REL/RELA)注入点定位
objdump -t 显示符号表,其中 Ndx 列标识符号所属节区,Value 为运行时虚拟地址(链接后)或偏移(重定位前):
$ objdump -t hello.o | grep -E "main|data"
0000000000000000 l d .text 0000000000000000 .text
0000000000000000 g F .text 000000000000001a main
0000000000000000 g O .data 0000000000000004 msg
g表示全局符号,F表示函数,O表示对象;main的Value=0x0在重定位前仅为节内偏移,实际地址由链接器在.text节基址上叠加确定;msg符号绑定于.data,其Value=0x4指向该节起始后的第4字节,是 RELA 重定位项的典型目标。
重定位项注入点即符号 Value 所指向的节内偏移位置,链接器据此在 .rela.text 或 .rela.data 中查找对应条目:
| Relocation Type | Target Section | Symbol Bound To | Inject Offset |
|---|---|---|---|
| R_X86_64_PC32 | .text | main | 0x5 (call指令后4字节处) |
| R_X86_64_64 | .data | msg | 0x0 (lea指令立即数字段) |
graph TD
A[.o文件符号表] --> B{Ndx == .text?}
B -->|Yes| C[Value → .text内偏移 → RELA注入点]
B -->|No| D[Value → .data内偏移 → RELA注入点]
C & D --> E[链接器填充绝对地址]
4.2 Go汇编器(cmd/asm)对TEXT符号修饰(如·funcname)的污染敏感性分析
Go汇编器要求导出函数名必须以 ·(U+00B7)前缀,例如 TEXT ·add(SB), $0-16。该符号非ASCII,易被编辑器、构建工具链或版本控制系统误处理。
符号污染常见场景
- 复制粘贴时
·被替换为 ASCII 点.或全角. - Git diff 中显示为
M-BM-编码乱码(UTF-8 BOM 或 Latin-1 混用) go tool asm静默忽略非法前缀,但链接期报undefined: add
典型错误汇编片段
// 错误:使用了 ASCII 点(U+002E)而非中点(U+00B7)
TEXT .add(SB), $0-16
MOVQ AX, BX
RET
逻辑分析:
cmd/asm在词法分析阶段将.视为标号分隔符而非符号前缀,导致add被解析为局部标号;·add才被识别为导出函数符号。参数$0-16表示无栈帧、16字节参数(2×int64),但前缀错误使整个 TEXT 定义失效。
| 污染类型 | 表现形式 | 检测方式 |
|---|---|---|
| Unicode 替换 | . / . / • |
xxd -u file.s \| grep '002E\|FF0E' |
| 行尾空白截断 | ·funcname(含空格) |
go tool asm -S file.s 报 unknown symbol |
graph TD
A[源码输入] --> B{词法扫描}
B -->|匹配 U+00B7 + 标识符| C[注册为导出符号]
B -->|其他任意点字符| D[降级为局部标号]
D --> E[链接失败:undefined reference]
4.3 GOT/PLT表初始化过程中的动态符号注入时机与ELF兼容性约束
动态符号注入必须严格发生在 _dl_relocate_object 执行 elf_machine_rela 之前,且早于 __libc_start_main 调用链中首个 PLT 间接跳转。
符号解析时序约束
- GOT[1] 必须在重定位前填入
link_map*,供elf_machine_rela查找符号定义 - PLT 第二条指令(
jmp *GOT[2])依赖 GOT[2] 已被dl_runtime_resolve初始化 - 若注入晚于首次 PLT 调用,将触发未解析的
0x0地址跳转,导致 SIGSEGV
ELF 兼容性关键字段
| 字段 | 作用 | 约束条件 |
|---|---|---|
DT_JMPREL |
PLT 重定位入口地址 | 必须指向 .rela.plt,否则 elf_machine_rela 跳过 PLT 修复 |
DT_PLTGOT |
GOT[1]/GOT[2] 基址 | 必须对齐 8 字节(AArch64/x86_64),否则 ld-linux.so 拒绝加载 |
// _dl_relocate_object 中关键检查(glibc 2.39)
if (l->l_info[DT_JMPREL] == NULL) {
// 缺失 DT_JMPREL → 跳过 PLT 重定位 → GOT[2] 保持 0 → 后续 PLT 调用崩溃
return;
}
该检查确保 PLT 重定位流程可启动;若缺失,动态链接器直接跳过 PLT 修复阶段,使所有外部函数调用失败。
graph TD
A[加载共享对象] --> B[解析 DT_JMPREL/DT_PLTGOT]
B --> C{DT_JMPREL 存在?}
C -->|否| D[跳过 PLT 重定位]
C -->|是| E[填充 GOT[1]/GOT[2]]
E --> F[执行 .rela.plt 重定位]
F --> G[PLT 可安全调用]
4.4 内联汇编(//go:asm)与外部汇编文件(.s)引入符号污染的差异性实践验证
Go 中符号可见性受编译单元边界严格约束://go:asm 声明的内联汇编仅作用于当前 Go 文件,而 .s 文件中定义的全局符号(如 TEXT ·add(SB), NOSPLIT, $0-16)默认导出至整个链接阶段。
符号作用域对比
- 内联汇编:由
go tool compile直接嵌入函数体,无独立符号表条目 - 外部
.s文件:经go tool asm编译为对象文件,所有·开头符号参与全局符号合并
实验验证片段
// add.s
#include "textflag.h"
TEXT ·add(SB), NOSPLIT, $0-16
MOVQ a+0(FP), AX
ADDQ b+8(FP), AX
MOVQ AX, ret+16(FP)
RET
该 ·add 符号在多包引用时若未加 NOLOCAL 标志,将触发重复定义错误;而等效内联汇编通过 asm volatile("addq %rsi, %rax" : "=a"(r) : "a"(a), "S"(b)) 完全隔离于函数栈帧,无符号泄漏。
| 方式 | 符号导出 | 跨包冲突风险 | 调试信息完整性 |
|---|---|---|---|
//go:asm |
否 | 无 | 有限(无 DWARF) |
.s 文件 |
是 | 高 | 完整 |
// 内联调用示例(无污染)
func Add(a, b int64) int64 {
var r int64
asm volatile("addq %rsi, %rax" : "=a"(r) : "a"(a), "S"(b))
return r
}
此内联实现不生成 .text.add 符号,避免链接期重定义;而 add.s 中 ·add 若被两个模块 import,则 go build 报 duplicate symbol。
第五章:ELF loader 层:运行时符号解析与最终污染落地
在真实APT攻击链中,ELF loader层是恶意载荷完成“最后一跃”的关键枢纽。当攻击者绕过静态检测、规避沙箱启发式分析后,真正决定C2通信是否建立、提权逻辑是否触发、横向模块是否加载的,正是动态链接器(ld-linux.so)在_dl_runtime_resolve阶段对符号的解析行为与劫持时机。
符号解析劫持实战:.plt.got 重定向
以某Linux后门样本为例,其通过LD_PRELOAD注入伪造的libc.so.6,覆盖__libc_start_main的GOT条目为0x401a80(恶意跳转地址)。当主程序调用printf时,PLT跳转至GOT,而GOT中已写入攻击者控制的shellcode地址:
; GOT[printf] entry before infection
0x602018: 0x7f8b3a12c3a0 ; original printf@GLIBC_2.2.5
; GOT[printf] entry after LD_PRELOAD injection
0x602018: 0x401a80 ; attacker-controlled stub
该stub执行mprotect(0x401000, 0x1000, 7)后解密内存中嵌套的AES-256加密SO模块,并dlopen加载。
动态链接器钩子:_dl_lookup_symbol_x 深度干预
glibc 2.34+ 引入符号缓存机制,但攻击者仍可通过篡改struct link_map链表头节点的l_name字段,使_dl_lookup_symbol_x在遍历共享库时优先匹配伪造的libcrypto.so.1.1(实际为/tmp/.X11-unix/.xauth伪装文件)。该文件包含如下结构:
| 字段 | 值 | 说明 |
|---|---|---|
l_addr |
0x7f9a21000000 |
映射基址(RWX) |
l_name |
/tmp/.X11-unix/.xauth |
触发stat()不报错的合法路径 |
l_ld |
0x7f9a210002a0 |
指向伪造的.dynamic段 |
此时,dlsym(RTLD_NEXT, "EVP_EncryptInit_ex")将返回攻击者预置的hook函数,而非OpenSSL真实实现。
运行时污染落地路径图谱
flowchart LR
A[main() 执行] --> B[PLT 调用 printf]
B --> C[GOT[printf] 查表]
C --> D{GOT 条目是否被篡改?}
D -->|是| E[跳转至 0x401a80 stub]
D -->|否| F[调用真实 printf]
E --> G[调用 mprotect 修改权限]
G --> H[解密内存 SO 模块]
H --> I[dlopen 加载伪装 libcrypto]
I --> J[劫持 EVP_* 系列函数]
J --> K[启动 HTTPS C2 信道]
GOT/PLT 污染检测对抗策略
安全团队在EDR中部署内核模块elf_guard.ko,在mmap()系统调用返回前校验目标页是否同时满足:
- 含
.plt或.got.plt节头标记 - 页内存在非
0x90/0xcc的可执行字节 - 对应ELF文件
st_mode & 0200 == 0(无写权限但内存可写)
某次红蓝对抗中,该规则成功捕获37个变种loader,其中21个使用memfd_create创建匿名fd并ftruncate分配0x2000字节后直接mmap为RX,绕过传统文件扫描——但无法逃逸上述内存页属性联合判定。
真实样本时间线还原
2023年Q4某云主机集群失陷事件中,攻击者利用systemd-coredump服务配置缺陷,将CoreDumpFilter设为0x33后触发崩溃,使coredump包含完整堆栈与GOT内容。通过解析/var/lib/systemd/coredump/core.*中的_DYNAMIC段,提取出被污染的DT_JMPREL(重定位表起始)与DT_PLTGOT(GOT首地址),进而批量定位127台服务器上的libc-2.31.so GOT污染偏移量。
ELF 解析器级混淆技术
最新loader采用PT_INTERP段动态生成技术:在readelf -l payload中显示[Requesting program interpreter: /lib64/ld-linux-x86-64.so.2],但实际openat(AT_FDCWD, "/lib64/ld-linux-x86-64.so.2", ...)被seccomp-bpf过滤后,内核fallback至/proc/self/exe并执行自解析。此时_dl_start从/proc/self/mem读取原始PT_LOAD段,再用mmap重建虚拟地址空间,使readelf等静态工具完全失效。
污染持久化载体选择
攻击者放弃传统/etc/ld.so.preload,转而利用/usr/local/bin/python3的RPATH=$ORIGIN/../lib:$ORIGIN/../lib64特性,在/usr/local/lib64/下部署libresolv.so.2(SHA256与合法版本一致),仅修改其.dynamic段中的DT_NEEDED条目,将libpthread.so.0替换为`libpthread.so.0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0
