Titleless Sightshttp://james0zan.github.io/2016-07-27T00:00:00+08:00Welcome!2016-07-27T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2016-07-27:index.html.html<p>Hello, I'm ZHANG, Mingxing a.k.a. james0zan.</p>
<p>Currently, I am a 5th year Ph.D. student at the <a class="reference external" href="http://madsys.cs.tsinghua.edu.cn/">MadSys Group</a> of Tsinghua.
I'm interested in building efficient and reliable parallel systems.
You can refer to my <a class="reference external" href="resource/Resume-ZHANGMingxing.pdf">CV</a> for more information.</p>
<p>Thank you for the visiting. The blog is <a class="reference external" href="category/blog.html">here</a>.</p>
<div class="section" id="news">
<h2>News</h2>
<ul class="simple">
<li>Our paper <a class="reference external" href="https://www.usenix.org/conference/osdi16/technical-sessions/presentation/zhang">Exploring the Hidden Dimension in Graph Processing</a> is accepted by <a class="reference external" href="https://www.usenix.org/conference/osdi16">OSDI 2016</a></li>
<li>Our paper <a class="reference external" href="http://www.vldb.org/pvldb/vol9/p912-zhang.pdf">Measuring and Optimizing Distributed Array Programs</a> is accepted by <a class="reference external" href="http://vldb2016.persistent.com/">VLDB 2016</a></li>
<li>Our paper <a class="reference external" href="http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=7412768">A Lightweight System for Detecting and Tolerating Concurrency Bugs</a> is accepted by <a class="reference external" href="https://www.computer.org/web/tse">IEEE Transactions on Software Engineering 2016</a></li>
<li>Our paper <a class="reference external" href="http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=7349596">What is Wrong With the Transmission? - A Comprehensive Study on Message Passing Related Bugs</a> is accepted by <a class="reference external" href="http://icpp2015.tsinghua.edu.cn/">ICPP 2015</a></li>
<li>Our paper <a class="reference external" href="resource/fse14_zhang.pdf">AI: A Lightweight System for Tolerating Concurrency Bugs</a> won <a class="reference external" href="http://fse22.gatech.edu/dpa">ACM SIGSOFT Distinguished Paper Award</a> at <a class="reference external" href="http://fse22.gatech.edu">FSE 2014</a></li>
</ul>
</div>
Steps of learning Monad2015-02-19T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2015-02-19:steps-of-learning-monad.html<p>Step 1: Randomly pick up a handbook or tutorial and get confused or even misled.</p>
<p>Step 2: Read <a class="reference external" href="http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html">Functors, Applicatives, And Monads In Pictures</a> to get a sense of how monad is analogue with a box/container.</p>
<p>Step 3: Read <a class="reference external" href="http://jelv.is/blog/Haskell-Monads-and-Purity/">Haskell, Monads and Purity</a> for truly understanding the essence of monad -- "separates evaluation and execution".</p>
Anticipating Invariant2014-03-03T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2014-03-03:AI.html.html<div class="section" id="ai-in-brief">
<h2>AI in Brief</h2>
<p>Concurrency bugs (CBugs) are notoriously difficult to be eradicated in the testing phase because of their non-deterministic nature,
and the bug fixing procedure is also time-consuming and error-prone.</p>
<p>Thus, tolerating concurrency bugs in the production phase emerges as an attractive complementary approach.
But unfortunately, the existing tolerating tools are usually
1) constrained in types of bugs they can handle;
or 2) requiring roll-back mechanism, which can hitherto not be fully achieved efficiently without hardware supports.</p>
<p>In contrast, the Anticipating Invariant (AI) can anticipate CBugs before any irreversible changes have been made.
Based on it, we implemented a software-only tool to tolerate concurrency bugs on-the-fly.</p>
<p>The tool will restrict the program's interleaving space, such that it avoids AI-violating (i.e., potentially failure-triggering) interleavings during the production runs.
Since AI can detect the bugs beforehand, we are able to bypass the suspicious interleavings through stalling, instead of resorting to roll-back.</p>
<p>Experiments with 35 real-world concurrency bugs demonstrate that AI is capable of detecting and tolerating most types of concurrency bugs, including both atomicity and order violations.</p>
<p>We also evaluate AI with 6 representative parallel programs.
Results show that AI incurs negligible overhead (< 1%) for many nontrivial desktop and server applications.
And its slowdown on computation-intensive programs can be reduced to about 2x after using the bias instrumentation.</p>
<p>To the best of our knowledge, this is the first attempt to efficiently tolerate previously unknown order and atomicity violations at run time without using rollback.</p>
</div>
<div class="section" id="paper">
<h2>Paper</h2>
<ul class="simple">
<li><strong>Mingxing Zhang</strong>, Yongwei Wu, Shan Lu, Shanxiang Qi, Jinglei Ren and Weimin Zheng. <a class="reference external" href="http://ieeexplore.ieee.org/xpl/login.jsp?tp=&arnumber=7412768">A Lightweight System for Detecting and Tolerating Concurrency Bugs</a>. <strong>TSE 2016</strong></li>
<li><strong>Mingxing Zhang</strong>, Yongwei Wu, Shan Lu, Shanxiang Qi, Jinglei Ren and Weimin Zheng. <a class="reference external" href="resource/fse14_zhang.pdf">AI: A Lightweight System for Tolerating Concurrency Bugs</a>. <strong>FSE '14</strong></li>
</ul>
<a href="http://fse22.gatech.edu/dpa"><font color="maroon"><span style="display:inline-block; width: 40px;"></span>Won SIGSOFT Distinguished Paper Award</font></a></div>
<div class="section" id="software">
<h2>Software</h2>
<p>You can download and try AI at <a class="reference external" href="https://github.com/james0zan/AI">here</a>.</p>
<p>In the package, we present:</p>
<ol class="arabic simple">
<li>the source code of our LLVM-based AI implementation;</li>
<li>several demos for demonstrating AI's ability of tolerating CBugs;</li>
<li>applications from different categories (desktop, server, HPC) for evaluating AI's overhead;</li>
<li>an example of the APIs' usage.</li>
</ol>
<p>Documentations, screencasts and some auxiliary scripts are also provided.</p>
</div>
DEF CON CTF Qualifier 2013 OMGACM 4 Writeup2013-06-18T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-06-18:def-con-ctf-qualifier-2013-omgacm-4-writeup.html<h1>Crossposting</h1>
<p>This artical is also cross-posted in <a href="http://www.blue-lotus.net/">blue-lotus</a>'s official blog at <a href="http://www.blue-lotus.net/def-con-ctf-qualifier-2013-omgacm-4-writeup/">here</a>.</p>
<h1>Problem Description</h1>
<p>Each problem gives you a circuit board, which will have a dimension, a set of nulls (that trace cannot go through), a feed point, and a set of antenna points.</p>
<p>Your goal is to draw a trace for each antenna point that starts at the feed point, ends at the antenna point and does not intersect other traces.</p>
<p>The distance of these traces must also be equal for all antenna points.</p>
<h1>Our Solution</h1>
<p>Since we intuitively classify this problem as NP-Complete, we resort to iterative deepening depth-first search for solving it.</p>
<p>In our algorithm, we choose to "grow" the traces from antenna points, which means that all the traces simultaneously start from their respective antenna point and go one step further one by one.</p>
<p>This strategy forces that all the traces will be equal length with each other, thus many unnecessary states are avoided.<br />
And if one trace encounters with another trace before reaching the feed point, we can simply merge them into one to eschew intersection.</p>
<p>More specifically, in order to record the current state, we use:</p>
<ol>
<li>Nine bool variables for each point: one for the point and 8 for adjacent edges; </li>
<li>One pair < int, int > (one for 1 and the other for sqrt 2) variable for each point to store the distance from this point to the corresponding antenna point if it has been covered by a trace; </li>
<li>Current "growing" point for each trace; </li>
<li>Which trace’s turn is it to grow in this iteration; </li>
<li>The final distance, if one of the traces has reached the feed point; </li>
</ol>
<p>And we also use a set of pruning tricks to accelerate the algorithm.</p>
<ol>
<li>Iterative deepening on length of each path; </li>
<li>Limit the depth of dfs to be at most 30. (This ought to have been another iterative deepening argument, but we hard code it with an empirical number for simplifying the code); </li>
<li>Preprocess the minimal distance from each point to the feed point and combine this information with iterative deepening threshold for further pruning; </li>
<li>If one of the trace has already reached the feed point, use the distance for pruning. </li>
</ol>
<p>Here is another tip:</p>
<p>The intersections will not only happen at points but also in small squares, you may need to double check this.</p>
<h1>Code</h1>
<div class="highlight"><pre><span class="cp">#include <stdio.h></span>
<span class="cp">#include <stdlib.h></span>
<span class="cp">#include <map></span>
<span class="cp">#include <set></span>
<span class="cp">#include <vector></span>
<span class="cp">#include <queue></span>
<span class="cp">#include <string.h></span>
<span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
<span class="k">typedef</span> <span class="kt">unsigned</span> <span class="kt">long</span> <span class="kt">long</span> <span class="n">llu</span><span class="p">;</span>
<span class="cp">#define MAX 100</span>
<span class="cp">#define mp make_pair</span>
<span class="cp">#define pb push_back</span>
<span class="kt">bool</span> <span class="n">Null</span><span class="p">[</span><span class="n">MAX</span><span class="p">][</span><span class="n">MAX</span><span class="p">],</span> <span class="n">Null2</span><span class="p">[</span><span class="n">MAX</span><span class="p">][</span><span class="n">MAX</span><span class="p">];</span>
<span class="kt">int</span> <span class="n">XY</span><span class="p">[</span><span class="n">MAX</span><span class="p">][</span><span class="n">MAX</span><span class="p">];</span>
<span class="kt">int</span> <span class="n">N</span><span class="p">,</span> <span class="n">M</span><span class="p">,</span> <span class="n">eN</span><span class="p">,</span> <span class="n">fX</span><span class="p">,</span> <span class="n">fY</span><span class="p">,</span> <span class="n">P</span><span class="p">,</span> <span class="n">UP</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">dy</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">dx</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">};</span>
<span class="kt">int</span> <span class="n">verse</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span><span class="mi">8</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">6</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">2</span> <span class="p">,</span> <span class="mi">1</span><span class="p">};</span>
<span class="n">set</span><span class="o"><</span><span class="n">vector</span><span class="o"><</span><span class="kt">bool</span><span class="o">></span> <span class="o">></span> <span class="n">S</span><span class="p">;</span>
<span class="n">pair</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">dp</span><span class="p">[]</span> <span class="o">=</span> <span class="p">{</span>
<span class="n">mp</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
<span class="n">mp</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="n">mp</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
<span class="n">mp</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="n">mp</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="n">mp</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">),</span>
<span class="n">mp</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">0</span><span class="p">),</span>
<span class="n">mp</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">)</span>
<span class="p">};</span>
<span class="k">struct</span> <span class="n">node</span> <span class="p">{</span>
<span class="n">vector</span><span class="o"><</span><span class="kt">bool</span><span class="o">></span> <span class="n">t</span><span class="p">;</span>
<span class="n">vector</span><span class="o"><</span><span class="n">pair</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="o">></span> <span class="n">len</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">cnt</span><span class="p">;</span>
<span class="n">pair</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">ans</span><span class="p">;</span>
<span class="n">vector</span><span class="o"><</span><span class="n">pair</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="o">></span> <span class="n">now</span><span class="p">;</span>
<span class="n">vector</span><span class="o"><</span><span class="kt">bool</span> <span class="o">></span> <span class="n">used</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">I</span><span class="p">;</span>
<span class="p">};</span>
<span class="n">node</span> <span class="n">Key</span><span class="p">;</span>
<span class="kt">int</span> <span class="nf">get</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">x</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">y</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">pair</span><span class="o"><</span><span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">></span> <span class="n">getLen</span><span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="n">mp</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">len</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">].</span><span class="n">first</span><span class="p">,</span> <span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">].</span><span class="n">second</span><span class="p">)].</span><span class="n">first</span><span class="o">+</span><span class="n">dp</span><span class="p">[</span><span class="n">j</span><span class="p">].</span><span class="n">first</span><span class="p">,</span>
<span class="n">Key</span><span class="p">.</span><span class="n">len</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">].</span><span class="n">first</span><span class="p">,</span> <span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">].</span><span class="n">second</span><span class="p">)].</span><span class="n">second</span><span class="o">+</span><span class="n">dp</span><span class="p">[</span><span class="n">j</span><span class="p">].</span><span class="n">second</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="n">output</span><span class="p">(</span><span class="n">node</span> <span class="n">ans</span><span class="p">)</span> <span class="p">{</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Solution %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">P</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">kk</span><span class="o">=</span><span class="mi">0</span><span class="p">,</span> <span class="n">L</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="n">N</span><span class="o">*</span><span class="n">M</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">kk</span><span class="o">++</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">tx</span> <span class="o">=</span> <span class="n">i</span> <span class="o">/</span> <span class="n">M</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">ty</span> <span class="o">=</span> <span class="n">i</span> <span class="o">%</span> <span class="n">M</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o"><</span><span class="mi">4</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">,</span> <span class="n">kk</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ans</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">kk</span><span class="p">])</span>
<span class="n">L</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">kk</span><span class="o">+=</span><span class="mi">4</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Line %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">L</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">k</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="n">N</span><span class="o">*</span><span class="n">M</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">k</span><span class="o">++</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">tx</span> <span class="o">=</span> <span class="n">i</span> <span class="o">/</span> <span class="n">M</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">ty</span> <span class="o">=</span> <span class="n">i</span> <span class="o">%</span> <span class="n">M</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">j</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">j</span><span class="o"><</span><span class="mi">4</span><span class="p">;</span> <span class="n">j</span><span class="o">++</span><span class="p">,</span> <span class="n">k</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ans</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">k</span><span class="p">])</span>
<span class="n">printf</span><span class="p">(</span><span class="s">"Segment %d %d %d %d</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span> <span class="n">tx</span><span class="p">,</span> <span class="n">ty</span><span class="p">,</span> <span class="n">tx</span><span class="o">+</span><span class="n">dx</span><span class="p">[</span><span class="n">j</span><span class="p">],</span> <span class="n">ty</span><span class="o">+</span><span class="n">dy</span><span class="p">[</span><span class="n">j</span><span class="p">]);</span>
<span class="p">}</span>
<span class="n">k</span><span class="o">+=</span><span class="mi">4</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">bool</span> <span class="n">none</span><span class="p">()</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="n">eN</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">[</span><span class="n">i</span><span class="p">])</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span>
<span class="k">return</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">myabs</span><span class="p">(</span><span class="kt">int</span> <span class="n">xx</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">xx</span><span class="o"><</span><span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="o">-</span><span class="n">xx</span><span class="p">;</span>
<span class="k">return</span> <span class="n">xx</span><span class="p">;</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">UPPER_BOUND</span> <span class="o">=</span> <span class="mi">28</span><span class="p">;</span>
<span class="kt">void</span> <span class="nf">dfs</span><span class="p">(</span><span class="kt">int</span> <span class="n">depth</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">depth</span> <span class="o">></span> <span class="n">UPPER_BOUND</span><span class="p">)</span> <span class="k">return</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">].</span><span class="n">first</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">y</span> <span class="o">=</span> <span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">].</span><span class="n">second</span><span class="p">;</span>
<span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">rand</span><span class="p">()</span> <span class="o">%</span> <span class="mi">8</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">iii</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">iii</span><span class="o"><</span><span class="mi">8</span><span class="p">;</span> <span class="n">iii</span><span class="o">++</span><span class="p">,</span> <span class="n">i</span><span class="o">=</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="mi">8</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">newX</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">dx</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="kt">int</span> <span class="n">newY</span> <span class="o">=</span> <span class="n">y</span> <span class="o">+</span> <span class="n">dy</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="n">newX</span> <span class="o"><</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">newX</span> <span class="o">>=</span> <span class="n">N</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">newY</span> <span class="o"><</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">newY</span> <span class="o">>=</span> <span class="n">M</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Null</span><span class="p">[</span><span class="n">newX</span><span class="p">][</span><span class="n">newY</span><span class="p">])</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">XY</span><span class="p">[</span><span class="n">newX</span><span class="p">][</span><span class="n">newY</span><span class="p">]</span> <span class="o">==</span> <span class="o">-</span><span class="mi">1</span> <span class="o">||</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">).</span><span class="n">first</span> <span class="o">+</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">).</span><span class="n">second</span> <span class="o">+</span> <span class="n">XY</span><span class="p">[</span><span class="n">newX</span><span class="p">][</span><span class="n">newY</span><span class="p">]</span> <span class="o">></span> <span class="n">UP</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">cnt</span> <span class="o">></span> <span class="mi">0</span> <span class="o">&&</span>
<span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">ans</span><span class="p">.</span><span class="n">first</span> <span class="o"><</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">).</span><span class="n">first</span> <span class="o">||</span> <span class="n">Key</span><span class="p">.</span><span class="n">ans</span><span class="p">.</span><span class="n">second</span> <span class="o"><</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">).</span><span class="n">second</span><span class="p">)</span> <span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">cnt</span> <span class="o">></span> <span class="mi">0</span> <span class="o">&&</span>
<span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">ans</span><span class="p">.</span><span class="n">first</span> <span class="o">==</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">).</span><span class="n">first</span> <span class="o">&&</span> <span class="n">Key</span><span class="p">.</span><span class="n">ans</span><span class="p">.</span><span class="n">second</span> <span class="o">==</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">).</span><span class="n">second</span><span class="p">)</span> <span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="o">*</span> <span class="mi">9</span> <span class="o">+</span> <span class="mi">6</span><span class="p">])</span> <span class="k">continue</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="o">*</span> <span class="mi">9</span> <span class="o">+</span> <span class="mi">8</span><span class="p">])</span> <span class="k">continue</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="mi">7</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mi">9</span> <span class="o">+</span> <span class="mi">6</span><span class="p">])</span> <span class="k">continue</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">i</span> <span class="o">==</span> <span class="mi">5</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mi">9</span> <span class="o">+</span> <span class="mi">8</span><span class="p">])</span> <span class="k">continue</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">if</span> <span class="p">(</span><span class="n">newX</span> <span class="o">==</span> <span class="n">fX</span> <span class="o">&&</span> <span class="n">newY</span> <span class="o">==</span> <span class="n">fY</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">cnt</span> <span class="o">></span> <span class="mi">0</span> <span class="o">&&</span> <span class="n">Key</span><span class="p">.</span><span class="n">ans</span> <span class="o">!=</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">))</span> <span class="k">continue</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">cnt</span><span class="o">++</span><span class="p">;</span> <span class="n">Key</span><span class="p">.</span><span class="n">ans</span> <span class="o">=</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[(</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">verse</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="n">mp</span><span class="p">(</span><span class="n">newX</span><span class="p">,</span> <span class="n">newY</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">cnt</span> <span class="o">></span> <span class="mi">0</span> <span class="o">&&</span> <span class="n">none</span><span class="p">())</span> <span class="p">{</span>
<span class="n">output</span><span class="p">(</span><span class="n">Key</span><span class="p">);</span>
<span class="n">exit</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">II</span> <span class="o">=</span> <span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">,</span> <span class="n">ttt</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">=</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">eN</span><span class="p">;</span> <span class="n">ttt</span><span class="o"><</span><span class="n">eN</span><span class="p">;</span> <span class="n">ttt</span><span class="o">++</span><span class="p">,</span> <span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">=</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">eN</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">])</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ttt</span> <span class="o"><</span> <span class="n">eN</span><span class="p">)</span> <span class="p">{</span>
<span class="n">dfs</span><span class="p">(</span><span class="n">depth</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[(</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">verse</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">I</span> <span class="o">=</span> <span class="n">II</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="n">mp</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span>
<span class="n">Key</span><span class="p">.</span><span class="n">cnt</span><span class="o">--</span><span class="p">;</span>
<span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">newX</span><span class="p">,</span> <span class="n">newY</span><span class="p">)</span> <span class="o">*</span> <span class="mi">9</span><span class="p">])</span> <span class="p">{</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">len</span><span class="p">[</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">]</span> <span class="o">!=</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">))</span> <span class="k">continue</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[(</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">verse</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="n">mp</span><span class="p">(</span><span class="n">newX</span><span class="p">,</span> <span class="n">newY</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">II</span> <span class="o">=</span> <span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">,</span> <span class="n">ttt</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">=</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">eN</span><span class="p">;</span> <span class="n">ttt</span><span class="o"><</span><span class="n">eN</span><span class="p">;</span> <span class="n">ttt</span><span class="o">++</span><span class="p">,</span> <span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">=</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">eN</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">])</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ttt</span> <span class="o"><</span> <span class="n">eN</span><span class="p">)</span> <span class="p">{</span>
<span class="n">dfs</span><span class="p">(</span><span class="n">depth</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[(</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">verse</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">I</span> <span class="o">=</span> <span class="n">II</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="n">mp</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span>
<span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[(</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[(</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">verse</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">len</span><span class="p">[</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">]</span> <span class="o">=</span> <span class="n">getLen</span><span class="p">(</span><span class="n">i</span><span class="p">);</span>
<span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="n">mp</span><span class="p">(</span><span class="n">newX</span><span class="p">,</span> <span class="n">newY</span><span class="p">);</span>
<span class="kt">int</span> <span class="n">II</span> <span class="o">=</span> <span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">,</span> <span class="n">ttt</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">=</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">eN</span><span class="p">;</span> <span class="n">ttt</span><span class="o"><</span><span class="n">eN</span><span class="p">;</span> <span class="n">ttt</span><span class="o">++</span><span class="p">,</span> <span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">=</span><span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="o">+</span><span class="mi">1</span><span class="p">)</span><span class="o">%</span><span class="n">eN</span><span class="p">)</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">])</span>
<span class="k">break</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">ttt</span> <span class="o"><</span> <span class="n">eN</span><span class="p">)</span> <span class="p">{</span>
<span class="n">dfs</span><span class="p">(</span><span class="n">depth</span><span class="o">+</span><span class="mi">1</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[(</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[(</span><span class="n">newX</span><span class="o">*</span><span class="n">M</span> <span class="o">+</span> <span class="n">newY</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">verse</span><span class="p">[</span><span class="n">i</span><span class="p">]]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span><span class="o">*</span><span class="mi">9</span> <span class="o">+</span> <span class="n">i</span> <span class="o">+</span> <span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="nb">false</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">I</span> <span class="o">=</span> <span class="n">II</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">[</span><span class="n">Key</span><span class="p">.</span><span class="n">I</span><span class="p">]</span> <span class="o">=</span> <span class="n">mp</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">dfs2</span><span class="p">(</span><span class="kt">int</span> <span class="n">x</span><span class="p">,</span> <span class="kt">int</span> <span class="n">y</span><span class="p">)</span> <span class="p">{</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="mi">8</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">newX</span> <span class="o">=</span> <span class="n">x</span> <span class="o">+</span> <span class="n">dx</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="kt">int</span> <span class="n">newY</span> <span class="o">=</span> <span class="n">y</span> <span class="o">+</span> <span class="n">dy</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
<span class="k">if</span> <span class="p">(</span><span class="n">newX</span> <span class="o"><</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">newX</span> <span class="o">>=</span> <span class="n">N</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">newY</span> <span class="o"><</span> <span class="mi">0</span> <span class="o">||</span> <span class="n">newY</span> <span class="o">>=</span> <span class="n">M</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">Null</span><span class="p">[</span><span class="n">newX</span><span class="p">][</span><span class="n">newY</span><span class="p">])</span> <span class="k">continue</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="n">XY</span><span class="p">[</span><span class="n">newX</span><span class="p">][</span><span class="n">newY</span><span class="p">]</span> <span class="o">!=</span> <span class="o">-</span><span class="mi">1</span> <span class="o">&&</span> <span class="n">XY</span><span class="p">[</span><span class="n">newX</span><span class="p">][</span><span class="n">newY</span><span class="p">]</span> <span class="o"><=</span> <span class="n">XY</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span> <span class="k">continue</span><span class="p">;</span>
<span class="n">XY</span><span class="p">[</span><span class="n">newX</span><span class="p">][</span><span class="n">newY</span><span class="p">]</span> <span class="o">=</span> <span class="n">XY</span><span class="p">[</span><span class="n">x</span><span class="p">][</span><span class="n">y</span><span class="p">]</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
<span class="n">dfs2</span><span class="p">(</span><span class="n">newX</span><span class="p">,</span> <span class="n">newY</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">void</span> <span class="nf">solve</span><span class="p">()</span> <span class="p">{</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%*s%d"</span><span class="p">,</span> <span class="o">&</span><span class="n">P</span><span class="p">);</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%*s%*d"</span><span class="p">);</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%d%d"</span><span class="p">,</span> <span class="o">&</span><span class="n">N</span><span class="p">,</span> <span class="o">&</span><span class="n">M</span><span class="p">);</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%*s%*d"</span><span class="p">);</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%d%d"</span><span class="p">,</span> <span class="o">&</span><span class="n">fX</span><span class="p">,</span> <span class="o">&</span><span class="n">fY</span><span class="p">);</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">N</span> <span class="o">*</span> <span class="n">M</span> <span class="o">*</span> <span class="mi">9</span><span class="p">);</span>
<span class="n">Key</span><span class="p">.</span><span class="n">len</span><span class="p">.</span><span class="n">resize</span><span class="p">(</span><span class="n">N</span> <span class="o">*</span> <span class="n">M</span><span class="p">);</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%*s%d"</span><span class="p">,</span> <span class="o">&</span><span class="n">eN</span><span class="p">);</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="n">eN</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">tx</span><span class="p">,</span> <span class="n">ty</span><span class="p">;</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%d%d"</span><span class="p">,</span> <span class="o">&</span><span class="n">tx</span><span class="p">,</span> <span class="o">&</span><span class="n">ty</span><span class="p">);</span>
<span class="n">Key</span><span class="p">.</span><span class="n">now</span><span class="p">.</span><span class="n">pb</span><span class="p">(</span><span class="n">mp</span><span class="p">(</span><span class="n">tx</span><span class="p">,</span> <span class="n">ty</span><span class="p">));</span>
<span class="n">Key</span><span class="p">.</span><span class="n">t</span><span class="p">[</span><span class="n">get</span><span class="p">(</span><span class="n">tx</span><span class="p">,</span> <span class="n">ty</span><span class="p">)</span> <span class="o">*</span> <span class="mi">9</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Key</span><span class="p">.</span><span class="n">used</span><span class="p">.</span><span class="n">pb</span><span class="p">(</span><span class="nb">true</span><span class="p">);</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="n">nN</span><span class="p">;</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%*s%d"</span><span class="p">,</span> <span class="o">&</span><span class="n">nN</span><span class="p">);</span>
<span class="n">memset</span><span class="p">(</span><span class="n">Null</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">Null</span><span class="p">));</span>
<span class="n">memset</span><span class="p">(</span><span class="n">Null2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">Null2</span><span class="p">));</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span> <span class="n">i</span><span class="o"><</span><span class="n">nN</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">tx</span><span class="p">,</span> <span class="n">ty</span><span class="p">;</span>
<span class="n">scanf</span><span class="p">(</span><span class="s">"%d%d"</span><span class="p">,</span> <span class="o">&</span><span class="n">tx</span><span class="p">,</span> <span class="o">&</span><span class="n">ty</span><span class="p">);</span>
<span class="n">Null</span><span class="p">[</span><span class="n">tx</span><span class="p">][</span><span class="n">ty</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="n">Null2</span><span class="p">[</span><span class="n">tx</span><span class="p">][</span><span class="n">ty</span><span class="p">]</span> <span class="o">=</span> <span class="nb">true</span><span class="p">;</span>
<span class="p">}</span>
<span class="n">memset</span><span class="p">(</span><span class="n">XY</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">XY</span><span class="p">));</span>
<span class="n">XY</span><span class="p">[</span><span class="n">fX</span><span class="p">][</span><span class="n">fY</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">dfs2</span><span class="p">(</span><span class="n">fX</span><span class="p">,</span> <span class="n">fY</span><span class="p">);</span>
<span class="n">node</span> <span class="n">base</span> <span class="o">=</span> <span class="n">Key</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="n">UP</span><span class="o">=</span><span class="mi">6</span><span class="p">;</span> <span class="p">;</span> <span class="n">UP</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
<span class="n">dfs</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span>
<span class="n">Key</span> <span class="o">=</span> <span class="n">base</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="n">solve</span><span class="p">();</span>
<span class="p">}</span>
</pre></div>
<h1>Result</h1>
<p>You can check out <a href="http://ascii.io/a/3644">http://ascii.io/a/3644</a> for the result.</p>
<p><strong>CAVEAT:</strong> We use many heuristics in the program, so it will not guarantee success for every run.</p>Memory Barriers: a Hardware View for Software Hackers2013-06-07T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-06-07:memory-barriers-a-hardware-view-for-software-hackers.html<p><em>URL:</em> <a class="reference external" href="http://www.rdrop.com/users/paulmck/scalability/paper/whymb.2010.07.23a.pdf">http://www.rdrop.com/users/paulmck/scalability/paper/whymb.2010.07.23a.pdf</a></p>
<p>This paper gives a clear explanation on techniques for increasing cache utilization,
and justify the existence of memory barriers as a necessary evil that
is required to enable good performance and scalability.</p>
<p>Its general structure is as follows:</p>
<ol class="arabic simple">
<li>Presents the structure of a cache;</li>
<li>Explains how cache-coherency protocols ensure that different per-CPU caches coordinate with each other;</li>
<li>Describes a technique called "store buffer", which can be used to ease the performance loss caused by invalidate-acknowledgement message passing.</li>
<li>Gives an example on why write memory barriers are needed -- Store buffers will reorder the execution of instructions to achieve better performance but we need methods to ensure some critical orders will not be undermined;</li>
<li>Outlines another technique named "invalidate queue" for making invalidate-acknowledgement messages arrive more quickly.</li>
<li>Gives a corresponding example on why read memory barriers are needed -- Invalidate queues will cause another kind of reordering which can be prevented by read memory barriers.</li>
</ol>
<p>The paper also gives many quizzes and discussions on real implementations (e.g. ARM, IA64).</p>
Scalable Event Multiplexing: epoll vs. kqueue2013-05-16T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-05-16:scalable-event-multiplexing-epoll-vs-kqueue.html<p><em>URL:</em> <a class="reference external" href="http://www.eecs.berkeley.edu/~sangjin/2012/12/21/epoll-vs-kqueue.html">http://www.eecs.berkeley.edu/~sangjin/2012/12/21/epoll-vs-kqueue.html</a></p>
<p>This article gives a fairly good review on common event multiplexing techniques, especially the difference between epoll (in Linux) and kqueue (in BSD).</p>
<p>There are also some interesting anecdotes enclosed in the post, such as:</p>
<ul class="simple">
<li>Stateful event multiplexing techniques (epoll, kqueue) are derived from the <a class="reference external" href="http://static.usenix.org/event/usenix99/full_papers/banga/banga.pdf">paper</a> by Banga et al, published at USENIX ATC 1999.</li>
<li>kqueue is technically superior to epoll.</li>
<li>It is often quoted that “In Unix, everything is a file”, but it is not always true.</li>
</ul>
Pitfalls of Object Oriented Programming2013-05-15T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-05-15:pitfalls-of-object-oriented-programming.html<p><em>URL:</em> <a class="reference external" href="http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf">http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf</a></p>
<p>Since the time consumed by a single CPU cycle is much lesser than RAM latency in nowadays, it becomes critical and profitable to better utilize the cache.</p>
<p>In this slide, Tony Albrecht states that with modern hardware, excessive encapsulation in OO is BAD. According to the principle of OOP, an instantiated object will generally contain all data associated with it. But when we only need a small portion of its fileds during the calculation there may be a lot of avoidable cache misses.</p>
Fast and accurate long-read alignment with Burrows–Wheeler transform @ BIOINFORMATICS Vol. 26 no. 5 20102013-05-03T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-05-03:fast-and-accurate-long-read-alignment-with-burrows-wheeler-transform-bioinformatics-vol-26-no-5-2010.html<p><em>URL:</em> <a class="reference external" href="http://dl.acm.org/citation.cfm?id=1741825">http://dl.acm.org/citation.cfm?id=1741825</a></p>
<p>A new generation of faster methods to find DNA sequence matches was developed since 2000. They are tailored for short (<100 bp) reads alignment and 10–1000 times faster than general algorithms, such as BLAST. However, reads coming from the new sequencing technologies are not short any more, which makes efficiently aligning long reads against a long reference sequence a new challenge to the development of alignment tools.</p>
<p>This paper presents Burrows-Wheeler Aligner’s Smith-Waterman Alignment (BWA-SW), a novel algorithm to align long sequences up to 1Mb against a large sequence database (e.g. the human genome) with a few gigabytes of memory. The algorithm is as accurate as SSAHA2, more accurate than BLAST, and is several to tens of times faster than both.</p>
<p>Similar to other algorithm papers, if you are familiar with the background, it’s easy for you to grasp the core algorithm within a few minutes. So I will just recommend several supporting material here:</p>
<ul class="simple">
<li>First, Heng Li et al.'s previous paper <a class="reference external" href="http://dl.acm.org/citation.cfm?id=1576130">"Fast and accurate short read alignment with Burrows–Wheeler transform"</a> gives a more detailed explanation of the building blocks of this algorithm, such as Prefix trie and Burrows–Wheeler transform. It is a good idea to read this paper in advance.</li>
<li>Second, if you still have trouble in understanding how FM-index works, there is an excellent diagrammatic presentation in Alex's post <a class="reference external" href="http://alexbowe.com/fm-index/">"FM-Indexes and Backwards Search"</a>.</li>
<li>Finally, if you have no idea what is "read alignment" but still interesting in this exquisite application of FM-index. You can read these two slides [<a class="reference external" href="http://www.cs.helsinki.fi/bioinformatiikka/mbi/courses/07-08/itb/slides/itb0708_slides_83-116.pdf">1</a>, <a class="reference external" href="http://www.cs.helsinki.fi/bioinformatiikka/mbi/courses/07-08/itb/slides/itb0708_slides_117-142.pdf">2</a>] at first.</li>
</ul>
Production-Run Software Failure Diagnosis via Hardware Performance Counters @ ASPLOS'132013-05-03T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-05-03:production-run-software-failure-diagnosis-via-hardware-performance-counters-asplos13.html<p><em>URL:</em> <a class="reference external" href="http://dl.acm.org/citation.cfm?id=2451128">http://dl.acm.org/citation.cfm?id=2451128</a></p>
<p>This paper presents PBI, a system that uses existing hardware performance counters to diagnose production-run failures caused by sequential and concurrency bugs with low overhead (< 10%).</p>
<p>Firstly, we must notice that this tool is used to diagnose bugs, not detect or prevent bugs during production runs. This purpose enables PBI to leverage some kinds of statistical methods. As a consequence, you must collect enough failure runs before diagnosing it, which usually requests that you should know how to trigger the bug.</p>
<p>Then, personally, I think the most important observation in this paper is: a wide variety of common software bugs can be reflected by a small portion of hardware events supported by hardware performance counters.</p>
<ul class="simple">
<li>For concurrency bugs, those events are cache-coherence events (state change in <a class="reference external" href="http://en.wikipedia.org/wiki/MESI_protocol">MESI protocol</a>). For example, the I-predicate and S-predicate can differentiate failure runs from success runs for all 4 types of atomicity violations. More detailed discussions can be found in Sec. 3.1.2.</li>
<li>For sequential bugs, PBI use branch-related events, because many semantic bugs are related to wrong control flows.</li>
</ul>
<p>This paper also proposes a statistical method to identify which events are highly correlated with failure runs.</p>
All about Eve: Execute-Verify Replication for Multi-Core Servers @ OSDI'122013-05-02T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-05-02:all-about-eve-execute-verify-replication-for-multi-core-servers-osdi12.html<p><em>URL:</em> <a class="reference external" href="http://dl.acm.org/citation.cfm?id=2387903">http://dl.acm.org/citation.cfm?id=2387903</a></p>
<p><a class="reference external" href="http://en.wikipedia.org/wiki/State_machine_replication">State machine replication (SMR)</a> is a powerful fault tolerance technique, it enforces replicas to deterministically process the same
sequence of requests so that they produce the same sequence of outputs.</p>
<p>But this technique doesn't suit for parallel systems, because if different servers interleave requests’ instructions in different ways, the states and outputs of correct servers may diverge even if no faults occur. As a result, most SMR systems require servers to process requests sequentially.</p>
<p>In contrast, Eve partitions requests in batches and allows different replicas to execute requests within each batch in parallel. After each batch, it speculates that whether the results of these parallel executions (i.e. the system’s important state and output at each replica) will match across enough replicas. If such a correct state/output can be identified, Eve makes those incorrect replicas issue an incremental state transfer request to other replicas (by leveraging a <a class="reference external" href="http://en.wikipedia.org/wiki/Merkle_signature_scheme">Merkle tree</a>). However, if too many replicas diverge so that the correct state/output cannot be identified, Eve guarantees safety and liveness by rolling back and sequentially and deterministically re-executing the requests.</p>
<p>Since diverges will seriously impair Eve's performance, it uses a <em>mixer</em> stage to apply
<strong>application-specific</strong> criteria to produce groups of requests that are unlikely to interfere.</p>
<p>As a side effect, Eve is especially useful in tolerating concurrency bugs. First, Eve’s
mixer reduces the likelihood of triggering latent concurrency bugs by attempting to run only unlikely-to-interfere requests in parallel; Second, Eve's execute-verify architecture allows Eve to detect and recover when concurrency causes executions to diverge.</p>
<p>In their experiments, Eve achieves a 2.6x ~ 6.5x speedup over traditional sequential execution replica and at most 4.7x speedup over the <a class="reference external" href="http://dl.acm.org/citation.cfm?id=1387601">Remus primary-backup system</a>. It also finds new concurrency bugs in H2 database.</p>
Myth: Eric Brewer on Why Banks are BASE Not ACID - Availability Is Revenue2013-05-02T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-05-02:myth-eric-brewer-on-why-banks-are-base-not-acid-availability-is-revenue.html<p><em>URL:</em> <a class="reference external" href="http://highscalability.com/blog/2013/5/1/myth-eric-brewer-on-why-banks-are-base-not-acid-availability.html">http://highscalability.com/blog/2013/5/1/myth-eric-brewer-on-why-banks-are-base-not-acid-availability.html</a></p>
<p>A refutation of the myth, "Money is important, so banks must use transactions to keep money safe and consistent".</p>
<p>This fact sets the grounds of Jeff Darcy's argument, <a class="reference external" href="http://pl.atyp.us/wordpress/index.php/2013/03/is-eventual-consistency-useful">"Is Eventual Consistency Useful?"</a></p>
Consistency Models Explained Briefly2013-04-27T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-04-27:consistency-models-explained-briefly.html<p><em>URL:</em> <a class="reference external" href="http://coldattic.info/shvedsky/pro/blogs/a-foo-walks-into-a-bar/posts/88">http://coldattic.info/shvedsky/pro/blogs/a-foo-walks-into-a-bar/posts/88</a></p>
<p>Consistency model, which describes how far the behavior of your multi-threaded (or distributed) system is from the ideal "sequential behavior", belongs to the most important concepts of concurrency systems. But unfortunatly, discriptions about this topic are usually incomplete and even inconsistent with each other.</p>
<p>This article, as its title indicates, clearly explains all the important consistency models with vivid diagrammatic presentations, which is well worth reading.</p>
<p>Its main content is following:</p>
<ul>
<li><p class="first">"Multithreading" Consistency Models</p>
<blockquote>
<ul class="simple">
<li>Strong Consistency aka Linearizability</li>
<li>Sequential Consistency</li>
<li>Quiescent Consistency</li>
</ul>
</blockquote>
</li>
<li><p class="first">"Distributed" Consistency Models</p>
<blockquote>
<ul class="simple">
<li>Eventual Consistency</li>
<li>Strict Consistency</li>
<li>Serializability</li>
</ul>
</blockquote>
</li>
</ul>
Parallel Merge Sort2013-04-27T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-04-27:parallel-merge-sort.html<p><em>URL:</em> <a class="reference external" href="http://coldattic.info/shvedsky/pro/blogs/a-foo-walks-into-a-bar/posts/49">http://coldattic.info/shvedsky/pro/blogs/a-foo-walks-into-a-bar/posts/49</a></p>
<p>I used to think that the "merge" step of merge sort cannot be efficiently parallelized, because the fact that an element belongs to the tail of one sorted array could not even guarrantee that it won't rank first in the other sorted arrary.</p>
<p>But this article illustrates that we can get across this obstacle by doing some binary search in advence.</p>
<p>And even better, this algorithm preserves merges sort's ability to be a external sort.</p>
Start Blogging Now2013-04-27T00:00:00+08:00Mingxing Zhangtag:james0zan.github.io,2013-04-27:start-blogging-now.html<p>Inspired and encoraged by Nathan Marz's posts [<a class="reference external" href="http://nathanmarz.com/blog/you-should-blog-even-if-you-have-no-readers.html">1</a>, <a class="reference external" href="http://nathanmarz.com/blog/break-into-silicon-valley-with-a-blog-1.html">2</a>], I made the decision to restart my blog here.
But since I'm infected with procrastination to some extent, I may only share several interesting articles with my own comments under the "<a class="reference external" href="http://james0zan.github.io/category/bookmark.html">Bookmark</a>" column in the begining. I hope this will help me develop a habit of writing and sharing.</p>
<p>Actually, I have already goten some articles under crafting, but I'm not sure when I can finish them ......</p>
<p>Thank you for your reading, and I hope that I can see you again.</p>