Problem:
全探索お姉さんの休日

全探索お姉さんはとても優秀な女性である。
お姉さんは格子状の道の経路の数え上げを数千程度なら簡単に数え上げてしまう。

あなたと全探索お姉さんは今、六角形のタイルが敷き詰められた部屋にいる。
お姉さんは初めて見る六角形にとても興奮している様子である。
六角形の並びを座標に表すことに不慣れなお姉さんは図1のような座標系で部屋を表した。

図1

あなたはこの座標系上である地点からある地点まで移動したい。
しかし、お姉さんは 1 分ごとに動きたい方向をあなたに指示する。
いつものお姉さんなら同じ座標の場所を通らないようにあなたに移動の指示を出すだろう。
しかし、この座標系に不慣れなお姉さんは|x×y×t|(x：x 座標、y：y座標、t:最初の指示からの経過時間[分])を 6 で割った余り
に対応する方向（図で示す番号と対応）を指示するだけで、まったくのでたらめな方向にあなたを誘導する。

図2

お姉さんを傷つけたくないあなたは、お姉さんの指示をできるだけ守りつつ目的地までたどり着きたい。
あなたは許された行動は下の 7 つの行動である。

方向 0 へ 1 タイル移動

方向 1 へ 1 タイル移動

方向 2 へ 1 タイル移動

方向 3 へ 1 タイル移動

方向 4 へ 1 タイル移動

方向 5 へ 1 タイル移動

その場に留まる

お姉さんが指示を出した直後にあなたはこれら行動のうちの必ず1つを行う。

部屋には家具があり家具が配置されているタイルの中に移動することはできない。
また、y 座標の絶対値が ly を超えたり x 座標の絶対値が lx を超えるような移動は許されていない。
しかし、お姉さんはそのような移動を指示することがある。
指示を無視するとはお姉さんが示した方向と異なる方向へ移動するか、
もしくは、その場に留まることである。

目的地にたどり着くために最小で何度指示を無視すれば良いかを出力せよ。
目的地にたどり着くことが不可能な場合は -1 を出力せよ。

Input

入力は以下の形式で与えられる。

sx sy gx gy
n
x1 y1
...
xi yi
...
xn yn
lx ly

ここで、

sx, sy は出発地点の座標

gx, gy は目的地の座標

n は部屋に配置されている家具の数

xi, yi は家具があるタイルの座標

lx, ly は移動できる X, Y それぞれの座標の絶対値の上限
である。

Constraints

入力はすべて整数

-lx ≤ sx, gx ≤ lx

-ly ≤ sy, gy ≤ ly

(sx, sy) ≠ (gx, gy)

(xi, yi) ≠ (sx, sy)(1≤i≤n)

(xi, yi) ≠ (gx, gy)(1≤i≤n)

(xi, yi) ≠ (xj, yj)(i ≠ j)

0≤ n ≤ 1000

-lx ≤ xi ≤ lx (1≤i≤n)

-ly ≤ yi ≤ ly (1≤i≤n)

0 < lx, ly ≤ 100

Output

出力は1つの整数を含む1行で出力せよ。
目的地にたどり着ける場合は、最小の指示を無視する回数を出力せよ。
目的地にたどり着くことが不可能な場合は-1を出力せよ。

Sample Input 1

0 0 0 2
0
2 2

Output for the Sample Input 1

0

Sample Input 2

0 0 0 2
6
0 1
1 0
1 -1
0 -1
-1 -1
-1 0
2 2

Output for the Sample Input 2

-1

Sample Input 3

0 0 0 2
1
0 1
2 2

Output for the Sample Input 3

1

Solution in Ruby (judge verdict: Memory Limit Exceeded)

