# ABC 168 E
# https://atcoder.jp/contests/contests/abc168/tasks/contests/abc168_e

n = read_line.to_i64

class Sardine
  def initialize(@taste : Int64, @fragrance : Int64)
    @gcd = taste.abs.gcd(fragrance.abs)
  end

  getter :taste, :fragrance
  getter gcd : Int64

  def to_a : Array(Int64)
    [taste, fragrance]
  end

  def basis_vector : Array(Int64)
    return [0_i64, 0_i64] if to_a.all?(&.zero?)
    return [0_i64, 1_i64] if to_a.first.zero?
    return [1_i64, 0_i64] if to_a.last.zero?

    a = to_a.map { |i| i // gcd }
    if a.first < 0 # [-, +], [-, -] の形のベクトルは [+, -] または [+, +] になるようにする
      a.map { |i| i * -1 }
    else
      a
    end
  end
end

class SardineGroup
  def initialize(@basis_vector : Array(Int64), @sardines : Array(Sardine))
    @invalid_group = nil
    @checked = false
  end

  getter :basis_vector, :sardines

  property invalid_group : SardineGroup | Nil
  property checked : Bool

  def calc(mod : Int64) : Int64
    if basis_vector == [0_i64, 0_i64]
      return (2_i64**size) % mod
    end

    j = (2_i64 ** size + 2_i64 ** invalid_size - 1) % mod
    invalid_checked! unless invalid_group.nil?
    return j
  end

  private def size : Int64
    sardines.size.to_i64
  end

  private def invalid_size : Int64
    if invalid_group.nil?
      0_i64
    else
      invalid_group.as(SardineGroup).sardines.size.to_i64
    end
  end

  private def invalid_checked!
    invalid_group.as(SardineGroup).checked = true
  end
end

h = Array.new(n) { a, b = read_line.split.map(&.to_i64); Sardine.new(a, b) }.group_by(&.basis_vector)

sardine_groups = Hash(Array(Int64), SardineGroup).new
h.each do |basis_vector, sardines|
  sardine_groups[basis_vector] = SardineGroup.new(basis_vector, sardines)
end

sardine_groups.each do |basis_vector, sardine_group|
  basis_vector_inverse = basis_vector[1] < 0 ? [basis_vector[1] * -1, basis_vector[0]] : [basis_vector[1], basis_vector[0] * -1] # [+, -] または [+, +] になるようにする
  if sardine_groups.has_key?(basis_vector_inverse)
    # puts "basis_vector: #{basis_vector}, basis_vector_inverse: #{basis_vector_inverse}"
    sardine_groups[basis_vector].invalid_group = sardine_groups[basis_vector_inverse]
  end
end

# sardine_groups.each do |basis_vector, sardine_group|
#   puts "#{basis_vector.inspect}"
#   puts "  (#{sardine_group.sardines.size})"
#   puts "  #{sardine_group.inspect}"
# end

mod = 1000000007_i64
i = 1_i64

sardine_groups.each do |basis_vector, sardine_group|
  next if sardine_group.checked
  i *= sardine_group.calc(mod)
  i %= mod
end

puts (i - 1_i64) % mod
