Problem:
Score : 600 points

Problem Statement

For a non-negative integer K, we define a fractal of level K as follows:

A fractal of level 0 is a grid with just one white square.

When K > 0, a fractal of level K is a 3^K \times 3^K grid. If we divide this grid into nine 3^{K-1} \times 3^{K-1} subgrids:

The central subgrid consists of only black squares.

Each of the other eight subgrids is a fractal of level K-1.

For example, a fractal of level 2 is as follows:

In a fractal of level 30, let (r, c) denote the square at the r-th row from the top and the c-th column from the left.

You are given Q quadruples of integers (a_i, b_i, c_i, d_i).
For each quadruple, find the distance from (a_i, b_i) to (c_i, d_i).

Here the distance from (a, b) to (c, d) is the minimum integer n that satisfies the following condition:

There exists a sequence of white squares (x_0, y_0), \ldots, (x_n, y_n) satisfying the following conditions:

(x_0, y_0) = (a, b)

(x_n, y_n) = (c, d)

For every i (0 \leq i \leq n-1), (x_i, y_i) and (x_{i+1}, y_{i+1}) share a side.

Constraints

1 \leq Q \leq 10000

1 \leq a_i, b_i, c_i, d_i \leq 3^{30}

(a_i, b_i) \neq (c_i, d_i)

(a_i, b_i) and (c_i, d_i) are white squares.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

Q
a_1 \ b_1 \ c_1 \ d_1
:
a_Q \ b_Q \ c_Q \ d_Q

Output

Print Q lines.
The i-th line should contain the distance from (a_i, b_i) to (c_i, d_i).

Sample Input 1

2
4 2 7 4
9 9 1 9

Sample Output 1

5
8

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

//author: camypaper
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Debug = System.Diagnostics.Debug;
using SB = System.Text.StringBuilder;
using System.Numerics;
using Point = System.Numerics.Complex;
using static System.Math;
using Number = System.Int64;
using System.Runtime.CompilerServices;

namespace Program {
    public class Solver {
        Random rnd = new Random(0);
        void pre() {
            {
                var x = "...";
                var y = ".#.";
                var z = "###";
                var X = x + x + x;
                mat = new string[] {
                x + x + x,
                y + y + y,
                x + x + x,
                x + z + x,
                y + z + y,
                x + z + x,
                x + x + x,
                y + y + y,
                x + x + x
                };
                var matmat = new string[27];
                for (int i = 0; i < 9; i++) {
                    matmat[i] = matmat[i + 9] = matmat[i + 18] = mat[i] + mat[i] + mat[i];
                }
                mat = matmat;
                foreach (var s in mat) Debug.WriteLine(s);
            }
            const int N = 27;
            g = new int[N, N][,];
            var dx = new int[] { 1, -1, 0, 0 };
            var dy = new int[] { 0, 0, 1, -1 };
            for (int i = 0; i < N; i++)
                for (int j = 0; j < N; j++) {
                    var dist = new int[N, N];
                    for (int p = 0; p < N; p++)
                        for (int q = 0; q < N; q++)
                            dist[p, q] = 1000;
                    if (mat[i][j] == '#') continue;
                    dist[i, j] = 0;
                    var Q = new Queue<int>();
                    Q.Enqueue(i * N + j);
                    while (Q.Any()) {
                        var p = Q.Dequeue();
                        var x = p / N;
                        var y = p % N;
                        for (int k = 0; k < 4; k++) {
                            var nx = x + dx[k];
                            var ny = y + dy[k];
                            if (nx < 0 || nx >= N || ny < 0 || ny >= 18) continue;
                            if (mat[nx][ny] == '.' && dist[nx, ny] > dist[x, y] + 1) {
                                dist[nx, ny] = dist[x, y] + 1;
                                Q.Enqueue(nx * N + ny);
                            }
                        }
                    }
                    g[i, j] = dist;
                }
        }
        string[] mat;
        int[,][,] g;
        public void Solve() {
            pre();
            var Q = ri;
            for (int i = 0; i < Q; i++) {
                var a = rl - 1;
                var b = rl - 1;
                var c = rl - 1;
                var d = rl - 1;
                var dx = Abs(c - a);
                var dy = Abs(d - b);
                var ret = dx + dy;
                var p = a % 9;
                var q = b % 9;
                var u = c % 9;
                var v = d % 9;
                if (a >= 9) { p += 9; u += 9; }
                if (b >= 9) { q += 9; v += 9; }
                if (dx >= 9) {
                    if (a < c) u += 9;
                    else u -= 9;
                }
                if (dy >= 9) {
                    if (b < d) v += 9;
                    else v -= 9;
                }

                if (dx < 3 || dy < 3 && ret >= 2) {
                    Debug.WriteLine("#");
                    ret += g[p, q][u, v] - Abs(p - u) - Abs(q - v);
                }

                Console.WriteLine(ret);
            }
        }
        const long INF = 1L << 60;
        int ri => sc.Integer();
        long rl => sc.Long();
        double rd => sc.Double();
        string rs => sc.Scan();
        public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());

        static IEnumerable<int> Rep(int n) => Enumerable.Range(0, n);
        static IEnumerable<int> RRep(int n) => Enumerable.Range(0, n).Reverse();
        static T[] Enumerate<T>(int n, Func<int, T> f) {
            var a = new T[n];
            for (int i = 0; i < a.Length; ++i) a[i] = f(i);
            return a;
        }
        static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
    }
}

#region main
static class Ex {
    static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
    static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
        return string.Join(st, ie);
    }
    static public void Main() {
        //Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
        var solver = new Program.Solver();
        solver.Solve();
        Console.Out.Flush();
    }
}
#endregion
#region Ex
namespace Program.IO {
    using System.IO;
    using System.Text;
    using System.Globalization;

    public class Printer : StreamWriter {
        public override IFormatProvider FormatProvider => CultureInfo.InvariantCulture;
        public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
    }

    public class StreamScanner {
        public StreamScanner(Stream stream) { str = stream; }

        public readonly Stream str;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        public bool isEof = false;

        private byte read() {
            if (isEof) return 0;
            if (ptr >= len) {
                ptr = 0;
                if ((len = str.Read(buf, 0, 1024)) <= 0) {
                    isEof = true;
                    return 0;
                }
            }
            return buf[ptr++];
        }

        public char Char() {
            byte b = 0;
            do b = read(); while ((b < 33 || 126 < b) && !isEof);
            return (char)b;
        }
        public string Scan() {
            var sb = new StringBuilder();
            for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
            return sb.ToString();
        }
        public string ScanLine() {
            var sb = new StringBuilder();
            for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
            return sb.ToString();
        }
        public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
        public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
        public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
    }
}

#endregion