class Heap
	require 'forwardable'
	extend Forwardable

	def initialize
		@array = []
		@index = {}
	end

	def add(obj, key)
		@array << [obj, key]
		@index[obj] = @array.size - 1
		lift_up(@array.size - 1)
	end

	def swap(i, j)
		u = @array[i]
		v = @array[j]
		@index[u[0]], @index[v[0]] = j, i
		@array[i], @array[j] = v, u
	end

	def lift_up(i)
		return if i == 0
		j = (i - 1) / 2
		if (@array[i][1] <=> @array[j][1]) < 0
			swap(i, j)
			lift_up(j)
		end
	end

	def del_min
		raise "heap is empty!" if empty?
		min = @array[0]
		if size > 1
			swap(0, @array.size-1)
			@array.pop
			lift_down(0)
		else
			@array.pop
		end
		@index.delete(min[0])
		min
	end

	def inc_key(obj, diff)
		i = @index[obj]
		@array[i][1] += diff
		lift_down(i)
	end

	def dec_key(obj, diff)
		i = @index[obj]
		@array[i][1] -= diff
		lift_up(i)
	end

	def update_key(obj, new_key)
		i = @index[obj]
		return unless i
		return if (new_key <=> @array[i][1]) >= 0
		@array[i][1] = new_key
		lift_up(i)
	end

	def min_obj
		@array[0][0]
	end

	def min_key
		@array[0][1]
	end

	def lift_down(i)
		j = 2 * i + 1
		k = j + 1
		if k >= size
			return if j >= size
			if (@array[i][1] <=> @array[j][1]) > 0
				swap(i, j)
				lift_down(j)
			end
		else
			l = ((@array[j][1] <=> @array[k][1]) < 0 ? j : k)
			if (@array[i][1] <=> @array[l][1]) > 0
				swap(i, l)
				lift_down(l)
			end
		end
	end

	def_delegators :@array, :empty?, :size
end

module Graphical
	require 'set'

	def get_path_by_bfs(s, t)
		prev_node = {}
		reached = Set[s]
		queue = [s]
		while !queue.empty? 
			u = queue.shift
			each_out_connection_of(u){|v, _|
				next if reached.include?(v)	
				reached << v
				queue << v
				prev_node[v] = u

				if v == t
					path = [v]
					while v = prev_node[v]
						path.unshift v
					end
					return path
				end
			}
		end	
		return nil
	end

	def get_path_by_dfs(s, t, reached = Set.new)
		reached << s
		return [s] if s == t
		each_out_connection_of(s){|v|
			next if reached.include?(v)
			path = get_path_by_dfs(v, t, reached) 
			return [s] + path if path
		}
		nil
	end

	def reachable_from(s, max_depth = nil)
		reached = Set[s]
		queue = [s]
		depth = 0
		loop {
			break if max_depth && depth >= max_depth
			next_queue = []
			until queue.empty?
				u = queue.shift
				each_out_connection_of(u){|v, _|
					next if reached.include?(v)
					reached << v
					next_queue << v
				}
			end
			break if next_queue.empty?
			queue = next_queue
			depth += 1
		}
		return reached
	end

	def bfs(start)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		reached = Set[*start.to_a]
		queue = []
		start.each{|s| queue << s}
		dist = {}
		loop.with_index {|_, depth|
			next_queue = []
			until queue.empty?
				u = queue.shift
				return depth if block_given? && yield(u, depth)
				dist[u] = depth
				each_out_connection_of(u){|v, _|
					next if reached.include?(v)
					reached << v
					next_queue << v
				}
			end
			break if next_queue.empty?
			queue = next_queue
		}
		block_given? ? nil : dist
	end

	def dijkstra(start)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		h = Heap.new
		reached = Set[*start.to_a]
		start.each{|s| h.add(s, 0)}

		dist = {}
		until h.empty?
			u, key = h.del_min
			return key if block_given? && yield(u, key)
			dist[u] = key
			each_out_connection_of(u){|v, l|
				d = dist[u] + l
				if reached.include?(v)
					h.update_key(v, d)
				else
					h.add(v, d)
					reached << v
				end
			}
		end
		block_given? ? nil : dist
	end

	def bidir_dijkstra(s, t)
		f_dist = {}
		b_dist = {}

		f_heap = Heap.new
		b_heap = Heap.new

		f_heap.add(s, 0)
		b_heap.add(t, 0)

		f_reached = Set[s]
		b_reached = Set[t]

		f_current_dist = b_current_dist = 0
		best = Float::INFINITY

		loop {
			if !f_heap.empty?
				u, key = f_heap.del_min
				f_dist[u] = key
				f_current_dist = key
				each_out_connection_of(u){|v, l|
					d = f_dist[u] + l
					if b_dist[v]
						path_len = d + b_dist[v]
						best = path_len if path_len < best
					end
					if f_reached.include?(v)
						f_heap.update_key(v, d)
					else
						f_heap.add(v, d)
						f_reached << v
					end
				}
			end

			if !b_heap.empty?
				u, key = b_heap.del_min
				b_dist[u] = key
				b_current_dist = key
				each_in_connection_of(u){|v, l|
					d = b_dist[u] + l
					if f_dist[v]
						path_len = d + f_dist[v]
						best = path_len if path_len < best
					end
					if b_reached.include?(v)
						b_heap.update_key(v, d)
					else
						b_heap.add(v, d)
						b_reached << v
					end
				}
			end

			return best if f_current_dist + b_current_dist >= best
			return nil if f_heap.empty? && b_heap.empty?
		}
	end

	def a_star(start)
		raise "a_star need termination condition" unless block_given?
		h = Heap.new
		reached = Set[start]
		h.add(start, [a_star_heuristic(start), 0])

		dist = {}
		until h.empty?
			u, (e, d) = h.del_min
			return d if yield(u, dist)
			dist[u] = d
			each_out_connection_of(u){|v, l|
				d = dist[u] + l
				e = d + a_star_heuristic(v)
				if reached.include?(v)
					h.update_key(v, [e, d])
				else
					h.add(v, [e, d])
					reached << v
				end
			}
		end
		block_given? ? nil : dist
	end

	#make_variations :bidir_dijkstra

	def prim(start)
		h = Heap.new
		h.add(start, 0)
		reached = Set[start]
		tree_len = 0

		until h.empty?
			u, key = h.del_min
			tree_len += key

			each_out_connection_of(u){|v, d|
				if reached.include?(v)
					h.update_key(v, d)
				else
					h.add(v, d)
					reached << v
				end
			}
		end
		tree_len
	end

	def each_layer_from(start)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		return enum_for(__method__, start) unless block_given?
		reached = Set[*start]
		current_layer = start

		loop {
			yield current_layer
			next_layer = []
			current_layer.each{|u|
				each_out_connection_of(u){|v|
					next if reached.include?(v)
					reached << v
					next_layer << v
				}
			}	

			return if next_layer.empty?
			current_layer = next_layer
		}
	end
end

class Graph
	include Graphical

	def initialize(*options)
		@options = Set[*options]
	end

	def add_node(property = {})
		Node.new(property)
	end

	def add_edge(u, v, property = {})
		e = Edge.new(u, v, property)
		u.add_edge(e)
		v.add_edge(e)
		e
	end
	
	def del_edge(e)
		u, v = e.opposite.keys
		u.del_edge(e)
		v.del_edge(e)
		e
	end

	class Node
		def initialize(property)
			@property = property
			@edges = Set.new
		end

		def add_edge(e)
			@edges << e
		end

		def del_edge(e)
			@edges.delete(e)
		end

		def to_s
			@property[:name] || super
		end

		def each_edge
			@edges.each{|e| 
				yield e
			}
		end

		attr_reader :property
	end

	class Edge
		def initialize(u, v, property)
			@opposite = {u => v, v => u}
			@property = property
		end
		attr_reader :opposite, :property

		def to_s
			@property[:name] || super
		end

		def length
			@property[:length] || 1
		end
	end

	def each_out_connection_of(u)
		u.each_edge{|e|
			yield(e.opposite[u], e.length)
		}
	end

	alias :each_in_connection_of :each_out_connection_of
end

class Digraph < Graph
	def add_node(property = {})
		Node.new(property)
	end

	def add_edge(u, v, property = {})
		e = Edge.new(u, v, property)
		u.add_out_edge(e)
		v.add_in_edge(e)
		e
	end
	
	def del_edge(e)
		u, v = e.from, e.to
		u.out_edges.delete(e)
		v.in_edges.delete(e)
		e
	end

	class Node < Graph::Node
		def initialize(property)
			@property = property
			@out_edges = Set.new
			@in_edges = Set.new
		end

		def add_out_edge(e)
			@out_edges << e
		end

		def del_out_edge(e)
			@out_edges.delete(e)
		end

		def add_in_edge(e)
			@in_edges << e
		end

		def del_in_edge(e)
			@in_edges.delete(e)
		end

		attr_reader :in_edges, :out_edges
	end

	class Edge < Graph::Edge
		def initialize(u, v, property)
			@from = u	
			@to = v
			@property = property
		end

		attr_reader :from, :to
	end

	def each_out_connection_of(u)
		u.out_edges.each{|e|
			yield [e.to, e.length]
		}
	end

	def each_in_connection_of(v)
		v.in_edges.each{|e|
			yield [e.from, e.length]
		}
	end

#----------------------------------------------------------

	def get_path_bfs(s, t)
		path_edge = {}
		reached = Set[s]
		queue = [s]
		while !queue.empty? 
			u = queue.shift
			u.outgoings.each{|e|
				v = e.to
				next if reached.include?(v)	
				reached << v
				queue << v
				path_edge[v] = e

				if v == t
					path = []
					while e = path_edge[v]
						path.unshift e
						v = e.from
					end
					return path
				end
			}
		end	
		return nil
	end

	def get_path_dfs(s, t, reached = Set.new)
		reached << s	
		s.outgoings.each{|e|
			v = e.to
			next if reached.include?(v)
			return [e] if v == t
			
			path = get_path_dfs(v, t, reached) 
			return [e] + path if path
		}
		nil
	end

end

sx, sy, gx, gy = gets.split.map &:to_i
n = gets.to_i

obstacle = {}
n.times do
	x, y = gets.split.map &:to_i
	obstacle[[x, y]] = 1
end
lx, ly = gets.split.map &:to_i

g = Digraph.new

nodes = {}
(-lx-1..lx+1).each do |x|
	(-ly-1..ly+1).each do |y|
		(0..5).each do |t|
			nodes[[x, y, t]] = g.add_node
			obstacle[[x, y]] = 0 if x.abs > lx || y.abs > ly
		end
	end
end

ed = [[0,1],[1,0],[1,-1],[0,-1],[-1,-1],[-1,0],[0,0]]
od = [[0,1],[1,1],[1,0],[0,-1],[-1,0],[-1,1],[0,0]]

(-lx..lx).each do |x0|
	(-ly..ly).each do |y0|
		(0..5).each do |t|
			u = nodes[[x0, y0, t]]
			diff = (x0.even? ? ed : od)
			diff.each.with_index do |(dx, dy), i|
				x1, y1 = x0+dx, y0+dy
				v = nodes[[x1, y1, (t+1)%6]]
				next if obstacle[[x1, y1]]
				e = g.add_edge(u, v)
				e.property[:length] = ((x0 * y0 * t).abs % 6 == i ? 0 : 1)
			end
		end
	end
end

goal_nodes = Set[*(0..5).map {|t| nodes[[gx, gy, t]]}]
p g.dijkstra([nodes[[sx,sy,0]]]){|v| goal_nodes.include?(v)} || -1